From 01cc996183a0a2de2b52c5f5fb43403996e3587d Mon Sep 17 00:00:00 2001 From: Brett Broadhurst Date: Tue, 31 Mar 2026 15:11:54 -0600 Subject: [PATCH] fix: add .break_inline ir instruction to ensure interned values can be referenced --- src/AstGen.zig | 9 +++++---- src/Ir.zig | 2 ++ src/Sema.zig | 7 +++++++ src/print_ir.zig | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index 85d4d38..c3199e9 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1173,7 +1173,7 @@ fn choiceStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void } } - var body_block = gi.makeSubBlock(); + var body_block = block_3.makeSubBlock(); defer body_block.unstack(); if (trailing_divert) |trailing| { @@ -1190,7 +1190,7 @@ fn choiceStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void const rhs_body = block_3.instructionsSliceUpto(&body_block); const body = body_block.instructionsSlice(); const case_extra_len = - @typeInfo(Ir.Inst.SwitchBr.Case).@"struct".fields.len + + @typeInfo(Ir.Inst.ChoiceBr.Case).@"struct".fields.len + lhs_body.len + mhs_body.len + rhs_body.len + body.len; try astgen.extra.ensureUnusedCapacity(gpa, case_extra_len); @@ -1441,9 +1441,10 @@ fn varDecl(gi: *GenIr, scope: *Scope, decl_node: *const Ast.Node) !void { var decl_block = gi.makeSubBlock(); defer decl_block.unstack(); - const var_inst = try decl_block.makePayloadNode(.decl_var); - _ = try expr(&decl_block, scope, expr_node); const name_str = try astgen.strFromNode(identifier_node); + const var_inst = try decl_block.makePayloadNode(.decl_var); + const rvalue_inst = try expr(&decl_block, scope, expr_node); + _ = try decl_block.addBinaryNode(.break_inline, var_inst.toRef(), rvalue_inst); try setDeclVarPayload(var_inst, &decl_block, identifier_node); try setDeclaration(decl_inst, .{ diff --git a/src/Ir.zig b/src/Ir.zig index b248ade..d025c03 100644 --- a/src/Ir.zig +++ b/src/Ir.zig @@ -201,6 +201,7 @@ pub const Inst = struct { block, condbr, @"break", + break_inline, switch_br, /// Uses the `un` union field. content_push, @@ -388,6 +389,7 @@ pub const Inst = struct { .ret, .implicit_ret, .@"break", + .break_inline, .done, .exit, => true, diff --git a/src/Sema.zig b/src/Sema.zig index 7538313..cd55597 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -629,6 +629,12 @@ fn irBreak(sema: *Sema, inst: Ir.Inst.Index) InnerError!void { _ = inst; } +fn irBreakInline(sema: *Sema, inst: Ir.Inst.Index) InnerError!ValueInfo { + const data = sema.ir.instructions[@intFromEnum(inst)].data.bin; + const rvalue_inst = sema.resolveInst(data.rhs); + return rvalue_inst; +} + fn irBlock(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void { const data = sema.ir.instructions[@intFromEnum(inst)].data.payload; const extra = sema.ir.extraData(Ir.Inst.Block, data.extra_index); @@ -1002,6 +1008,7 @@ fn analyzeBodyInner( try irBreak(sema, inst); continue; }, + .break_inline => try irBreakInline(sema, inst), .block => { try irBlock(sema, builder, inst); continue; diff --git a/src/print_ir.zig b/src/print_ir.zig index 2852aac..4bb830b 100644 --- a/src/print_ir.zig +++ b/src/print_ir.zig @@ -318,6 +318,7 @@ pub const Writer = struct { .decl_ref => try self.writeStrTokInst(w, inst), .condbr => try self.writeCondbrInst(w, inst), .@"break" => try self.writeBreakInst(w, inst), + .break_inline => try self.writeBinaryInst(w, inst), .switch_br => try self.writeSwitchBrInst(w, inst), .alloc => {}, .load => try self.writeUnaryInst(w, inst),