From 434537213e406191959818f573b24ca45c1b0e45 Mon Sep 17 00:00:00 2001 From: mlugg Date: Tue, 13 Feb 2024 01:54:57 +0000 Subject: [PATCH] Sema: eliminate `src` field `sema.src` is a failed experiment. It introduces complexity, and makes often unwarranted assumptions about the existence of instructions providing source locations, requiring an unreasonable amount of caution in AstGen for correctness. Eliminating it simplifies the whole frontend. This required adding source locations to a few instructions, but the cost in ZIR bytes should be counteracted by the other work on this branch. --- src/AstGen.zig | 140 ++++++++++++++++++++++------------------ src/Autodoc.zig | 6 +- src/Sema.zig | 159 +++++++++++++++++++++------------------------- src/Zir.zig | 85 +++++++++++++++---------- src/print_zir.zig | 37 +++++------ 5 files changed, 222 insertions(+), 205 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index a5a5b54f69..0117f0ac26 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2122,7 +2122,7 @@ fn restoreErrRetIndex( else => .none, // always restore/pop }, }; - _ = try gz.addRestoreErrRetIndex(bt, .{ .if_non_error = op }); + _ = try gz.addRestoreErrRetIndex(bt, .{ .if_non_error = op }, node); } fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { @@ -2179,7 +2179,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn // As our last action before the break, "pop" the error trace if needed if (!block_gz.is_comptime) - _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); + _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always, node); _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); return Zir.Inst.Ref.unreachable_value; @@ -2271,7 +2271,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) // As our last action before the continue, "pop" the error trace if needed if (!gen_zir.is_comptime) - _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always); + _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always, node); _ = try parent_gz.addBreak(break_tag, continue_block, .void_value); return Zir.Inst.Ref.unreachable_value; @@ -2331,7 +2331,7 @@ fn blockExpr( if (!block_scope.endsWithNoReturn()) { // As our last action before the break, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); + _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always, block_node); _ = try block_scope.addBreak(.@"break", block_inst, .void_value); } @@ -2426,7 +2426,7 @@ fn labeledBlockExpr( try blockExprStmts(&block_scope, &block_scope.base, statements); if (!block_scope.endsWithNoReturn()) { // As our last action before the return, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); + _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always, block_node); _ = try block_scope.addBreak(.@"break", block_inst, .void_value); } @@ -2818,7 +2818,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .export_value, .set_eval_branch_quota, .atomic_store, - .store, .store_node, .store_to_inferred_ptr, .resolve_inferred_alloc, @@ -2829,7 +2828,8 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .validate_deref, .validate_destructure, .save_err_ret_index, - .restore_err_ret_index, + .restore_err_ret_index_unconditional, + .restore_err_ret_index_fn_entry, .validate_struct_init_ty, .validate_struct_init_result_ty, .validate_ptr_struct_init, @@ -3692,7 +3692,10 @@ fn assignOp( .lhs = lhs, .rhs = rhs, }); - _ = try gz.addBin(.store, lhs_ptr, result); + _ = try gz.addPlNode(.store_node, infix_node, Zir.Inst.Bin{ + .lhs = lhs_ptr, + .rhs = result, + }); } fn assignShift( @@ -3715,7 +3718,10 @@ fn assignShift( .lhs = lhs, .rhs = rhs, }); - _ = try gz.addBin(.store, lhs_ptr, result); + _ = try gz.addPlNode(.store_node, infix_node, Zir.Inst.Bin{ + .lhs = lhs_ptr, + .rhs = result, + }); } fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!void { @@ -3733,7 +3739,10 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE .lhs = lhs, .rhs = rhs, }); - _ = try gz.addBin(.store, lhs_ptr, result); + _ = try gz.addPlNode(.store_node, infix_node, Zir.Inst.Bin{ + .lhs = lhs_ptr, + .rhs = result, + }); } fn ptrType( @@ -4294,7 +4303,7 @@ fn fnDecl( if (!fn_gz.endsWithNoReturn()) { // As our last action before the return, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.ret, .always); + _ = try gz.addRestoreErrRetIndex(.ret, .always, decl_node); // Add implicit return at end of function. _ = try fn_gz.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node)); @@ -4742,7 +4751,7 @@ fn testDecl( if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) { // As our last action before the return, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.ret, .always); + _ = try gz.addRestoreErrRetIndex(.ret, .always, node); // Add implicit return at end of function. _ = try fn_block.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node)); @@ -6149,7 +6158,7 @@ fn boolBinOp( const node_datas = tree.nodes.items(.data); const lhs = try expr(gz, scope, bool_ri, node_datas[node].lhs); - const bool_br = try gz.addBoolBr(zir_tag, lhs); + const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?; var rhs_scope = gz.makeSubBlock(scope); defer rhs_scope.unstack(); @@ -6157,7 +6166,7 @@ fn boolBinOp( if (!gz.refIsNoReturn(rhs)) { _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); } - try rhs_scope.setBoolBrBody(bool_br); + try rhs_scope.setBoolBrBody(bool_br, lhs); const block_ref = bool_br.toRef(); return rvalue(gz, ri, block_ref, node); @@ -6725,7 +6734,10 @@ fn forExpr( const alloc_tag: Zir.Inst.Tag = if (is_inline) .alloc_comptime_mut else .alloc; const index_ptr = try parent_gz.addUnNode(alloc_tag, .usize_type, node); // initialize to zero - _ = try parent_gz.addBin(.store, index_ptr, .zero_usize); + _ = try parent_gz.addPlNode(.store_node, node, Zir.Inst.Bin{ + .lhs = index_ptr, + .rhs = .zero_usize, + }); break :blk index_ptr; }; @@ -6955,7 +6967,10 @@ fn forExpr( .lhs = index, .rhs = .one_usize, }); - _ = try loop_scope.addBin(.store, index_ptr, index_plus_one); + _ = try loop_scope.addPlNode(.store_node, node, Zir.Inst.Bin{ + .lhs = index_ptr, + .rhs = index_plus_one, + }); const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; _ = try loop_scope.addNode(repeat_tag, node); @@ -8008,7 +8023,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref try genDefers(gz, defer_outer, scope, .normal_only); // As our last action before the return, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.ret, .always); + _ = try gz.addRestoreErrRetIndex(.ret, .always, node); _ = try gz.addUnNode(.ret_node, .void_value, node); return Zir.Inst.Ref.unreachable_value; @@ -8051,7 +8066,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref try genDefers(gz, defer_outer, scope, .normal_only); // As our last action before the return, "pop" the error trace if needed - _ = try gz.addRestoreErrRetIndex(.ret, .always); + _ = try gz.addRestoreErrRetIndex(.ret, .always, node); try emitDbgStmt(gz, ret_lc); try gz.addRet(ri, operand, node); @@ -8074,7 +8089,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref // As our last action before the return, "pop" the error trace if needed const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; - _ = try gz.addRestoreErrRetIndex(.ret, .{ .if_non_error = result }); + _ = try gz.addRestoreErrRetIndex(.ret, .{ .if_non_error = result }, node); try gz.addRet(ri, operand, node); return Zir.Inst.Ref.unreachable_value; @@ -8091,7 +8106,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref try genDefers(&then_scope, defer_outer, scope, .normal_only); // As our last action before the return, "pop" the error trace if needed - _ = try then_scope.addRestoreErrRetIndex(.ret, .always); + _ = try then_scope.addRestoreErrRetIndex(.ret, .always, node); try emitDbgStmt(&then_scope, ret_lc); try then_scope.addRet(ri, operand, node); @@ -10979,7 +10994,10 @@ fn rvalueInner( return .void_value; }, .inferred_ptr => |alloc| { - _ = try gz.addBin(.store_to_inferred_ptr, alloc, result); + _ = try gz.addPlNode(.store_to_inferred_ptr, src_node, Zir.Inst.Bin{ + .lhs = alloc, + .rhs = result, + }); return .void_value; }, .destructure => |destructure| { @@ -11006,7 +11024,10 @@ fn rvalueInner( }); }, .inferred_ptr => |ptr_inst| { - _ = try gz.addBin(.store_to_inferred_ptr, ptr_inst, elem_val); + _ = try gz.addPlNode(.store_to_inferred_ptr, src_node, Zir.Inst.Bin{ + .lhs = ptr_inst, + .rhs = elem_val, + }); }, .discard => unreachable, } @@ -11828,19 +11849,20 @@ const GenZir = struct { } /// Assumes nothing stacked on `gz`. Unstacks `gz`. - fn setBoolBrBody(gz: *GenZir, inst: Zir.Inst.Index) !void { + fn setBoolBrBody(gz: *GenZir, bool_br: Zir.Inst.Index, bool_br_lhs: Zir.Inst.Ref) !void { const astgen = gz.astgen; const gpa = astgen.gpa; const body = gz.instructionsSlice(); const body_len = astgen.countBodyLenAfterFixups(body); try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.Block).Struct.fields.len + body_len, + @typeInfo(Zir.Inst.BoolBr).Struct.fields.len + body_len, ); const zir_datas = astgen.instructions.items(.data); - zir_datas[@intFromEnum(inst)].bool_br.payload_index = astgen.addExtraAssumeCapacity( - Zir.Inst.Block{ .body_len = body_len }, - ); + zir_datas[@intFromEnum(bool_br)].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.BoolBr{ + .lhs = bool_br_lhs, + .body_len = body_len, + }); astgen.appendBodyWithFixups(body); gz.unstack(); } @@ -12225,30 +12247,6 @@ const GenZir = struct { return new_index.toRef(); } - /// Note that this returns a `Zir.Inst.Index` not a ref. - /// Leaves the `payload_index` field undefined. - fn addBoolBr( - gz: *GenZir, - tag: Zir.Inst.Tag, - lhs: Zir.Inst.Ref, - ) !Zir.Inst.Index { - assert(lhs != .none); - const gpa = gz.astgen.gpa; - try gz.instructions.ensureUnusedCapacity(gpa, 1); - try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); - - const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); - gz.astgen.instructions.appendAssumeCapacity(.{ - .tag = tag, - .data = .{ .bool_br = .{ - .lhs = lhs, - .payload_index = undefined, - } }, - }); - gz.instructions.appendAssumeCapacity(new_index); - return new_index; - } - fn addInt(gz: *GenZir, integer: u64) !Zir.Inst.Ref { return gz.add(.{ .tag = .int, @@ -12569,17 +12567,37 @@ const GenZir = struct { always: void, if_non_error: Zir.Inst.Ref, }, + src_node: Ast.Node.Index, ) !Zir.Inst.Index { - return gz.addAsIndex(.{ - .tag = .restore_err_ret_index, - .data = .{ .restore_err_ret_index = .{ - .block = switch (bt) { - .ret => .none, - .block => |b| b.toRef(), - }, - .operand = if (cond == .if_non_error) cond.if_non_error else .none, - } }, - }); + switch (cond) { + .always => return gz.addAsIndex(.{ + .tag = .restore_err_ret_index_unconditional, + .data = .{ .un_node = .{ + .operand = switch (bt) { + .ret => .none, + .block => |b| b.toRef(), + }, + .src_node = gz.nodeIndexToRelative(src_node), + } }, + }), + .if_non_error => |operand| switch (bt) { + .ret => return gz.addAsIndex(.{ + .tag = .restore_err_ret_index_fn_entry, + .data = .{ .un_node = .{ + .operand = operand, + .src_node = gz.nodeIndexToRelative(src_node), + } }, + }), + .block => |block| return (try gz.addExtendedPayload( + .restore_err_ret_index, + Zir.Inst.RestoreErrRetIndex{ + .src_node = gz.nodeIndexToRelative(src_node), + .block = block.toRef(), + .operand = operand, + }, + )).toIndex().?, + }, + } } fn addBreak( diff --git a/src/Autodoc.zig b/src/Autodoc.zig index e5f0993bcb..6822d3a048 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -1799,7 +1799,8 @@ fn walkInstruction( }; }, .bool_br_and, .bool_br_or => { - const bool_br = data[@intFromEnum(inst)].bool_br; + const pl_node = data[@intFromEnum(inst)].pl_node; + const extra = file.zir.extraData(Zir.Inst.BoolBr, pl_node.payload_index); const bin_index = self.exprs.items.len; try self.exprs.append(self.arena, .{ .binOp = .{ .lhs = 0, .rhs = 0 } }); @@ -1808,14 +1809,13 @@ fn walkInstruction( file, parent_scope, parent_src, - bool_br.lhs, + extra.data.lhs, false, call_ctx, ); const lhs_index = self.exprs.items.len; try self.exprs.append(self.arena, lhs.expr); - const extra = file.zir.extraData(Zir.Inst.Block, bool_br.payload_index); const rhs = try self.walkInstruction( file, parent_scope, diff --git a/src/Sema.zig b/src/Sema.zig index 874c83ae0c..e0ff94ec83 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -50,11 +50,6 @@ branch_count: u32 = 0, /// Populated when returning `error.ComptimeBreak`. Used to communicate the /// break instruction up the stack to find the corresponding Block. comptime_break_inst: Zir.Inst.Index = undefined, -/// This field is updated when a new source location becomes active, so that -/// instructions which do not have explicitly mapped source locations still have -/// access to the source location set by the previous instruction which did -/// contain a mapped source location. -src: LazySrcLoc = .{ .token_offset = 0 }, decl_val_table: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Air.Inst.Ref) = .{}, /// When doing a generic function instantiation, this array collects a value /// for each parameter of the generic owner. `none` for non-comptime parameters. @@ -1006,10 +1001,10 @@ fn analyzeBodyInner( const air_inst: Air.Inst.Ref = switch (tags[@intFromEnum(inst)]) { // zig fmt: off .alloc => try sema.zirAlloc(block, inst), - .alloc_inferred => try sema.zirAllocInferred(block, inst, true), - .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, false), - .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, true), - .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, false), + .alloc_inferred => try sema.zirAllocInferred(block, true), + .alloc_inferred_mut => try sema.zirAllocInferred(block, false), + .alloc_inferred_comptime => try sema.zirAllocInferredComptime(true), + .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(false), .alloc_mut => try sema.zirAllocMut(block, inst), .alloc_comptime_mut => try sema.zirAllocComptime(block, inst), .make_ptr_const => try sema.zirMakePtrConst(block, inst), @@ -1308,6 +1303,11 @@ fn analyzeBodyInner( i += 1; continue; }, + .restore_err_ret_index => { + try sema.zirRestoreErrRetIndex(block, extended); + i += 1; + continue; + }, .value_placeholder => unreachable, // never appears in a body }; }, @@ -1369,11 +1369,6 @@ fn analyzeBodyInner( i += 1; continue; }, - .store => { - try sema.zirStore(block, inst); - i += 1; - continue; - }, .store_node => { try sema.zirStoreNode(block, inst); i += 1; @@ -1518,8 +1513,15 @@ fn analyzeBodyInner( i += 1; continue; }, - .restore_err_ret_index => { - try sema.zirRestoreErrRetIndex(block, inst); + .restore_err_ret_index_unconditional => { + const un_node = datas[@intFromEnum(inst)].un_node; + try sema.restoreErrRetIndex(block, un_node.src(), un_node.operand, .none); + i += 1; + continue; + }, + .restore_err_ret_index_fn_entry => { + const un_node = datas[@intFromEnum(inst)].un_node; + try sema.restoreErrRetIndex(block, un_node.src(), .none, un_node.operand); i += 1; continue; }, @@ -2779,7 +2781,7 @@ fn zirStructDecl( const src: LazySrcLoc = if (small.has_src_node) blk: { const node_offset: i32 = @bitCast(sema.code.extra[extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len]); break :blk LazySrcLoc.nodeOffset(node_offset); - } else sema.src; + } else unreachable; // MLUGG TODO // Because these three things each reference each other, `undefined` // placeholders are used before being set after the struct type gains an @@ -2945,7 +2947,7 @@ fn zirEnumDecl( const node_offset: i32 = @bitCast(sema.code.extra[extra_index]); extra_index += 1; break :blk LazySrcLoc.nodeOffset(node_offset); - } else sema.src; + } else unreachable; // MLUGG TODO const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x }; const tag_type_ref = if (small.has_tag_type) blk: { @@ -3218,7 +3220,7 @@ fn zirUnionDecl( const node_offset: i32 = @bitCast(sema.code.extra[extra_index]); extra_index += 1; break :blk LazySrcLoc.nodeOffset(node_offset); - } else sema.src; + } else unreachable; // MLUGG TODO extra_index += @intFromBool(small.has_tag_type); extra_index += @intFromBool(small.has_body_len); @@ -3327,7 +3329,7 @@ fn zirOpaqueDecl( const node_offset: i32 = @bitCast(sema.code.extra[extra_index]); extra_index += 1; break :blk LazySrcLoc.nodeOffset(node_offset); - } else sema.src; + } else unreachable; // MLUGG TODO const decls_len = if (small.has_decls_len) blk: { const decls_len = sema.code.extra[extra_index]; @@ -3977,13 +3979,9 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai fn zirAllocInferredComptime( sema: *Sema, - inst: Zir.Inst.Index, is_const: bool, ) CompileError!Air.Inst.Ref { const gpa = sema.gpa; - const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; - const src = LazySrcLoc.nodeOffset(src_node); - sema.src = src; try sema.air_instructions.append(gpa, .{ .tag = .inferred_alloc_comptime, @@ -4042,16 +4040,12 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn zirAllocInferred( sema: *Sema, block: *Block, - inst: Zir.Inst.Index, is_const: bool, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); const gpa = sema.gpa; - const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; - const src = LazySrcLoc.nodeOffset(src_node); - sema.src = src; if (block.is_comptime) { try sema.air_instructions.append(gpa, .{ @@ -5428,10 +5422,11 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi const tracy = trace(@src()); defer tracy.end(); - const src: LazySrcLoc = sema.src; - const bin_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin; - const ptr = try sema.resolveInst(bin_inst.lhs); - const operand = try sema.resolveInst(bin_inst.rhs); + const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; + const src = pl_node.src(); + const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data; + const ptr = try sema.resolveInst(bin.lhs); + const operand = try sema.resolveInst(bin.rhs); const ptr_inst = ptr.toIndex().?; const air_datas = sema.air_instructions.items(.data); @@ -5496,16 +5491,6 @@ fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi sema.branch_quota = @max(sema.branch_quota, quota); } -fn zirStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { - const tracy = trace(@src()); - defer tracy.end(); - - const bin_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin; - const ptr = try sema.resolveInst(bin_inst.lhs); - const value = try sema.resolveInst(bin_inst.rhs); - return sema.storePtr(block, sema.src, ptr, value); -} - fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -5709,7 +5694,6 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node; const src = LazySrcLoc.nodeOffset(src_node); - sema.src = src; if (block.is_comptime) return sema.fail(block, src, "encountered @trap at comptime", .{}); _ = try block.addNoOp(.trap); @@ -6384,10 +6368,6 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError } fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { - // We do not set sema.src here because dbg_stmt instructions are only emitted for - // ZIR code that possibly will need to generate runtime code. So error messages - // and other source locations must not rely on sema.src being set from dbg_stmt - // instructions. if (block.is_comptime or block.ownerModule().strip) return; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; @@ -6632,7 +6612,6 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { const mod = sema.mod; const gpa = sema.gpa; - const src = sema.src; if (block.is_comptime or block.is_typeof) { const index_val = try mod.intValue_u64(Type.usize, sema.comptime_err_ret_trace.items.len); @@ -6650,9 +6629,10 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref else => |e| return e, }; const field_name = try mod.intern_pool.getOrPutString(gpa, "index"); - const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, src) catch |err| switch (err) { - error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, - else => |e| return e, + const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, .unneeded) catch |err| switch (err) { + error.AnalysisFail, error.NeededSourceLocation => @panic("std.builtin.StackTrace is corrupt"), + error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, + error.OutOfMemory => |e| return e, }; return try block.addInst(.{ @@ -9900,7 +9880,6 @@ fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src = inst_data.src(); const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data; - sema.src = src; return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false); } @@ -10855,7 +10834,7 @@ const SwitchProngAnalysis = struct { .address_space = operand_ptr_ty.ptrAddressSpace(mod), }, }); - if (try sema.resolveDefinedValue(block, sema.src, spa.operand_ptr)) |union_ptr| { + if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| { return Air.internedToRef((try mod.intern(.{ .ptr = .{ .ty = ptr_field_ty.toIntern(), .addr = .{ .field = .{ @@ -10866,7 +10845,7 @@ const SwitchProngAnalysis = struct { } return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty); } else { - if (try sema.resolveDefinedValue(block, sema.src, spa.operand)) |union_val| { + if (try sema.resolveDefinedValue(block, operand_src, spa.operand)) |union_val| { const tag_and_val = ip.indexToKey(union_val.toIntern()).un; return Air.internedToRef(tag_and_val.val); } @@ -13191,6 +13170,7 @@ fn validateErrSetSwitch( // else => |e| return e, // even if all the possible errors were already handled. const tags = sema.code.instructions.items(.tag); + const datas = sema.code.instructions.items(.data); for (else_case.body) |else_inst| switch (tags[@intFromEnum(else_inst)]) { .dbg_block_begin, .dbg_block_end, @@ -13205,11 +13185,16 @@ fn validateErrSetSwitch( .err_union_code, .ret_err_value_code, .save_err_ret_index, - .restore_err_ret_index, + .restore_err_ret_index_unconditional, + .restore_err_ret_index_fn_entry, .is_non_err, .ret_is_non_err, .condbr, => {}, + .extended => switch (datas[@intFromEnum(else_inst)].extended.opcode) { + .restore_err_ret_index => {}, + else => break, + }, else => break, } else break :else_validation; @@ -13707,7 +13692,6 @@ fn zirShl( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src = inst_data.src(); - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -13878,7 +13862,6 @@ fn zirShr( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src = inst_data.src(); - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -14014,7 +13997,6 @@ fn zirBitwise( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -14795,21 +14777,20 @@ fn zirArithmetic( defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - sema.src = .{ .node_offset_bin_op = inst_data.src_node }; + const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const lhs = try sema.resolveInst(extra.lhs); const rhs = try sema.resolveInst(extra.rhs); - return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, safety); + return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, src, lhs_src, rhs_src, safety); } fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -14975,7 +14956,6 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -15141,7 +15121,6 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -15252,7 +15231,6 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -15494,7 +15472,6 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -15679,7 +15656,6 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -15775,7 +15751,6 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -18741,14 +18716,17 @@ fn zirBoolBr( defer tracy.end(); const mod = sema.mod; - const datas = sema.code.instructions.items(.data); - const inst_data = datas[@intFromEnum(inst)].bool_br; - const lhs = try sema.resolveInst(inst_data.lhs); - const lhs_src = sema.src; - const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); - const body = sema.code.bodySlice(extra.end, extra.data.body_len); const gpa = sema.gpa; + const datas = sema.code.instructions.items(.data); + const inst_data = datas[@intFromEnum(inst)].pl_node; + const extra = sema.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index); + + const lhs = try sema.resolveInst(extra.data.lhs); + const body = sema.code.bodySlice(extra.end, extra.data.body_len); + const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; + const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; + if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { if (is_bool_or and lhs_val.toBool()) { return .bool_true; @@ -18795,7 +18773,7 @@ fn zirBoolBr( const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst); if (!sema.typeOf(rhs_result).isNoReturn(mod)) { - if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| { + if (try sema.resolveDefinedValue(rhs_block, rhs_src, rhs_result)) |rhs_val| { if (is_bool_or and rhs_val.toBool()) { return .bool_true; } else if (!is_bool_or and !rhs_val.toBool()) { @@ -19375,17 +19353,21 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE block.error_return_trace_index = try sema.analyzeSaveErrRetIndex(block); } -fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!void { - const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].restore_err_ret_index; - const src = sema.src; // TODO - - const mod = sema.mod; - const ip = &mod.intern_pool; +fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { + const extra = sema.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data; + return sema.restoreErrRetIndex(start_block, extra.src(), extra.block, extra.operand); +} +/// If `operand` is non-error (or is `none`), restores the error return trace to +/// its state at the point `block` was reached (or, if `block` is `none`, the +/// point this function began execution). +fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_block: Zir.Inst.Ref, operand_zir: Zir.Inst.Ref) CompileError!void { const tracy = trace(@src()); defer tracy.end(); - const saved_index = if (inst_data.block.toIndexAllowNone()) |zir_block| b: { + const mod = sema.mod; + + const saved_index = if (target_block.toIndexAllowNone()) |zir_block| b: { var block = start_block; while (true) { if (block.label) |label| { @@ -19409,7 +19391,7 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) return; // No need to restore }; - const operand = try sema.resolveInstAllowNone(inst_data.operand); + const operand = try sema.resolveInstAllowNone(operand_zir); if (start_block.is_comptime or start_block.is_typeof) { const is_non_error = if (operand != .none) blk: { @@ -19427,7 +19409,7 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) return; } - if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return; + if (!mod.intern_pool.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return; if (!start_block.ownerModule().error_tracing) return; assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere @@ -23161,7 +23143,6 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; - sema.src = src; const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -26416,12 +26397,16 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP try sema.prepareSimplePanic(block); const panic_messages_ty = try sema.getBuiltinType("panic_messages"); - const msg_decl_index = (try sema.namespaceLookup( + const msg_decl_index = (sema.namespaceLookup( block, - sema.src, + .unneeded, panic_messages_ty.getNamespaceIndex(mod).unwrap().?, try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id)), - )).?; + ) catch |err| switch (err) { + error.AnalysisFail, error.NeededSourceLocation => @panic("std.builtin.panic_messages is corrupt"), + error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, + error.OutOfMemory => |e| return e, + }).?; try sema.ensureDeclAnalyzed(msg_decl_index); mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional(); return msg_decl_index; diff --git a/src/Zir.zig b/src/Zir.zig index c313ab8563..c76c1f2f62 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -303,11 +303,11 @@ pub const Inst = struct { bool_not, /// Short-circuiting boolean `and`. `lhs` is a boolean `Ref` and the other operand /// is a block, which is evaluated if `lhs` is `true`. - /// Uses the `bool_br` union field. + /// Uses the `pl_node` union field. Payload is `BoolBr`. bool_br_and, /// Short-circuiting boolean `or`. `lhs` is a boolean `Ref` and the other operand /// is a block, which is evaluated if `lhs` is `false`. - /// Uses the `bool_br` union field. + /// Uses the `pl_node` union field. Payload is `BoolBr`. bool_br_or, /// Return a value from a block. /// Uses the `break` union field. @@ -592,16 +592,12 @@ pub const Inst = struct { /// Returns a pointer to the subslice. /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceLength`. slice_length, - /// Write a value to a pointer. For loading, see `load`. - /// Source location is assumed to be same as previous instruction. - /// Uses the `bin` union field. - store, /// Same as `store` except provides a source location. /// Uses the `pl_node` union field. Payload is `Bin`. store_node, - /// Same as `store` but the type of the value being stored will be used to infer - /// the pointer type. - /// Uses the `bin` union field. + /// Same as `store_node` but the type of the value being stored will be + /// used to infer the pointer type of an `alloc_inferred`. + /// Uses the `pl_node` union field. Payload is `Bin`. store_to_inferred_ptr, /// String Literal. Makes an anonymous Decl and then takes a pointer to it. /// Uses the `str` union field. @@ -1036,10 +1032,18 @@ pub const Inst = struct { /// block, if the operand is .none or of an error/error-union type. /// Uses the `save_err_ret_index` field. save_err_ret_index, - /// Sets error return trace to zero if no operand is given, - /// otherwise sets the value to the given amount. - /// Uses the `restore_err_ret_index` union field. - restore_err_ret_index, + /// Specialized form of `Extended.restore_err_ret_index`. + /// Unconditionally restores the error return index to its last saved state + /// in the block referred to by `operand`. If `operand` is `none`, restores + /// to the point of function entry. + /// Uses the `un_node` field. + restore_err_ret_index_unconditional, + /// Specialized form of `Extended.restore_err_ret_index`. + /// Restores the error return index to its state at the entry of + /// the current function conditional on `operand` being a non-error. + /// If `operand` is `none`, restores unconditionally. + /// Uses the `un_node` field. + restore_err_ret_index_fn_entry, /// The ZIR instruction tag is one of the `Extended` ones. /// Uses the `extended` union field. @@ -1145,7 +1149,6 @@ pub const Inst = struct { .shl, .shl_sat, .shr, - .store, .store_node, .store_to_inferred_ptr, .str, @@ -1265,7 +1268,6 @@ pub const Inst = struct { .@"defer", .defer_err_code, .save_err_ret_index, - .restore_err_ret_index, .for_len, .opt_eu_base_ptr_init, .coerce_ptr_elem_ty, @@ -1290,6 +1292,8 @@ pub const Inst = struct { .array_init_elem_type, .array_init_elem_ptr, .validate_ref_ty, + .restore_err_ret_index_unconditional, + .restore_err_ret_index_fn_entry, => false, .@"break", @@ -1338,7 +1342,6 @@ pub const Inst = struct { .ensure_err_union_payload_void, .set_eval_branch_quota, .atomic_store, - .store, .store_node, .store_to_inferred_ptr, .resolve_inferred_alloc, @@ -1352,8 +1355,9 @@ pub const Inst = struct { .check_comptime_control_flow, .@"defer", .defer_err_code, - .restore_err_ret_index, .save_err_ret_index, + .restore_err_ret_index_unconditional, + .restore_err_ret_index_fn_entry, .validate_struct_init_ty, .validate_struct_init_result_ty, .validate_ptr_struct_init, @@ -1635,8 +1639,8 @@ pub const Inst = struct { .declaration = .pl_node, .suspend_block = .pl_node, .bool_not = .un_node, - .bool_br_and = .bool_br, - .bool_br_or = .bool_br, + .bool_br_and = .pl_node, + .bool_br_or = .pl_node, .@"break" = .@"break", .break_inline = .@"break", .check_comptime_control_flow = .un_node, @@ -1713,9 +1717,8 @@ pub const Inst = struct { .slice_end = .pl_node, .slice_sentinel = .pl_node, .slice_length = .pl_node, - .store = .bin, .store_node = .pl_node, - .store_to_inferred_ptr = .bin, + .store_to_inferred_ptr = .pl_node, .str = .str, .negate = .un_node, .negate_wrap = .un_node, @@ -1845,7 +1848,8 @@ pub const Inst = struct { .defer_err_code = .defer_err_code, .save_err_ret_index = .save_err_ret_index, - .restore_err_ret_index = .restore_err_ret_index, + .restore_err_ret_index_unconditional = .un_node, + .restore_err_ret_index_fn_entry = .un_node, .struct_init_empty = .un_node, .struct_init_empty_result = .un_node, @@ -2075,6 +2079,13 @@ pub const Inst = struct { /// Implements the `@inComptime` builtin. /// `operand` is `src_node: i32`. in_comptime, + /// Restores the error return index to its last saved state in a given + /// block. If the block is `.none`, restores to the state from the point + /// of function entry. If the operand is not `.none`, the restore is + /// conditional on the operand value not being an error. + /// `operand` is payload index to `RestoreErrRetIndex`. + /// `small` is undefined. + restore_err_ret_index, /// Used as a placeholder instruction which is just a dummy index for Sema to replace /// with a specific value. For instance, this is used for the capture of an `errdefer`. /// This should never appear in a body. @@ -2345,11 +2356,6 @@ pub const Inst = struct { return LazySrcLoc.nodeOffset(self.src_node); } }, - bool_br: struct { - lhs: Ref, - /// Points to a `Block`. - payload_index: u32, - }, @"unreachable": struct { /// Offset from Decl AST node index. /// `Tag` determines which kind of AST node this points to. @@ -2396,10 +2402,6 @@ pub const Inst = struct { save_err_ret_index: struct { operand: Ref, // If error type (or .none), save new trace index }, - restore_err_ret_index: struct { - block: Ref, // If restored, the index is from this block's entrypoint - operand: Ref, // If non-error (or .none), then restore the index - }, elem_val_imm: struct { /// The indexable value being accessed. operand: Ref, @@ -2435,7 +2437,6 @@ pub const Inst = struct { float, ptr_type, int_type, - bool_br, @"unreachable", @"break", dbg_stmt, @@ -2444,7 +2445,6 @@ pub const Inst = struct { @"defer", defer_err_code, save_err_ret_index, - restore_err_ret_index, elem_val_imm, }; }; @@ -2630,6 +2630,13 @@ pub const Inst = struct { body_len: u32, }; + /// Trailing: + /// * inst: Index // for each `body_len` + pub const BoolBr = struct { + lhs: Ref, + body_len: u32, + }; + /// Trailing: /// 0. doc_comment: u32 // if `has_doc_comment`; null-terminated string index /// 1. align_body_len: u32 // if `has_align_linksection_addrspace`; 0 means no `align` @@ -3439,6 +3446,18 @@ pub const Inst = struct { /// The RHS of the array multiplication. rhs: Ref, }; + + pub const RestoreErrRetIndex = struct { + src_node: i32, + /// If `.none`, restore the trace to its state upon function entry. + block: Ref, + /// If `.none`, restore unconditionally. + operand: Ref, + + pub fn src(self: RestoreErrRetIndex) LazySrcLoc { + return LazySrcLoc.nodeOffset(self.src_node); + } + }; }; pub const SpecialProng = enum { none, @"else", under }; diff --git a/src/print_zir.zig b/src/print_zir.zig index f33d00c989..8e5fbc1788 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -199,10 +199,6 @@ const Writer = struct { const tag = tags[@intFromEnum(inst)]; try stream.print("= {s}(", .{@tagName(tags[@intFromEnum(inst)])}); switch (tag) { - .store, - .store_to_inferred_ptr, - => try self.writeBin(stream, inst), - .alloc, .alloc_mut, .alloc_comptime_mut, @@ -280,6 +276,8 @@ const Writer = struct { .validate_deref, .check_comptime_control_flow, .opt_eu_base_ptr_init, + .restore_err_ret_index_unconditional, + .restore_err_ret_index_fn_entry, => try self.writeUnNode(stream, inst), .ref, @@ -303,7 +301,6 @@ const Writer = struct { .int_type => try self.writeIntType(stream, inst), .save_err_ret_index => try self.writeSaveErrRetIndex(stream, inst), - .restore_err_ret_index => try self.writeRestoreErrRetIndex(stream, inst), .@"break", .break_inline, @@ -392,6 +389,7 @@ const Writer = struct { .shr_exact, .xor, .store_node, + .store_to_inferred_ptr, .error_union_type, .merge_error_sets, .bit_and, @@ -615,6 +613,8 @@ const Writer = struct { .cmpxchg => try self.writeCmpxchg(stream, extended), .ptr_cast_full => try self.writePtrCastFull(stream, extended), .ptr_cast_no_dest => try self.writePtrCastNoDest(stream, extended), + + .restore_err_ret_index => try self.writeRestoreErrRetIndex(stream, extended), } } @@ -624,14 +624,6 @@ const Writer = struct { try self.writeSrc(stream, src); } - fn writeBin(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin; - try self.writeInstRef(stream, inst_data.lhs); - try stream.writeAll(", "); - try self.writeInstRef(stream, inst_data.rhs); - try stream.writeByte(')'); - } - fn writeArrayInitElemType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bin; try self.writeInstRef(stream, inst_data.lhs); @@ -2505,12 +2497,14 @@ const Writer = struct { } fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].bool_br; - const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index); + const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; + const extra = self.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index); const body = self.code.bodySlice(extra.end, extra.data.body_len); - try self.writeInstRef(stream, inst_data.lhs); + try self.writeInstRef(stream, extra.data.lhs); try stream.writeAll(", "); try self.writeBracedBody(stream, body); + try stream.writeAll(") "); + try self.writeSrc(stream, inst_data.src()); } fn writeIntType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { @@ -2531,13 +2525,14 @@ const Writer = struct { try stream.writeAll(")"); } - fn writeRestoreErrRetIndex(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].restore_err_ret_index; + fn writeRestoreErrRetIndex(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const extra = self.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data; - try self.writeInstRef(stream, inst_data.block); - try self.writeInstRef(stream, inst_data.operand); + try self.writeInstRef(stream, extra.block); + try self.writeInstRef(stream, extra.operand); - try stream.writeAll(")"); + try stream.writeAll(") "); + try self.writeSrc(stream, extra.src()); } fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {