diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index f02dcaa2db..b356789bfd 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -4011,7 +4011,7 @@ fn fnDecl( // We insert this at the beginning so that its instruction index marks the // start of the top level declaration. - const decl_inst = try gz.makeBlockInst(.declaration, fn_proto.ast.proto_node); + const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node); astgen.advanceSourceCursorToNode(decl_node); var decl_gz: GenZir = .{ @@ -4393,7 +4393,7 @@ fn globalVarDecl( const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var; // We do this at the beginning so that the instruction index marks the range start // of the top level declaration. - const decl_inst = try gz.makeBlockInst(.declaration, node); + const decl_inst = try gz.makeDeclaration(node); const name_token = var_decl.ast.mut_token + 1; astgen.advanceSourceCursorToNode(node); @@ -4555,7 +4555,7 @@ fn comptimeDecl( // Up top so the ZIR instruction index marks the start range of this // top-level declaration. - const decl_inst = try gz.makeBlockInst(.declaration, node); + const decl_inst = try gz.makeDeclaration(node); wip_members.nextDecl(decl_inst); astgen.advanceSourceCursorToNode(node); @@ -4607,7 +4607,7 @@ fn usingnamespaceDecl( }; // Up top so the ZIR instruction index marks the start range of this // top-level declaration. - const decl_inst = try gz.makeBlockInst(.declaration, node); + const decl_inst = try gz.makeDeclaration(node); wip_members.nextDecl(decl_inst); astgen.advanceSourceCursorToNode(node); @@ -4651,7 +4651,7 @@ fn testDecl( // Up top so the ZIR instruction index marks the start range of this // top-level declaration. - const decl_inst = try gz.makeBlockInst(.declaration, node); + const decl_inst = try gz.makeDeclaration(node); wip_members.nextDecl(decl_inst); astgen.advanceSourceCursorToNode(node); @@ -13071,6 +13071,21 @@ const GenZir = struct { return new_index; } + /// Note that this returns a `Zir.Inst.Index` not a ref. + /// Does *not* append the block instruction to the scope. + /// Leaves the `payload_index` field undefined. Use `setDeclaration` to finalize. + fn makeDeclaration(gz: *GenZir, node: Ast.Node.Index) !Zir.Inst.Index { + const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); + try gz.astgen.instructions.append(gz.astgen.gpa, .{ + .tag = .declaration, + .data = .{ .declaration = .{ + .src_node = node, + .payload_index = undefined, + } }, + }); + return new_index; + } + /// Note that this returns a `Zir.Inst.Index` not a ref. /// Leaves the `payload_index` field undefined. fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index { @@ -13117,7 +13132,7 @@ const GenZir = struct { .fields_hash_1 = fields_hash_arr[1], .fields_hash_2 = fields_hash_arr[2], .fields_hash_3 = fields_hash_arr[3], - .src_node = gz.nodeIndexToRelative(args.src_node), + .src_node = args.src_node, }); if (args.captures_len != 0) { @@ -13177,7 +13192,7 @@ const GenZir = struct { .fields_hash_1 = fields_hash_arr[1], .fields_hash_2 = fields_hash_arr[2], .fields_hash_3 = fields_hash_arr[3], - .src_node = gz.nodeIndexToRelative(args.src_node), + .src_node = args.src_node, }); if (args.tag_type != .none) { @@ -13238,7 +13253,7 @@ const GenZir = struct { .fields_hash_1 = fields_hash_arr[1], .fields_hash_2 = fields_hash_arr[2], .fields_hash_3 = fields_hash_arr[3], - .src_node = gz.nodeIndexToRelative(args.src_node), + .src_node = args.src_node, }); if (args.tag_type != .none) { @@ -13285,9 +13300,7 @@ const GenZir = struct { assert(args.src_node != 0); try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).Struct.fields.len + 2); - const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ - .src_node = gz.nodeIndexToRelative(args.src_node), - }); + const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ .src_node = args.src_node }); if (args.captures_len != 0) { astgen.extra.appendAssumeCapacity(args.captures_len); @@ -13897,7 +13910,7 @@ fn setDeclaration( .has_align_linksection_addrspace = align_len != 0 or linksection_len != 0 or addrspace_len != 0, }, }; - astgen.instructions.items(.data)[@intFromEnum(decl_inst)].pl_node.payload_index = try astgen.addExtra(extra); + astgen.instructions.items(.data)[@intFromEnum(decl_inst)].declaration.payload_index = try astgen.addExtra(extra); if (extra.flags.has_doc_comment) { try astgen.extra.append(gpa, @intFromEnum(true_doc_comment)); } diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index a79e965fe9..1ab7e94842 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -287,7 +287,7 @@ pub const Inst = struct { /// namespace type, e.g. within a `struct_decl` instruction. It represents a /// single source declaration (`const`/`var`/`fn`), containing the name, /// attributes, type, and value of the declaration. - /// Uses the `pl_node` union field. Payload is `Declaration`. + /// Uses the `declaration` union field. Payload is `Declaration`. declaration, /// Implements `suspend {...}`. /// Uses the `pl_node` union field. Payload is `Block`. @@ -1596,7 +1596,7 @@ pub const Inst = struct { .block = .pl_node, .block_comptime = .pl_node, .block_inline = .pl_node, - .declaration = .pl_node, + .declaration = .declaration, .suspend_block = .pl_node, .bool_not = .un_node, .bool_br_and = .pl_node, @@ -2370,6 +2370,16 @@ pub const Inst = struct { /// The index being accessed. idx: u32, }, + declaration: struct { + /// This node provides a new absolute baseline node for all instructions within this struct. + src_node: Ast.Node.Index, + /// index into extra to a `Declaration` payload. + payload_index: u32, + + pub fn src(self: @This()) LazySrcLoc { + return .{ .node_abs = self.src_node }; + } + }, // Make sure we don't accidentally add a field to make this union // bigger than expected. Note that in Debug builds, Zig is allowed @@ -2408,6 +2418,7 @@ pub const Inst = struct { defer_err_code, save_err_ret_index, elem_val_imm, + declaration, }; }; @@ -3018,10 +3029,11 @@ pub const Inst = struct { fields_hash_1: u32, fields_hash_2: u32, fields_hash_3: u32, - src_node: i32, + /// This node provides a new absolute baseline node for all instructions within this struct. + src_node: Ast.Node.Index, pub fn src(self: StructDecl) LazySrcLoc { - return LazySrcLoc.nodeOffset(self.src_node); + return .{ .node_abs = self.src_node }; } pub const Small = packed struct { @@ -3150,10 +3162,11 @@ pub const Inst = struct { fields_hash_1: u32, fields_hash_2: u32, fields_hash_3: u32, - src_node: i32, + /// This node provides a new absolute baseline node for all instructions within this struct. + src_node: Ast.Node.Index, pub fn src(self: EnumDecl) LazySrcLoc { - return LazySrcLoc.nodeOffset(self.src_node); + return .{ .node_abs = self.src_node }; } pub const Small = packed struct { @@ -3198,10 +3211,11 @@ pub const Inst = struct { fields_hash_1: u32, fields_hash_2: u32, fields_hash_3: u32, - src_node: i32, + /// This node provides a new absolute baseline node for all instructions within this struct. + src_node: Ast.Node.Index, pub fn src(self: UnionDecl) LazySrcLoc { - return LazySrcLoc.nodeOffset(self.src_node); + return .{ .node_abs = self.src_node }; } pub const Small = packed struct { @@ -3230,10 +3244,11 @@ pub const Inst = struct { /// 2. capture: Capture, // for every captures_len /// 3. decl: Index, // for every decls_len; points to a `declaration` instruction pub const OpaqueDecl = struct { - src_node: i32, + /// This node provides a new absolute baseline node for all instructions within this struct. + src_node: Ast.Node.Index, pub fn src(self: OpaqueDecl) LazySrcLoc { - return LazySrcLoc.nodeOffset(self.src_node); + return .{ .node_abs = self.src_node }; } pub const Small = packed struct { @@ -4046,7 +4061,7 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { pub fn getDeclaration(zir: Zir, inst: Zir.Inst.Index) struct { Inst.Declaration, u32 } { assert(zir.instructions.items(.tag)[@intFromEnum(inst)] == .declaration); - const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].pl_node; + const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].declaration; const extra = zir.extraData(Inst.Declaration, pl_node.payload_index); return .{ extra.data, diff --git a/src/Module.zig b/src/Module.zig index ef410fad4e..83406c36a4 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -413,8 +413,8 @@ pub const Decl = struct { pub fn zirBodies(decl: Decl, zcu: *Zcu) Zir.Inst.Declaration.Bodies { const zir = decl.getFileScope(zcu).zir; const zir_index = decl.zir_decl_index.unwrap().?.resolve(&zcu.intern_pool); - const pl_node = zir.instructions.items(.data)[@intFromEnum(zir_index)].pl_node; - const extra = zir.extraData(Zir.Inst.Declaration, pl_node.payload_index); + const declaration = zir.instructions.items(.data)[@intFromEnum(zir_index)].declaration; + const extra = zir.extraData(Zir.Inst.Declaration, declaration.payload_index); return extra.data.getBodies(@intCast(extra.end), zir); } @@ -4255,12 +4255,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void const zir = namespace.file_scope.zir; const ip = &zcu.intern_pool; - const pl_node = zir.instructions.items(.data)[@intFromEnum(decl_inst)].pl_node; - const extra = zir.extraData(Zir.Inst.Declaration, pl_node.payload_index); + const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration; + const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index); const declaration = extra.data; const line = iter.parent_decl.src_line + declaration.line_offset; - const decl_node = iter.parent_decl.relativeToNodeIndex(pl_node.src_node); // Every Decl needs a name. const decl_name: InternPool.NullTerminatedString, const kind: Decl.Kind, const is_named_test: bool = switch (declaration.name) { @@ -4348,14 +4347,14 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void const was_exported = decl.is_exported; assert(decl.kind == kind); // ZIR tracking should preserve this decl.name = decl_name; - decl.src_node = decl_node; + decl.src_node = inst_data.src_node; decl.src_line = line; decl.is_pub = declaration.flags.is_pub; decl.is_exported = declaration.flags.is_export; break :decl_index .{ was_exported, decl_index }; } else decl_index: { // Create and set up a new Decl. - const new_decl_index = try zcu.allocateNewDecl(namespace_index, decl_node); + const new_decl_index = try zcu.allocateNewDecl(namespace_index, inst_data.src_node); const new_decl = zcu.declPtr(new_decl_index); new_decl.kind = kind; new_decl.name = decl_name; diff --git a/src/Sema.zig b/src/Sema.zig index 2fcf1261a2..257f27d11a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2835,7 +2835,7 @@ fn zirStructDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + extra.data.src_node, Value.fromInterned(wip_ty.index), small.name_strategy, "struct", @@ -2872,7 +2872,7 @@ fn zirStructDecl( fn createAnonymousDeclTypeNamed( sema: *Sema, block: *Block, - src: LazySrcLoc, + src_node: std.zig.Ast.Node.Index, val: Value, name_strategy: Zir.Inst.NameStrategy, anon_prefix: []const u8, @@ -2883,31 +2883,17 @@ fn createAnonymousDeclTypeNamed( const gpa = sema.gpa; const namespace = block.namespace; const src_decl = zcu.declPtr(block.src_decl); - const src_node = src_decl.relativeToNodeIndex(src.node_offset.x); const new_decl_index = try zcu.allocateNewDecl(namespace, src_node); errdefer zcu.destroyDecl(new_decl_index); switch (name_strategy) { - .anon => { - // It would be neat to have "struct:line:column" but this name has - // to survive incremental updates, where it may have been shifted down - // or up to a different line, but unchanged, and thus not unnecessarily - // semantically analyzed. - // This name is also used as the key in the parent namespace so it cannot be - // renamed. - - const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ - src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), - }, .no_embedded_nulls) catch unreachable; - try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); - return new_decl_index; - }, + .anon => {}, // handled after switch .parent => { const name = zcu.declPtr(block.src_decl).name; try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); return new_decl_index; }, - .func => { + .func => func_strat: { const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); const zir_tags = sema.code.instructions.items(.tag); @@ -2927,7 +2913,7 @@ fn createAnonymousDeclTypeNamed( // function and the name doesn't matter since it will later // result in a compile error. const arg_val = sema.resolveConstValue(block, .unneeded, arg, undefined) catch - return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); + break :func_strat; // fall through to anon strat if (arg_i != 0) try writer.writeByte(','); @@ -2969,9 +2955,24 @@ fn createAnonymousDeclTypeNamed( }, else => {}, }; - return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); + // fall through to anon strat }, } + + // anon strat handling. + + // It would be neat to have "struct:line:column" but this name has + // to survive incremental updates, where it may have been shifted down + // or up to a different line, but unchanged, and thus not unnecessarily + // semantically analyzed. + // This name is also used as the key in the parent namespace so it cannot be + // renamed. + + const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ + src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), + }, .no_embedded_nulls) catch unreachable; + try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); + return new_decl_index; } fn zirEnumDecl( @@ -2991,7 +2992,6 @@ fn zirEnumDecl( var extra_index: usize = extra.end; const src = extra.data.src(); - const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x }; const tag_type_ref = if (small.has_tag_type) blk: { const tag_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); @@ -3071,7 +3071,7 @@ fn zirEnumDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + extra.data.src_node, Value.fromInterned(wip_ty.index), small.name_strategy, "enum", @@ -3140,14 +3140,17 @@ fn zirEnumDecl( }; defer enum_block.instructions.deinit(sema.gpa); + // This source location applies in the context of `enum_block`. + const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = 0 }; + if (body.len != 0) { _ = try sema.analyzeInlineBody(&enum_block, body, inst); } if (tag_type_ref != .none) { - const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); + const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref); if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) { - return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); + return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); } break :ty ty; } else if (fields_len == 0) { @@ -3342,7 +3345,7 @@ fn zirUnionDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + extra.data.src_node, Value.fromInterned(wip_ty.index), small.name_strategy, "union", @@ -3430,7 +3433,7 @@ fn zirOpaqueDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + extra.data.src_node, Value.fromInterned(wip_ty.index), small.name_strategy, "opaque", @@ -21658,7 +21661,7 @@ fn zirReify( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x), Value.fromInterned(wip_ty.index), name_strategy, "opaque", @@ -21858,7 +21861,7 @@ fn reifyEnum( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x), Value.fromInterned(wip_ty.index), name_strategy, "enum", @@ -22005,7 +22008,7 @@ fn reifyUnion( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x), Value.fromInterned(wip_ty.index), name_strategy, "union", @@ -22264,7 +22267,7 @@ fn reifyStruct( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, + mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x), Value.fromInterned(wip_ty.index), name_strategy, "struct", diff --git a/src/print_zir.zig b/src/print_zir.zig index 4a262c4ada..d5772949eb 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -1390,9 +1390,14 @@ const Writer = struct { } fn writeStructDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { - const small = @as(Zir.Inst.StructDecl.Small, @bitCast(extended.small)); + const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand); + + const prev_parent_decl_node = self.parent_decl_node; + self.parent_decl_node = extra.data.src_node; + defer self.parent_decl_node = prev_parent_decl_node; + const fields_hash: std.zig.SrcHash = @bitCast([4]u32{ extra.data.fields_hash_0, extra.data.fields_hash_1, @@ -1465,10 +1470,6 @@ const Writer = struct { if (decls_len == 0) { try stream.writeAll("{}, "); } else { - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); - defer self.parent_decl_node = prev_parent_decl_node; - try stream.writeAll("{\n"); self.indent += 2; try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len)); @@ -1546,8 +1547,6 @@ const Writer = struct { } } - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); try stream.writeAll("{\n"); self.indent += 2; @@ -1595,18 +1594,22 @@ const Writer = struct { try stream.writeAll(",\n"); } - self.parent_decl_node = prev_parent_decl_node; self.indent -= 2; try stream.writeByteNTimes(' ', self.indent); try stream.writeAll("})"); } - try self.writeSrcNode(stream, extra.data.src_node); + try self.writeSrcNode(stream, 0); } fn writeUnionDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small)); const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand); + + const prev_parent_decl_node = self.parent_decl_node; + self.parent_decl_node = extra.data.src_node; + defer self.parent_decl_node = prev_parent_decl_node; + const fields_hash: std.zig.SrcHash = @bitCast([4]u32{ extra.data.fields_hash_0, extra.data.fields_hash_1, @@ -1670,10 +1673,6 @@ const Writer = struct { if (decls_len == 0) { try stream.writeAll("{}"); } else { - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); - defer self.parent_decl_node = prev_parent_decl_node; - try stream.writeAll("{\n"); self.indent += 2; try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len)); @@ -1690,7 +1689,7 @@ const Writer = struct { if (fields_len == 0) { try stream.writeAll("})"); - try self.writeSrcNode(stream, extra.data.src_node); + try self.writeSrcNode(stream, 0); return; } try stream.writeAll(", "); @@ -1698,8 +1697,6 @@ const Writer = struct { const body = self.code.bodySlice(extra_index, body_len); extra_index += body.len; - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); try self.writeBracedDecl(stream, body); try stream.writeAll(", {\n"); @@ -1763,17 +1760,21 @@ const Writer = struct { try stream.writeAll(",\n"); } - self.parent_decl_node = prev_parent_decl_node; self.indent -= 2; try stream.writeByteNTimes(' ', self.indent); try stream.writeAll("})"); - try self.writeSrcNode(stream, extra.data.src_node); + try self.writeSrcNode(stream, 0); } fn writeEnumDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small)); const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand); + + const prev_parent_decl_node = self.parent_decl_node; + self.parent_decl_node = extra.data.src_node; + defer self.parent_decl_node = prev_parent_decl_node; + const fields_hash: std.zig.SrcHash = @bitCast([4]u32{ extra.data.fields_hash_0, extra.data.fields_hash_1, @@ -1835,10 +1836,6 @@ const Writer = struct { if (decls_len == 0) { try stream.writeAll("{}, "); } else { - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); - defer self.parent_decl_node = prev_parent_decl_node; - try stream.writeAll("{\n"); self.indent += 2; try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len)); @@ -1856,12 +1853,9 @@ const Writer = struct { const body = self.code.bodySlice(extra_index, body_len); extra_index += body.len; - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); try self.writeBracedDecl(stream, body); if (fields_len == 0) { try stream.writeAll(", {})"); - self.parent_decl_node = prev_parent_decl_node; } else { try stream.writeAll(", {\n"); @@ -1900,12 +1894,11 @@ const Writer = struct { } try stream.writeAll(",\n"); } - self.parent_decl_node = prev_parent_decl_node; self.indent -= 2; try stream.writeByteNTimes(' ', self.indent); try stream.writeAll("})"); } - try self.writeSrcNode(stream, extra.data.src_node); + try self.writeSrcNode(stream, 0); } fn writeOpaqueDecl( @@ -1915,6 +1908,11 @@ const Writer = struct { ) !void { const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small)); const extra = self.code.extraData(Zir.Inst.OpaqueDecl, extended.operand); + + const prev_parent_decl_node = self.parent_decl_node; + self.parent_decl_node = extra.data.src_node; + defer self.parent_decl_node = prev_parent_decl_node; + var extra_index: usize = extra.end; const captures_len = if (small.has_captures_len) blk: { @@ -1948,10 +1946,6 @@ const Writer = struct { if (decls_len == 0) { try stream.writeAll("{})"); } else { - const prev_parent_decl_node = self.parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(extra.data.src_node); - defer self.parent_decl_node = prev_parent_decl_node; - try stream.writeAll("{\n"); self.indent += 2; try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len)); @@ -1959,7 +1953,7 @@ const Writer = struct { try stream.writeByteNTimes(' ', self.indent); try stream.writeAll("})"); } - try self.writeSrcNode(stream, extra.data.src_node); + try self.writeSrcNode(stream, 0); } fn writeErrorSetDecl( @@ -2729,11 +2723,16 @@ const Writer = struct { } fn writeDeclaration(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; + const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].declaration; const extra = self.code.extraData(Zir.Inst.Declaration, inst_data.payload_index); const doc_comment: ?Zir.NullTerminatedString = if (extra.data.flags.has_doc_comment) dc: { break :dc @enumFromInt(self.code.extra[extra.end]); } else null; + + const prev_parent_decl_node = self.parent_decl_node; + defer self.parent_decl_node = prev_parent_decl_node; + self.parent_decl_node = inst_data.src_node; + if (extra.data.flags.is_pub) try stream.writeAll("pub "); if (extra.data.flags.is_export) try stream.writeAll("export "); switch (extra.data.name) { @@ -2757,10 +2756,6 @@ const Writer = struct { try stream.print(" line(+{d}) hash({})", .{ extra.data.line_offset, std.fmt.fmtSliceHexLower(&src_hash_bytes) }); { - const prev_parent_decl_node = self.parent_decl_node; - defer self.parent_decl_node = prev_parent_decl_node; - self.parent_decl_node = self.relativeToNodeIndex(inst_data.src_node); - const bodies = extra.data.getBodies(@intCast(extra.end), self.code); try stream.writeAll(" value="); @@ -2783,7 +2778,7 @@ const Writer = struct { } try stream.writeAll(") "); - try self.writeSrc(stream, inst_data.src()); + try self.writeSrcNode(stream, 0); } fn writeClosureGet(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {