Fix tests

This commit is contained in:
Richard Feldman 2025-11-08 11:56:51 -05:00
parent 1fe4fd6971
commit ca6abe360d
No known key found for this signature in database
3 changed files with 6 additions and 57 deletions

View file

@ -496,9 +496,11 @@ fn processTypeDeclFirstPass(
try self.env.setExposedNodeIndexById(qualified_name_idx, node_idx_u16);
// Extract and expose functions from the associated block
// For Type Modules like `Stdout := [].{ line! : Str => {} }`, the associated block
// For Platform Type Modules like `Stdout := [].{ line! : Str => {} }`, the associated block
// contains type annotation statements for the effectful functions
if (type_decl.associated) |assoc| {
// Only do this for platform modules
if (self.env.building_platform_modules) {
if (type_decl.associated) |assoc| {
const assoc_statements = self.parse_ir.store.statementSlice(assoc.statements);
for (assoc_statements) |stmt_idx| {
@ -535,6 +537,7 @@ fn processTypeDeclFirstPass(
}
}
}
}
}
}
}
@ -1309,45 +1312,13 @@ pub fn canonicalizeFile(
// For Type Modules, transform annotation-only defs into hosted lambdas (in-place)
// This allows platforms to import these modules and use the hosted functions
// Only do this when building platform modules (i.e., when root module is a platform)
std.debug.print("DEBUG: canDefinitions called for module: {s}, kind={s}, building_platform={}\n", .{ self.env.module_name, @tagName(self.env.module_kind), self.env.building_platform_modules });
// Debug: Print all defs for app modules
const is_test_module = std.mem.eql(u8, self.env.module_name, "stdin_simple.roc") or std.mem.eql(u8, self.env.module_name, "app.roc");
if (is_test_module) {
std.debug.print("DEBUG: Defs in {s}:\n", .{self.env.module_name});
const all_defs = self.env.store.sliceDefs(self.env.all_defs);
for (all_defs, 0..) |def_idx, def_i| {
const def = self.env.store.getDef(def_idx);
const expr = self.env.store.getExpr(def.expr);
std.debug.print(" def[{}] expr_idx={} expr_tag={s}\n", .{ def_i, @intFromEnum(def.expr), @tagName(expr) });
// If it's a lambda, show its body
if (expr == .e_lambda) {
const body_expr = self.env.store.getExpr(expr.e_lambda.body);
std.debug.print(" lambda body: expr_idx={} expr_tag={s}\n", .{ @intFromEnum(expr.e_lambda.body), @tagName(body_expr) });
// If the body is a call, show what it's calling
if (body_expr == .e_call) {
const func_expr = self.env.store.getExpr(body_expr.e_call.func);
const call_args = self.env.store.sliceExpr(body_expr.e_call.args);
std.debug.print(" call func: expr_idx={} expr_tag={s} num_args={}\n", .{ @intFromEnum(body_expr.e_call.func), @tagName(func_expr), call_args.len });
}
}
}
}
if (self.env.module_kind == .type_module and self.env.building_platform_modules) {
std.debug.print("DEBUG: Processing type module for hosted functions\n", .{});
std.debug.print(" Module name: {s}\n", .{self.env.module_name});
std.debug.print(" Module kind: {s}\n", .{@tagName(self.env.module_kind)});
std.debug.print(" Building platform modules: {}\n", .{self.env.building_platform_modules});
// First, create definitions for Type Module annotations (like `line! : Str => {}`)
// These annotations are exposed but don't have actual definitions yet
// We need to create e_anno_only defs for them so replaceAnnoOnlyWithHosted can transform them
const type_module_defs_start = self.env.store.scratchDefTop();
var exposed_iter = self.env.common.exposed_items.iterator();
std.debug.print(" Exposed items count: {}\n", .{self.env.common.exposed_items.count()});
while (exposed_iter.next()) |entry| {
const ident_idx = entry.ident_idx;
_ = entry.node_idx;

View file

@ -38,8 +38,6 @@ pub fn replaceAnnoOnlyWithHosted(env: *ModuleEnv) !std.ArrayList(CIR.Def.Idx) {
const pattern = env.store.getPattern(def.pattern);
if (pattern == .assign) {
const ident = pattern.assign.ident;
const ident_name = env.getIdent(ident);
std.debug.print("DEBUG: Processing anno-only def: {s}, has annotation: {}\n", .{ ident_name, def.annotation != null });
// Extract the number of arguments from the annotation
const annotation = env.store.getAnnotation(def.annotation.?);
@ -122,7 +120,7 @@ pub fn replaceAnnoOnlyWithHosted(env: *ModuleEnv) !std.ArrayList(CIR.Def.Idx) {
// Verify the def still has its annotation after modification
const modified_def = env.store.getDef(def_idx);
std.debug.print("DEBUG: After modification - def still has annotation: {}\n", .{modified_def.annotation != null});
_ = modified_def;
// Track this modified def index
try modified_def_indices.append(gpa, def_idx);

View file

@ -616,8 +616,6 @@ pub fn checkFile(self: *Self) std.mem.Allocator.Error!void {
const trace = tracy.trace(@src());
defer trace.end();
std.debug.print("DEBUG: checkFile called for module: {s}\n", .{self.cir.module_name});
try ensureTypeStoreIsFilled(self);
// Copy builtin types (Bool, Result) into this module's type store
@ -2463,21 +2461,14 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected
// Unify this expression with the referenced pattern
},
.e_lookup_external => |ext| {
std.debug.print("DEBUG Check: e_lookup_external module_idx={} node_idx={}\n", .{ @intFromEnum(ext.module_idx), ext.target_node_idx });
if (try self.resolveVarFromExternal(ext.module_idx, ext.target_node_idx)) |ext_ref| {
// Check what type was resolved
const resolved = self.types.resolveVar(ext_ref.local_var);
std.debug.print(" Resolved type: content={s}\n", .{@tagName(resolved.desc.content)});
const ext_instantiated_var = try self.instantiateVar(
ext_ref.local_var,
Rank.generalized,
.{ .explicit = expr_region },
);
std.debug.print(" Instantiated var: {}\n", .{@intFromEnum(ext_instantiated_var)});
try self.types.setVarRedirect(expr_var, ext_instantiated_var);
} else {
std.debug.print(" FAILED to resolve external!\n", .{});
try self.updateVar(expr_var, .err, rank);
}
},
@ -2726,9 +2717,7 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected
};
// Now, check the call args against the type of function
std.debug.print("DEBUG Check e_call: mb_func is_null={}\n", .{mb_func == null});
if (mb_func) |func| {
std.debug.print(" func.args.len={} call_args.len={}\n", .{ self.types.sliceVars(func.args).len, call_arg_expr_idxs.len });
const func_args = self.types.sliceVars(func.args);
// Special case: if func has 1 arg that is empty tuple () and call has 0 args, that's valid
@ -2739,7 +2728,6 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected
const struct_flat = arg_resolved.desc.content.structure;
// Empty tuple has 0 fields
if (struct_flat == .tuple and struct_flat.tuple.elems.len() == 0) {
std.debug.print(" Detected unit () argument - treating call with 0 args as valid\n", .{});
break :unit_check true;
}
}
@ -2826,9 +2814,6 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected
}
// Redirect the expr to the function's return type
std.debug.print("DEBUG Check e_call: Setting call expr type to func.ret={}\n", .{@intFromEnum(func.ret)});
const ret_resolved = self.types.resolveVar(func.ret);
std.debug.print(" func.ret resolved content={s}\n", .{@tagName(ret_resolved.desc.content)});
_ = try self.types.setVarRedirect(expr_var, func.ret);
} else {
// TODO(jared): Better arity difference error message
@ -3039,11 +3024,6 @@ fn checkExpr(self: *Self, expr_idx: CIR.Expr.Idx, rank: types_mod.Rank, expected
}
},
.e_hosted_lambda => |hosted| {
std.debug.print("DEBUG Check: e_hosted_lambda index={}, has expected={}\n", .{ hosted.index, expected == .expected });
if (expected == .expected) {
std.debug.print(" Expected type from_annotation={}\n", .{expected.expected.from_annotation});
}
// For hosted lambda expressions, treat like a lambda with a crash body.
// Check the body (which will be e_runtime_error or similar)
does_fx = try self.checkExpr(hosted.body, rank, .no_expectation) or does_fx;