mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Fix even more violations
This commit is contained in:
parent
eef0fac4b5
commit
55ca8d75db
9 changed files with 75 additions and 21 deletions
|
|
@ -195,6 +195,11 @@ f32_type_ident: Ident.Idx,
|
|||
f64_type_ident: Ident.Idx,
|
||||
dec_type_ident: Ident.Idx,
|
||||
|
||||
// Field/tag names used during type checking
|
||||
before_dot_ident: Ident.Idx,
|
||||
after_dot_ident: Ident.Idx,
|
||||
provided_by_compiler_ident: Ident.Idx,
|
||||
|
||||
/// Deferred numeric literals collected during type checking
|
||||
/// These will be validated during comptime evaluation
|
||||
deferred_numeric_literals: DeferredNumericLiteral.SafeList,
|
||||
|
|
@ -309,6 +314,9 @@ pub fn init(gpa: std.mem.Allocator, source: []const u8) std.mem.Allocator.Error!
|
|||
const f32_type_ident = try common.insertIdent(gpa, Ident.for_text("Builtin.Num.F32"));
|
||||
const f64_type_ident = try common.insertIdent(gpa, Ident.for_text("Builtin.Num.F64"));
|
||||
const dec_type_ident = try common.insertIdent(gpa, Ident.for_text("Builtin.Num.Dec"));
|
||||
const before_dot_ident = try common.insertIdent(gpa, Ident.for_text("before_dot"));
|
||||
const after_dot_ident = try common.insertIdent(gpa, Ident.for_text("after_dot"));
|
||||
const provided_by_compiler_ident = try common.insertIdent(gpa, Ident.for_text("ProvidedByCompiler"));
|
||||
|
||||
return Self{
|
||||
.gpa = gpa,
|
||||
|
|
@ -363,6 +371,9 @@ pub fn init(gpa: std.mem.Allocator, source: []const u8) std.mem.Allocator.Error!
|
|||
.f32_type_ident = f32_type_ident,
|
||||
.f64_type_ident = f64_type_ident,
|
||||
.dec_type_ident = dec_type_ident,
|
||||
.before_dot_ident = before_dot_ident,
|
||||
.after_dot_ident = after_dot_ident,
|
||||
.provided_by_compiler_ident = provided_by_compiler_ident,
|
||||
.deferred_numeric_literals = try DeferredNumericLiteral.SafeList.initCapacity(gpa, 32),
|
||||
};
|
||||
}
|
||||
|
|
@ -1822,6 +1833,9 @@ pub const Serialized = extern struct {
|
|||
f32_type_ident: Ident.Idx,
|
||||
f64_type_ident: Ident.Idx,
|
||||
dec_type_ident: Ident.Idx,
|
||||
before_dot_ident: Ident.Idx,
|
||||
after_dot_ident: Ident.Idx,
|
||||
provided_by_compiler_ident: Ident.Idx,
|
||||
deferred_numeric_literals: DeferredNumericLiteral.SafeList.Serialized,
|
||||
|
||||
/// Serialize a ModuleEnv into this Serialized struct, appending data to the writer
|
||||
|
|
@ -1897,6 +1911,9 @@ pub const Serialized = extern struct {
|
|||
self.f32_type_ident = env.f32_type_ident;
|
||||
self.f64_type_ident = env.f64_type_ident;
|
||||
self.dec_type_ident = env.dec_type_ident;
|
||||
self.before_dot_ident = env.before_dot_ident;
|
||||
self.after_dot_ident = env.after_dot_ident;
|
||||
self.provided_by_compiler_ident = env.provided_by_compiler_ident;
|
||||
}
|
||||
|
||||
/// Deserialize a ModuleEnv from the buffer, updating the ModuleEnv in place
|
||||
|
|
@ -1973,6 +1990,9 @@ pub const Serialized = extern struct {
|
|||
.f32_type_ident = self.f32_type_ident,
|
||||
.f64_type_ident = self.f64_type_ident,
|
||||
.dec_type_ident = self.dec_type_ident,
|
||||
.before_dot_ident = self.before_dot_ident,
|
||||
.after_dot_ident = self.after_dot_ident,
|
||||
.provided_by_compiler_ident = self.provided_by_compiler_ident,
|
||||
.deferred_numeric_literals = self.deferred_numeric_literals.deserialize(offset).*,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1077,7 +1077,13 @@ fn processRequiresTypes(self: *Self, env: *Env) std.mem.Allocator.Error!void {
|
|||
/// Check that the app's exported values match the platform's required types.
|
||||
/// This should be called after checkFile() to verify that app exports conform
|
||||
/// to the platform's requirements.
|
||||
pub fn checkPlatformRequirements(self: *Self, platform_env: *const ModuleEnv) std.mem.Allocator.Error!void {
|
||||
/// The `platform_to_app_idents` map translates platform ident indices to app ident indices,
|
||||
/// built by the caller to avoid string lookups during type checking.
|
||||
pub fn checkPlatformRequirements(
|
||||
self: *Self,
|
||||
platform_env: *const ModuleEnv,
|
||||
platform_to_app_idents: *const std.AutoHashMap(Ident.Idx, Ident.Idx),
|
||||
) std.mem.Allocator.Error!void {
|
||||
const trace = tracy.trace(@src());
|
||||
defer trace.end();
|
||||
|
||||
|
|
@ -1088,12 +1094,8 @@ pub fn checkPlatformRequirements(self: *Self, platform_env: *const ModuleEnv) st
|
|||
// Iterate over the platform's required types
|
||||
const requires_types_slice = platform_env.requires_types.items.items;
|
||||
for (requires_types_slice) |required_type| {
|
||||
// Get the identifier name for this required type and translate to app module
|
||||
const required_ident = required_type.ident;
|
||||
const required_ident_text = platform_env.getIdent(required_ident);
|
||||
|
||||
// Translate the platform ident to an app module ident (if it exists)
|
||||
const app_required_ident = self.cir.common.findIdent(required_ident_text);
|
||||
// Look up the pre-translated app ident for this platform requirement
|
||||
const app_required_ident = platform_to_app_idents.get(required_type.ident);
|
||||
|
||||
// Find the matching export in the app
|
||||
const app_exports_slice = self.cir.store.sliceDefs(self.cir.exports);
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ fn loadCompiledModule(gpa: std.mem.Allocator, bin_data: []const u8, module_name:
|
|||
.f32_type_ident = common.findIdent("Builtin.Num.F32") orelse unreachable,
|
||||
.f64_type_ident = common.findIdent("Builtin.Num.F64") orelse unreachable,
|
||||
.dec_type_ident = common.findIdent("Builtin.Num.Dec") orelse unreachable,
|
||||
.before_dot_ident = common.findIdent("before_dot") orelse unreachable,
|
||||
.after_dot_ident = common.findIdent("after_dot") orelse unreachable,
|
||||
.provided_by_compiler_ident = common.findIdent("ProvidedByCompiler") orelse unreachable,
|
||||
.deferred_numeric_literals = try ModuleEnv.DeferredNumericLiteral.SafeList.initCapacity(gpa, 0),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1198,8 +1198,8 @@ const Unifier = struct {
|
|||
const args_slice = self.types_store.sliceVars(func.args);
|
||||
if (args_slice.len != 1) return false;
|
||||
|
||||
const before_ident = self.module_env.common.findIdent("before_dot") orelse return false;
|
||||
const after_ident = self.module_env.common.findIdent("after_dot") orelse return false;
|
||||
const before_ident = self.module_env.before_dot_ident;
|
||||
const after_ident = self.module_env.after_dot_ident;
|
||||
|
||||
const record_desc = self.types_store.resolveVar(args_slice[0]);
|
||||
const record = switch (record_desc.desc.content) {
|
||||
|
|
@ -1322,7 +1322,7 @@ const Unifier = struct {
|
|||
// Create nominal List(U8) - List is from Builtin module
|
||||
// If List ident is not found, something is wrong with the environment
|
||||
// This should never happen in a properly initialized compiler!
|
||||
const list_ident = self.module_env.common.findIdent("List") orelse unreachable;
|
||||
const list_ident = self.module_env.list_type_ident;
|
||||
|
||||
// Use the cached builtin_module_ident which represents the "Builtin" module.
|
||||
const origin_module = if (self.module_lookup.get(self.module_env.builtin_module_ident)) |_|
|
||||
|
|
@ -1341,7 +1341,7 @@ const Unifier = struct {
|
|||
}) catch return error.AllocatorError;
|
||||
|
||||
// Create the [ProvidedByCompiler] tag
|
||||
const provided_tag_ident = self.module_env.common.findIdent("ProvidedByCompiler") orelse unreachable;
|
||||
const provided_tag_ident = self.module_env.provided_by_compiler_ident;
|
||||
const provided_tag = self.types_store.mkTag(provided_tag_ident, &.{}) catch return error.AllocatorError;
|
||||
|
||||
const tag_union = TagUnion{
|
||||
|
|
@ -1394,11 +1394,7 @@ const Unifier = struct {
|
|||
}
|
||||
|
||||
// Also check for fully qualified Builtin.Try
|
||||
if (self.module_env.common.findIdent("Builtin.Try")) |builtin_try_ident| {
|
||||
return nominal.ident.ident_idx == builtin_try_ident;
|
||||
}
|
||||
|
||||
return false;
|
||||
return nominal.ident.ident_idx == self.module_env.builtin_try_ident;
|
||||
}
|
||||
|
||||
fn createOutOfRangeTagUnion(self: *Self) Error!Var {
|
||||
|
|
|
|||
|
|
@ -1665,7 +1665,18 @@ pub fn setupSharedMemoryWithModuleEnv(allocs: *Allocators, roc_file_path: []cons
|
|||
|
||||
// Check that app exports match platform requirements (if platform exists)
|
||||
if (platform_main_env) |penv| {
|
||||
try app_checker.checkPlatformRequirements(penv);
|
||||
// Build the platform-to-app ident translation map
|
||||
var platform_to_app_idents = std.AutoHashMap(base.Ident.Idx, base.Ident.Idx).init(allocs.gpa);
|
||||
defer platform_to_app_idents.deinit();
|
||||
|
||||
for (penv.requires_types.items.items) |required_type| {
|
||||
const platform_ident_text = penv.getIdent(required_type.ident);
|
||||
if (app_env.common.findIdent(platform_ident_text)) |app_ident| {
|
||||
try platform_to_app_idents.put(required_type.ident, app_ident);
|
||||
}
|
||||
}
|
||||
|
||||
try app_checker.checkPlatformRequirements(penv, &platform_to_app_idents);
|
||||
}
|
||||
|
||||
app_env_ptr.* = app_env;
|
||||
|
|
|
|||
|
|
@ -642,8 +642,20 @@ pub const BuildEnv = struct {
|
|||
);
|
||||
defer checker.deinit();
|
||||
|
||||
// Build the platform-to-app ident translation map
|
||||
// This translates platform requirement idents to app idents by name
|
||||
var platform_to_app_idents = std.AutoHashMap(base.Ident.Idx, base.Ident.Idx).init(self.gpa);
|
||||
defer platform_to_app_idents.deinit();
|
||||
|
||||
for (platform_root_env.requires_types.items.items) |required_type| {
|
||||
const platform_ident_text = platform_root_env.getIdent(required_type.ident);
|
||||
if (app_root_env.common.findIdent(platform_ident_text)) |app_ident| {
|
||||
try platform_to_app_idents.put(required_type.ident, app_ident);
|
||||
}
|
||||
}
|
||||
|
||||
// Check platform requirements against app exports
|
||||
try checker.checkPlatformRequirements(platform_root_env);
|
||||
try checker.checkPlatformRequirements(platform_root_env, &platform_to_app_idents);
|
||||
|
||||
// If there are type problems, convert them to reports and emit via sink
|
||||
if (checker.problems.problems.items.len > 0) {
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ test "ModuleEnv.Serialized roundtrip" {
|
|||
.f32_type_ident = common.findIdent("Builtin.Num.F32") orelse unreachable,
|
||||
.f64_type_ident = common.findIdent("Builtin.Num.F64") orelse unreachable,
|
||||
.dec_type_ident = common.findIdent("Builtin.Num.Dec") orelse unreachable,
|
||||
.before_dot_ident = common.findIdent("before_dot") orelse unreachable,
|
||||
.after_dot_ident = common.findIdent("after_dot") orelse unreachable,
|
||||
.provided_by_compiler_ident = common.findIdent("ProvidedByCompiler") orelse unreachable,
|
||||
.deferred_numeric_literals = try ModuleEnv.DeferredNumericLiteral.SafeList.initCapacity(deser_alloc, 0),
|
||||
};
|
||||
|
||||
|
|
@ -150,7 +153,8 @@ test "ModuleEnv.Serialized roundtrip" {
|
|||
// initCIRFields inserts the module name ("TestModule") into the interner, so we have 3 total: hello, world, TestModule
|
||||
// ModuleEnv.init() also interns 19 well-known identifiers: from_int_digits, from_dec_digits, Try, OutOfRange, Builtin, plus, minus, times, div_by, div_trunc_by, rem_by, negate, not, is_lt, is_lte, is_gt, is_gte, is_eq, is_ne
|
||||
// Plus 17 type identifiers: Builtin.Try, Builtin.Num.Numeral, List, Box, Builtin.Num.{U8, I8, U16, I16, U32, I32, U64, I64, U128, I128, F32, F64, Dec}
|
||||
try testing.expectEqual(@as(u32, 39), original.common.idents.interner.entry_count);
|
||||
// Plus 3 field/tag identifiers: before_dot, after_dot, ProvidedByCompiler
|
||||
try testing.expectEqual(@as(u32, 42), original.common.idents.interner.entry_count);
|
||||
try testing.expectEqualStrings("hello", original.getIdent(hello_idx));
|
||||
try testing.expectEqualStrings("world", original.getIdent(world_idx));
|
||||
|
||||
|
|
@ -159,8 +163,8 @@ test "ModuleEnv.Serialized roundtrip" {
|
|||
try testing.expectEqual(@as(usize, 2), original.imports.imports.len()); // Should have 2 unique imports
|
||||
|
||||
// First verify that the CommonEnv data was preserved after deserialization
|
||||
// Should have same 39 identifiers as original: hello, world, TestModule + 19 well-known identifiers + 17 type identifiers from ModuleEnv.init()
|
||||
try testing.expectEqual(@as(u32, 39), env.common.idents.interner.entry_count);
|
||||
// Should have same 42 identifiers as original: hello, world, TestModule + 19 well-known identifiers + 17 type identifiers + 3 field/tag identifiers from ModuleEnv.init()
|
||||
try testing.expectEqual(@as(u32, 42), env.common.idents.interner.entry_count);
|
||||
|
||||
try testing.expectEqual(@as(usize, 1), env.common.exposed_items.count());
|
||||
try testing.expectEqual(@as(?u16, 42), env.common.exposed_items.getNodeIndexById(gpa, @as(u32, @bitCast(hello_idx))));
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,9 @@ fn compileSource(source: []const u8) !CompilerStageData {
|
|||
.f32_type_ident = common.findIdent("Builtin.Num.F32") orelse unreachable,
|
||||
.f64_type_ident = common.findIdent("Builtin.Num.F64") orelse unreachable,
|
||||
.dec_type_ident = common.findIdent("Builtin.Num.Dec") orelse unreachable,
|
||||
.before_dot_ident = common.findIdent("before_dot") orelse unreachable,
|
||||
.after_dot_ident = common.findIdent("after_dot") orelse unreachable,
|
||||
.provided_by_compiler_ident = common.findIdent("ProvidedByCompiler") orelse unreachable,
|
||||
.deferred_numeric_literals = try ModuleEnv.DeferredNumericLiteral.SafeList.initCapacity(gpa, 0),
|
||||
};
|
||||
logDebug("loadCompiledModule: ModuleEnv deserialized successfully\n", .{});
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ fn loadCompiledModule(gpa: std.mem.Allocator, bin_data: []const u8, module_name:
|
|||
.f32_type_ident = common.findIdent("Builtin.Num.F32") orelse unreachable,
|
||||
.f64_type_ident = common.findIdent("Builtin.Num.F64") orelse unreachable,
|
||||
.dec_type_ident = common.findIdent("Builtin.Num.Dec") orelse unreachable,
|
||||
.before_dot_ident = common.findIdent("before_dot") orelse unreachable,
|
||||
.after_dot_ident = common.findIdent("after_dot") orelse unreachable,
|
||||
.provided_by_compiler_ident = common.findIdent("ProvidedByCompiler") orelse unreachable,
|
||||
.deferred_numeric_literals = try ModuleEnv.DeferredNumericLiteral.SafeList.initCapacity(gpa, 0),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue