Reproduce and fix crash bug

This commit is contained in:
Richard Feldman 2025-11-25 09:33:28 -05:00
parent 9e509c53cc
commit a2e250d38c
No known key found for this signature in database
4 changed files with 53 additions and 3 deletions

View file

@ -7803,6 +7803,7 @@ fn canonicalizeBlock(self: *Self, e: AST.Block) std.mem.Allocator.Error!Canonica
const cir_stmt = self.env.store.getStatement(canonicailzed_stmt.idx);
switch (cir_stmt) {
.s_decl => |decl| try self.collectBoundVars(decl.pattern, &bound_vars),
.s_decl_gen => |decl| try self.collectBoundVars(decl.pattern, &bound_vars),
.s_var => |var_stmt| try self.collectBoundVars(var_stmt.pattern_idx, &bound_vars),
else => {},
}

View file

@ -264,3 +264,38 @@ test "fx platform expect with numeric literal" {
try testing.expectEqualStrings("", run_result.stdout);
try testing.expectEqualStrings("", run_result.stderr);
}
test "fx platform match with wildcard" {
const allocator = testing.allocator;
try ensureRocBinary(allocator);
// Run an app that uses a match expression with a wildcard pattern
// This tests that wildcard patterns in match expressions work correctly
const run_result = try std.process.Child.run(.{
.allocator = allocator,
.argv = &[_][]const u8{
"./zig-out/bin/roc",
"test/fx/match_with_wildcard.roc",
},
});
defer allocator.free(run_result.stdout);
defer allocator.free(run_result.stderr);
switch (run_result.term) {
.Exited => |code| {
if (code != 0) {
std.debug.print("Run failed with exit code {}\n", .{code});
std.debug.print("STDOUT: {s}\n", .{run_result.stdout});
std.debug.print("STDERR: {s}\n", .{run_result.stderr});
return error.RunFailed;
}
},
else => {
std.debug.print("Run terminated abnormally: {}\n", .{run_result.term});
std.debug.print("STDOUT: {s}\n", .{run_result.stdout});
std.debug.print("STDERR: {s}\n", .{run_result.stderr});
return error.RunFailed;
},
}
}

View file

@ -420,6 +420,16 @@ pub const Interpreter = struct {
}
const header: *const layout.Closure = @ptrCast(@alignCast(func_val.ptr.?));
// Switch to the closure's source module for correct expression evaluation.
// This is critical because pattern indices and expression indices in the closure
// are relative to the source module where the closure was defined, not the
// current module. Without this switch, bindings created in the closure body
// would have the wrong source_env and lookups would fail.
const saved_env = self.env;
self.env = @constCast(header.source_env);
defer self.env = saved_env;
const params = self.env.store.slicePatterns(header.params);
try self.active_closures.append(func_val);

View file

@ -61,9 +61,13 @@ const ShimError = error{
/// Expected format in shared memory: [u64 parent_address][u32 entry_count][ModuleEnv data][u32[] def_indices]
export fn roc_entrypoint(entry_idx: u32, ops: *builtins.host_abi.RocOps, ret_ptr: *anyopaque, arg_ptr: ?*anyopaque) callconv(.c) void {
evaluateFromSharedMemory(entry_idx, ops, ret_ptr, arg_ptr) catch |err| {
var buf: [256]u8 = undefined;
const msg2 = std.fmt.bufPrint(&buf, "Error evaluating from shared memory: {s}", .{@errorName(err)}) catch "Error evaluating from shared memory";
ops.crash(msg2);
// Only show this generic error if we haven't already crashed with a more specific message
// (errors like Crash already triggered roc_crashed with details)
if (err != error.Crash) {
var buf: [256]u8 = undefined;
const msg2 = std.fmt.bufPrint(&buf, "Error evaluating from shared memory: {s}", .{@errorName(err)}) catch "Error evaluating from shared memory";
ops.crash(msg2);
}
};
}