Skip to content

Commit 73fa03d

Browse files
Merge remote-tracking branch 'origin/main' into numeric-builtins
# Conflicts: # src/backend/dev/LirCodeGen.zig # src/build/roc/Builtin.roc # src/cli/main.zig # src/cli/targets/arm64musl/roc_default_platform.o # test/snapshots/match_expr/guards_1.md # test/snapshots/type_app_multiple_args.md
2 parents a5c4226 + 1829fdf commit 73fa03d

111 files changed

Lines changed: 3672 additions & 603 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ src/snapshots/**/*.html
140140

141141
# Local claude-code settings
142142
.claude/
143+
.claude
143144

144145
*.bak
145146
kcov-output/

src/backend/dev/LirCodeGen.zig

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3945,10 +3945,16 @@ pub fn LirCodeGen(comptime target: RocTarget) type {
39453945
return .{ .general_reg = gt_reg };
39463946
},
39473947

3948+
// Resolved before backend codegen: builtin `from_numeral` is
3949+
// folded to a constant during Monotype lowering, so the op must
3950+
// never reach a backend. Reaching here is an invariant failure,
3951+
// not a missing feature.
3952+
.num_from_numeral => {
3953+
std.debug.panic("num_from_numeral reached the dev backend; it must be folded to a constant during Monotype lowering", .{});
3954+
},
39483955
// Unimplemented ops
39493956
.num_log,
39503957
.num_round,
3951-
.num_from_numeral,
39523958
=> {
39533959
std.debug.panic("UNIMPLEMENTED low-level op: {s}", .{@tagName(ll.op)});
39543960
},
@@ -5649,7 +5655,8 @@ pub fn LirCodeGen(comptime target: RocTarget) type {
56495655
try locals.put(localKey(expect_stmt.condition), expect_stmt.condition);
56505656
try stack.append(sa, expect_stmt.next);
56515657
},
5652-
.runtime_error => {},
5658+
.comptime_branch_taken => |marker| try stack.append(sa, marker.next),
5659+
.runtime_error, .comptime_exhaustiveness_failed => {},
56535660
.incref => |inc| {
56545661
try locals.put(localKey(inc.value), inc.value);
56555662
try stack.append(sa, inc.next);
@@ -5770,7 +5777,8 @@ pub fn LirCodeGen(comptime target: RocTarget) type {
57705777
try locals.put(localKey(expect_stmt.condition), expect_stmt.condition);
57715778
try stack.append(sa, expect_stmt.next);
57725779
},
5773-
.runtime_error => {},
5780+
.comptime_branch_taken => |marker| try stack.append(sa, marker.next),
5781+
.runtime_error, .comptime_exhaustiveness_failed => {},
57745782
.incref => |inc| {
57755783
try locals.put(localKey(inc.value), inc.value);
57765784
try stack.append(sa, inc.next);
@@ -14488,6 +14496,15 @@ pub fn LirCodeGen(comptime target: RocTarget) type {
1448814496
try self.emitTrap();
1448914497
},
1449014498

14499+
.comptime_exhaustiveness_failed => {
14500+
try self.emitRocCrash("compile-time exhaustiveness failure reached runtime code");
14501+
try self.emitTrap();
14502+
},
14503+
14504+
.comptime_branch_taken => |marker| {
14505+
try work.append(wa, .{ .node = marker.next });
14506+
},
14507+
1449114508
.join => |j| {
1449214509
const jp_key = @intFromEnum(j.id);
1449314510
try self.setupJoinPointParams(j.id, j.params);

src/backend/llvm/Builder.zig

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6111,7 +6111,7 @@ pub const WipFunction = struct {
61116111
args: []const Value,
61126112
name: []const u8,
61136113
) Allocator.Error!Value {
6114-
return self.callInner(kind, call_conv, function_attributes, ty, callee, args, name, false);
6114+
return self.callInner(kind, call_conv, function_attributes, ty, callee, args, name, false, false);
61156115
}
61166116

61176117
fn callInner(
@@ -6124,6 +6124,7 @@ pub const WipFunction = struct {
61246124
args: []const Value,
61256125
name: []const u8,
61266126
has_op_bundle_cold: bool,
6127+
force_debug_location: bool,
61276128
) Allocator.Error!Value {
61286129
const ret_ty = ty.functionReturn(self.builder);
61296130
assert(ty.isFunction(self.builder));
@@ -6132,31 +6133,35 @@ pub const WipFunction = struct {
61326133
for (params, args[0..params.len]) |param, arg_val| assert(param == arg_val.typeOfWip(self));
61336134

61346135
try self.ensureUnusedExtraCapacity(1, Instruction.Call, args.len);
6135-
const instruction = try self.addInst(switch (ret_ty) {
6136-
.void => null,
6137-
else => name,
6138-
}, .{
6139-
.tag = switch (kind) {
6140-
.normal => .call,
6141-
.fast => .@"call fast",
6142-
.musttail => .@"musttail call",
6143-
.musttail_fast => .@"musttail call fast",
6144-
.notail => .@"notail call",
6145-
.notail_fast => .@"notail call fast",
6146-
.tail => .@"tail call",
6147-
.tail_fast => .@"tail call fast",
6148-
},
6149-
.data = self.addExtraAssumeCapacity(Instruction.Call{
6150-
.info = .{
6151-
.call_conv = call_conv,
6152-
.has_op_bundle_cold = has_op_bundle_cold,
6136+
const instruction = try self.addInstInner(
6137+
switch (ret_ty) {
6138+
.void => null,
6139+
else => name,
6140+
},
6141+
.{
6142+
.tag = switch (kind) {
6143+
.normal => .call,
6144+
.fast => .@"call fast",
6145+
.musttail => .@"musttail call",
6146+
.musttail_fast => .@"musttail call fast",
6147+
.notail => .@"notail call",
6148+
.notail_fast => .@"notail call fast",
6149+
.tail => .@"tail call",
6150+
.tail_fast => .@"tail call fast",
61536151
},
6154-
.attributes = function_attributes,
6155-
.ty = ty,
6156-
.callee = callee,
6157-
.args_len = @intCast(args.len),
6158-
}),
6159-
});
6152+
.data = self.addExtraAssumeCapacity(Instruction.Call{
6153+
.info = .{
6154+
.call_conv = call_conv,
6155+
.has_op_bundle_cold = has_op_bundle_cold,
6156+
},
6157+
.attributes = function_attributes,
6158+
.ty = ty,
6159+
.callee = callee,
6160+
.args_len = @intCast(args.len),
6161+
}),
6162+
},
6163+
force_debug_location,
6164+
);
61606165
self.extra.appendSliceAssumeCapacity(@ptrCast(args));
61616166
return instruction.toValue();
61626167
}
@@ -6185,14 +6190,19 @@ pub const WipFunction = struct {
61856190
name: []const u8,
61866191
) Allocator.Error!Value {
61876192
const intrinsic = try self.builder.getIntrinsic(id, overload);
6188-
return self.call(
6193+
return self.callInner(
61896194
fast.toCallKind(),
61906195
CallConv.default,
61916196
function_attributes,
61926197
intrinsic.typeOf(self.builder),
61936198
intrinsic.toValue(self.builder),
61946199
args,
61956200
name,
6201+
false,
6202+
switch (id) {
6203+
.@"dbg.declare", .@"dbg.value" => self.debug_location != .no_location,
6204+
else => false,
6205+
},
61966206
);
61976207
}
61986208

@@ -6207,6 +6217,7 @@ pub const WipFunction = struct {
62076217
&.{try self.builder.intValue(.i1, 1)},
62086218
"",
62096219
true,
6220+
false,
62106221
);
62116222
}
62126223

@@ -6990,6 +7001,15 @@ pub const WipFunction = struct {
69907001
self: *WipFunction,
69917002
name: ?[]const u8,
69927003
instruction: Instruction,
7004+
) Allocator.Error!Instruction.Index {
7005+
return self.addInstInner(name, instruction, false);
7006+
}
7007+
7008+
fn addInstInner(
7009+
self: *WipFunction,
7010+
name: ?[]const u8,
7011+
instruction: Instruction,
7012+
force_debug_location: bool,
69937013
) Allocator.Error!Instruction.Index {
69947014
const block_instructions = &self.cursor.block.ptr(self).instructions;
69957015
try self.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
@@ -7007,7 +7027,8 @@ pub const WipFunction = struct {
70077027
self.instructions.appendAssumeCapacity(instruction);
70087028
if (!self.strip) {
70097029
self.names.appendAssumeCapacity(final_name);
7010-
if (block_instructions.items.len == 0 or
7030+
if (force_debug_location or
7031+
block_instructions.items.len == 0 or
70117032
!std.meta.eql(self.debug_location, self.prev_debug_location))
70127033
{
70137034
self.debug_locations.putAssumeCapacity(index, self.debug_location);

src/backend/llvm/MonoLlvmCodeGen.zig

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ pub const MonoLlvmCodeGen = struct {
171171
/// one subprogram per proc, and per-statement line locations from the
172172
/// LIR store's source-location tables.
173173
emit_debug_info: bool = false,
174+
/// Emit local variable declarations for source-level debugger inspection.
175+
emit_local_debug_info: bool = false,
174176
/// Build-only default-platform Linux executables link a small runtime
175177
/// object that owns process startup diagnostics and signal handling.
176178
enable_default_platform_runtime: bool = false,
@@ -1187,7 +1189,9 @@ pub const MonoLlvmCodeGen = struct {
11871189
defer self.allocator.free(self.local_slots);
11881190
try self.allocLocalSlots();
11891191
try self.unpackProcArgs(proc);
1190-
if (!builder.strip) try self.declareFrameLocals(proc, self.store.procLoc(proc_id).line);
1192+
if (!builder.strip and self.emit_local_debug_info) {
1193+
try self.declareFrameLocals(proc, self.store.procLoc(proc_id).line);
1194+
}
11911195

11921196
if (proc.hosted) |hosted| {
11931197
try self.emitHostedProcBody(hosted, proc);
@@ -1388,7 +1392,7 @@ pub const MonoLlvmCodeGen = struct {
13881392
arg_layouts: []const layout.Idx,
13891393
ret_layout: layout.Idx,
13901394
) Error!void {
1391-
if (self.enable_default_platform_runtime and
1395+
if (self.enable_default_platform_hosted_calls and
13921396
self.host_call_mode == .extern_symbols and
13931397
self.target.os.tag == .linux and
13941398
std.mem.eql(u8, symbol_name, "_start"))
@@ -1798,6 +1802,12 @@ pub const MonoLlvmCodeGen = struct {
17981802
.runtime_error => {
17991803
try self.emitCrashBytes("hit a runtime error");
18001804
},
1805+
.comptime_exhaustiveness_failed => {
1806+
try self.emitCrashBytes("compile-time exhaustiveness failure reached runtime code");
1807+
},
1808+
.comptime_branch_taken => |marker| {
1809+
try work.append(wa, .{ .node = marker.next });
1810+
},
18011811
.incref => |inc| {
18021812
try self.emitRcForLocal(.incref, inc.value, inc.count, inc.atomicity);
18031813
try work.append(wa, .{ .node = inc.next });

src/backend/wasm/WasmCodeGen.zig

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3184,7 +3184,8 @@ fn collectProcLocals(
31843184
try recordProcLocal(locals, expect_stmt.condition);
31853185
try work.append(wa, expect_stmt.next);
31863186
},
3187-
.runtime_error => {},
3187+
.comptime_branch_taken => |marker| try work.append(wa, marker.next),
3188+
.runtime_error, .comptime_exhaustiveness_failed => {},
31883189
.switch_stmt => |switch_stmt| {
31893190
try recordProcLocal(locals, switch_stmt.cond);
31903191
for (self.store.getCFSwitchBranches(switch_stmt.branches)) |branch| {
@@ -7371,6 +7372,13 @@ fn generateCFStmtNode(self: *Self, work: *std.ArrayList(StmtWork), wa: Allocator
73717372
try self.emitRocStaticStringCall(wasm_roc_ops_crashed_offset, msg);
73727373
self.currentCode().append(self.allocator, Op.@"unreachable") catch return error.OutOfMemory;
73737374
},
7375+
.comptime_exhaustiveness_failed => {
7376+
try self.emitRocStaticStringCall(wasm_roc_ops_crashed_offset, "compile-time exhaustiveness failure reached runtime code");
7377+
self.currentCode().append(self.allocator, Op.@"unreachable") catch return error.OutOfMemory;
7378+
},
7379+
.comptime_branch_taken => |marker| {
7380+
try work.append(wa, .{ .node = .{ .stmt_id = marker.next, .stop = stop } });
7381+
},
73747382
.crash => |crash| {
73757383
const msg_bytes = self.store.getString(crash.msg);
73767384
try self.emitRocStaticStringCall(wasm_roc_ops_crashed_offset, msg_bytes);
@@ -10535,7 +10543,7 @@ fn generateLowLevel(self: *Self, ll: anytype) Allocator.Error!void {
1053510543
.{@tagName(self.procLocalLayoutIdx(args[0]))},
1053610544
),
1053710545
},
10538-
.num_from_numeral => unreachable, // Resolved before backend codegen
10546+
.num_from_numeral => unreachable, // Folded to a constant during Monotype lowering
1053910547

1054010548
// Box operations
1054110549
.box_box => {

src/base/mod.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ pub const CalledVia = enum {
8282
/// Try.parallel(get("a"), get("b"), (|foo, bar | { foo, bar }))
8383
/// ```
8484
record_builder,
85+
/// This call is the result of desugaring range syntax,
86+
/// e.g. `1..<5` becomes `Iter.exclusive_range(1, 5)`.
87+
range,
8588
};
8689

8790
/// Represents a value written as-is in a Roc source file.

0 commit comments

Comments
 (0)