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 {