mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Make Builtin itself un-importable
This commit is contained in:
parent
7bd9d645b9
commit
2a0410ec1d
4 changed files with 79 additions and 36 deletions
|
|
@ -305,27 +305,17 @@ pub fn setupAutoImportedBuiltinTypes(
|
|||
if (envs_map.get(type_ident)) |type_entry| {
|
||||
const module_env = type_entry.env;
|
||||
|
||||
// Create an import for the parent Builtin module (only once, shared across all types)
|
||||
// Create an import entry for the parent Builtin module
|
||||
// This is needed for type bindings to reference, but we do NOT add it to
|
||||
// import_indices or scope - "Builtin" should not be directly importable!
|
||||
const builtin_module_name = module_env.module_name;
|
||||
|
||||
// Check if we already have this import in our indices
|
||||
const is_new_import = !self.import_indices.contains(builtin_module_name);
|
||||
|
||||
const module_import_idx = try self.env.imports.getOrPut(
|
||||
gpa,
|
||||
self.env.common.getStringStore(),
|
||||
builtin_module_name,
|
||||
);
|
||||
|
||||
if (is_new_import) {
|
||||
// Add to import_indices so getOrCreateAutoImport can find it
|
||||
try self.import_indices.put(gpa, builtin_module_name, module_import_idx);
|
||||
|
||||
// Also add to current scope so scopeLookupImportedModule can find it
|
||||
// This ensures consistency with getOrCreateAutoImport
|
||||
_ = try current_scope.introduceImportedModule(gpa, builtin_module_name, module_import_idx);
|
||||
}
|
||||
|
||||
// Get target_node_idx from statement_idx
|
||||
const target_node_idx = if (type_entry.statement_idx) |stmt_idx|
|
||||
module_env.getExposedNodeIndexByStatementIdx(stmt_idx)
|
||||
|
|
|
|||
|
|
@ -40,4 +40,5 @@ test "check tests" {
|
|||
std.testing.refAllDecls(@import("test/let_polymorphism_integration_test.zig"));
|
||||
std.testing.refAllDecls(@import("test/num_type_inference_test.zig"));
|
||||
std.testing.refAllDecls(@import("test/num_type_requirements_test.zig"));
|
||||
std.testing.refAllDecls(@import("test/builtin_scope_test.zig"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,21 +216,21 @@ pub fn initWithImport(module_name: []const u8, source: []const u8, other_module_
|
|||
.builtin_module = other_test_env.builtin_module.env,
|
||||
};
|
||||
|
||||
// Build imported_envs array dynamically based on module_env.imports order
|
||||
// This matches the production approach in compile_package.zig
|
||||
const import_count = module_env.imports.imports.items.items.len;
|
||||
var imported_envs = try std.ArrayList(*const ModuleEnv).initCapacity(gpa, import_count);
|
||||
// Build imported_envs array
|
||||
// Always include the builtin module for auto-imported types (Bool, Str, etc.)
|
||||
var imported_envs = try std.ArrayList(*const ModuleEnv).initCapacity(gpa, 2);
|
||||
defer imported_envs.deinit(gpa);
|
||||
|
||||
// Add builtin module unconditionally (needed for auto-imported types)
|
||||
try imported_envs.append(gpa, other_test_env.builtin_module.env);
|
||||
|
||||
// Process explicit imports
|
||||
const import_count = module_env.imports.imports.items.items.len;
|
||||
for (module_env.imports.imports.items.items[0..import_count]) |str_idx| {
|
||||
const import_name = module_env.getString(str_idx);
|
||||
if (std.mem.eql(u8, import_name, "Builtin")) {
|
||||
try imported_envs.append(gpa, other_test_env.builtin_module.env);
|
||||
} else if (std.mem.eql(u8, import_name, other_module_name)) {
|
||||
if (std.mem.eql(u8, import_name, other_module_name)) {
|
||||
// Cross-module import - append the other test module's env
|
||||
try imported_envs.append(gpa, other_test_env.module_env);
|
||||
} else {
|
||||
std.debug.print("WARNING: Unknown import in test: {s}\n", .{import_name});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,22 +332,14 @@ pub fn init(module_name: []const u8, source: []const u8) !TestEnv {
|
|||
.builtin_module = builtin_module.env,
|
||||
};
|
||||
|
||||
// Build imported_envs array dynamically based on module_env.imports order
|
||||
// This matches the production approach in compile_package.zig
|
||||
const import_count = module_env.imports.imports.items.items.len;
|
||||
var imported_envs = try std.ArrayList(*const ModuleEnv).initCapacity(gpa, import_count);
|
||||
// Build imported_envs array
|
||||
// Always include the builtin module for auto-imported types (Bool, Str, etc.)
|
||||
var imported_envs = try std.ArrayList(*const ModuleEnv).initCapacity(gpa, 2);
|
||||
defer imported_envs.deinit(gpa);
|
||||
|
||||
for (module_env.imports.imports.items.items[0..import_count]) |str_idx| {
|
||||
const import_name = module_env.getString(str_idx);
|
||||
// For tests, all imports are to the Builtin module
|
||||
if (std.mem.eql(u8, import_name, "Builtin")) {
|
||||
try imported_envs.append(gpa, builtin_module.env);
|
||||
} else {
|
||||
// If there are other imports in the future, handle them here
|
||||
std.debug.print("WARNING: Unknown import in test: {s}\n", .{import_name});
|
||||
}
|
||||
}
|
||||
// Add builtin module unconditionally (needed for auto-imported types)
|
||||
try imported_envs.append(gpa, builtin_module.env);
|
||||
|
||||
|
||||
// Type Check - Pass the imported modules in other_modules parameter
|
||||
var checker = try Check.init(
|
||||
|
|
|
|||
60
src/check/test/builtin_scope_test.zig
Normal file
60
src/check/test/builtin_scope_test.zig
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//! Tests verifying that "Builtin" is not in scope and cannot be imported,
|
||||
//! but that nested types like Str, List, etc. are available.
|
||||
|
||||
const TestEnv = @import("./TestEnv.zig");
|
||||
const testing = @import("std").testing;
|
||||
const std = @import("std");
|
||||
|
||||
test "cannot import Builtin module" {
|
||||
const src =
|
||||
\\import Builtin
|
||||
\\
|
||||
\\x = 5
|
||||
;
|
||||
|
||||
var test_env = try TestEnv.init("Test", src);
|
||||
defer test_env.deinit();
|
||||
|
||||
// Should have a canonicalization problem because Builtin is not a module that can be imported
|
||||
const diagnostics = try test_env.module_env.getDiagnostics();
|
||||
defer test_env.module_env.gpa.free(diagnostics);
|
||||
|
||||
// Expect at least one diagnostic (module not found error)
|
||||
try testing.expect(diagnostics.len > 0);
|
||||
}
|
||||
|
||||
test "can define userspace type named Builtin" {
|
||||
const src =
|
||||
\\Test := [A, B, C]
|
||||
\\
|
||||
\\Builtin := [D, E, F]
|
||||
\\
|
||||
\\x : Builtin
|
||||
\\x = D
|
||||
;
|
||||
|
||||
var test_env = try TestEnv.init("Test", src);
|
||||
defer test_env.deinit();
|
||||
|
||||
// Should have no problems - Builtin is a valid userspace name
|
||||
try test_env.assertDefType("x", "Builtin");
|
||||
}
|
||||
|
||||
test "builtin types are still available without import" {
|
||||
const src =
|
||||
\\Test := [Whatever]
|
||||
\\
|
||||
\\x : Str
|
||||
\\x = "hello"
|
||||
\\
|
||||
\\y : List(U64)
|
||||
\\y = [1, 2, 3]
|
||||
;
|
||||
|
||||
var test_env = try TestEnv.init("Test", src);
|
||||
defer test_env.deinit();
|
||||
|
||||
// Builtin types like Str and List should work without importing Builtin
|
||||
try test_env.assertDefType("x", "Str");
|
||||
try test_env.assertDefType("y", "List(Num(Int(Unsigned64)))");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue