Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/cli/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2229,17 +2229,19 @@ pub fn setupSharedMemoryWithModuleEnv(ctx: *CliContext, roc_file_path: []const u
const all_aliases = penv.for_clause_aliases.items.items;
const type_aliases_slice = all_aliases[@intFromEnum(required_type.type_aliases.start)..][0..required_type.type_aliases.count];
for (type_aliases_slice) |alias| {
// Add alias name (e.g., "Model") - must exist in app since it's required
// Add alias name (e.g., "Model") - insert it into app's ident store to ensure
// the mapping can be created even if canonicalization hasn't added it yet.
// The app will provide the actual type alias definition which will be checked later.
const alias_name_text = penv.getIdent(alias.alias_name);
if (app_env.common.findIdent(alias_name_text)) |app_ident| {
try platform_to_app_idents.put(alias.alias_name, app_ident);
}
const alias_app_ident = try app_env.common.insertIdent(ctx.gpa, base.Ident.for_text(alias_name_text));
try platform_to_app_idents.put(alias.alias_name, alias_app_ident);

// Add rigid name (e.g., "model") - insert it into app's ident store since
// the rigid name is a platform concept that gets copied during type processing.
// Using insert (not find) ensures the app's ident store has this name for later lookups.
const rigid_name_text = penv.getIdent(alias.rigid_name);
const app_ident = try app_env.common.insertIdent(ctx.gpa, base.Ident.for_text(rigid_name_text));
try platform_to_app_idents.put(alias.rigid_name, app_ident);
const rigid_app_ident = try app_env.common.insertIdent(ctx.gpa, base.Ident.for_text(rigid_name_text));
try platform_to_app_idents.put(alias.rigid_name, rigid_app_ident);
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/cli/test/roc_subcommands.zig
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,31 @@ test "roc check reports type error - plus operator with incompatible types" {
try testing.expect(has_type_error);
}

test "roc check test/int/app.roc does not panic" {
// Skip on Windows - test/int platform doesn't have Windows host libraries
if (@import("builtin").os.tag == .windows) return error.SkipZigTest;

const testing = std.testing;
const gpa = testing.allocator;

const result = try util.runRoc(gpa, &.{ "check", "--no-cache" }, "test/int/app.roc");
defer gpa.free(result.stdout);
defer gpa.free(result.stderr);

// Verify that roc check does not panic on test/int/app.roc.
// Prior to fix for issue #8947, this would panic with:
// "trying unifyWith unexpected ranks 1 & 0"
// Now it should fail gracefully (exit code 1) with type errors, not panic (abort).

// 1. Should not abort (panic would cause exit code 134 on macOS/Linux)
const did_panic = result.term == .Signal or (result.term == .Exited and result.term.Exited == 134);
try testing.expect(!did_panic);

// 2. Should not contain "panic" in output
const has_panic_text = std.mem.indexOf(u8, result.stderr, "panic") != null;
try testing.expect(!has_panic_text);
}

test "roc test/int/app.roc runs successfully" {
// Skip on Windows - test/int platform doesn't have Windows host libraries
if (@import("builtin").os.tag == .windows) return error.SkipZigTest;
Expand Down
19 changes: 19 additions & 0 deletions src/compile/compile_build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,25 @@ pub const BuildEnv = struct {
if (app_root_env.common.findIdent(platform_ident_text)) |app_ident| {
try platform_to_app_idents.put(required_type.ident, app_ident);
}

// Also add for-clause type alias names (Model, model) to the translation map
const all_aliases = platform_root_env.for_clause_aliases.items.items;
const type_aliases_slice = all_aliases[@intFromEnum(required_type.type_aliases.start)..][0..required_type.type_aliases.count];
for (type_aliases_slice) |alias| {
// Add alias name (e.g., "Model") - insert it into app's ident store to ensure
// the mapping can be created even if canonicalization hasn't added it yet.
// The app will provide the actual type alias definition which will be checked later.
const alias_name_text = platform_root_env.getIdent(alias.alias_name);
const alias_app_ident = try app_root_env.common.insertIdent(self.gpa, base.Ident.for_text(alias_name_text));
try platform_to_app_idents.put(alias.alias_name, alias_app_ident);

// Add rigid name (e.g., "model") - insert it into app's ident store since
// the rigid name is a platform concept that gets copied during type processing.
// Using insert (not find) ensures the app's ident store has this name for later lookups.
const rigid_name_text = platform_root_env.getIdent(alias.rigid_name);
const rigid_app_ident = try app_root_env.common.insertIdent(self.gpa, base.Ident.for_text(rigid_name_text));
try platform_to_app_idents.put(alias.rigid_name, rigid_app_ident);
}
}

// Check platform requirements against app exports
Expand Down
Loading