authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-09-27 14:57:00+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-09-29 16:07:45+01:00
logac77c23aff39272f99369c247ded29d960122ecd
treeec52fd7567e4f368755fbac101ae7699ddec38e3
parentdd144a19881d94b2060e3596057199c71137cad3
signature Commit is signed but in an unrecognized format.

Zir: prevent AST node offsets of field and backing type expressions changing

We represent AST nodes in ZIR as relative to a "baseline" node so that source locations within unchanged declarations/types do not get invalidated by incremental updates. However, we were missing a bit of granualarity in container types: because container types have declarations, but type resolution is only re-run if the fields change, there is no single baseline node in a type declaration relative to which the fields' AST nodes do not change. Instead, we need to track a few different baseline nodes, and put the right one in the `LazySrcLoc`.

10 files changed, 511 insertions(+), 250 deletions(-)

lib/std/zig/AstGen.zig+80-22
......@@ -176,7 +176,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
176176 var gen_scope: GenZir = .{
177177 .is_comptime = true,
178178 .parent = &top_scope.base,
179 .decl_node_index = .root,
179 .src_baseline = .root,
180180 .decl_line = 0,
181181 .astgen = &astgen,
182182 .instructions = &gz_instructions,
......@@ -4048,7 +4048,7 @@ fn fnDecl(
40484048
40494049 var type_gz: GenZir = .{
40504050 .is_comptime = true,
4051 .decl_node_index = fn_proto.ast.proto_node,
4051 .src_baseline = fn_proto.ast.proto_node,
40524052 .decl_line = astgen.source_line,
40534053 .parent = scope,
40544054 .astgen = astgen,
......@@ -4314,7 +4314,7 @@ fn fnDeclInner(
43144314
43154315 var body_gz: GenZir = .{
43164316 .is_comptime = false,
4317 .decl_node_index = fn_proto.ast.proto_node,
4317 .src_baseline = fn_proto.ast.proto_node,
43184318 .decl_line = decl_gz.decl_line,
43194319 .parent = params_scope,
43204320 .astgen = astgen,
......@@ -4468,7 +4468,7 @@ fn globalVarDecl(
44684468
44694469 var type_gz: GenZir = .{
44704470 .parent = scope,
4471 .decl_node_index = node,
4471 .src_baseline = node,
44724472 .decl_line = astgen.source_line,
44734473 .astgen = astgen,
44744474 .is_comptime = true,
......@@ -4570,7 +4570,7 @@ fn comptimeDecl(
45704570
45714571 var comptime_gz: GenZir = .{
45724572 .is_comptime = true,
4573 .decl_node_index = node,
4573 .src_baseline = node,
45744574 .decl_line = astgen.source_line,
45754575 .parent = scope,
45764576 .astgen = astgen,
......@@ -4634,7 +4634,7 @@ fn testDecl(
46344634
46354635 var decl_block: GenZir = .{
46364636 .is_comptime = true,
4637 .decl_node_index = node,
4637 .src_baseline = node,
46384638 .decl_line = astgen.source_line,
46394639 .parent = scope,
46404640 .astgen = astgen,
......@@ -4732,7 +4732,7 @@ fn testDecl(
47324732
47334733 var fn_block: GenZir = .{
47344734 .is_comptime = false,
4735 .decl_node_index = node,
4735 .src_baseline = node,
47364736 .decl_line = decl_block.decl_line,
47374737 .parent = &decl_block.base,
47384738 .astgen = astgen,
......@@ -4857,6 +4857,8 @@ fn structDeclInner(
48574857 .src_column = src_column,
48584858 .src_node = node,
48594859 .name_strat = name_strat,
4860 .arg_baseline_src_node = .none,
4861 .fields_baseline_src_node = .none,
48604862 .layout = layout,
48614863 .backing_int_type_body_len = null,
48624864 .decls_len = 0,
......@@ -4886,7 +4888,7 @@ fn structDeclInner(
48864888 // can refer to decls within the struct itself.
48874889 var block_scope: GenZir = .{
48884890 .parent = &namespace.base,
4889 .decl_node_index = node,
4891 .src_baseline = node,
48904892 .decl_line = gz.decl_line,
48914893 .astgen = astgen,
48924894 .is_comptime = true,
......@@ -4933,6 +4935,7 @@ fn structDeclInner(
49334935 break :len body_len;
49344936 } else null;
49354937
4938 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
49364939 var next_field_idx: u32 = 0;
49374940 for (container_decl.ast.members) |member_node| {
49384941 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
......@@ -4942,6 +4945,13 @@ fn structDeclInner(
49424945 const field_idx = next_field_idx;
49434946 next_field_idx += 1;
49444947
4948 if (field_idx == 0) {
4949 assert(fields_src_baseline == .none);
4950 fields_src_baseline = member_node.toOptional();
4951 }
4952 block_scope.src_baseline = fields_src_baseline.unwrap().?;
4953 defer block_scope.src_baseline = node;
4954
49454955 astgen.src_hasher.update(tree.getNodeSource(member_node));
49464956
49474957 member.convertToNonTupleLike(astgen.tree);
......@@ -5013,6 +5023,8 @@ fn structDeclInner(
50135023 .src_column = src_column,
50145024 .src_node = node,
50155025 .name_strat = name_strat,
5026 .arg_baseline_src_node = maybe_backing_int_node,
5027 .fields_baseline_src_node = fields_src_baseline,
50165028 .layout = layout,
50175029 .backing_int_type_body_len = backing_int_type_body_len,
50185030 .decls_len = scan_result.decls_len,
......@@ -5176,7 +5188,7 @@ fn unionDeclInner(
51765188 // can refer to decls within the union itself.
51775189 var block_scope: GenZir = .{
51785190 .parent = &namespace.base,
5179 .decl_node_index = node,
5191 .src_baseline = node,
51805192 .decl_line = gz.decl_line,
51815193 .astgen = astgen,
51825194 .is_comptime = true,
......@@ -5213,6 +5225,7 @@ fn unionDeclInner(
52135225 break :len body_len;
52145226 } else null;
52155227
5228 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
52165229 var next_field_idx: u32 = 0;
52175230 for (members) |member_node| {
52185231 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
......@@ -5222,6 +5235,13 @@ fn unionDeclInner(
52225235 const field_idx = next_field_idx;
52235236 next_field_idx += 1;
52245237
5238 if (field_idx == 0) {
5239 assert(fields_src_baseline == .none);
5240 fields_src_baseline = member_node.toOptional();
5241 }
5242 block_scope.src_baseline = fields_src_baseline.unwrap().?;
5243 defer block_scope.src_baseline = node;
5244
52255245 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));
52265246 member.convertToNonTupleLike(astgen.tree);
52275247 if (member.ast.tuple_like) {
......@@ -5298,6 +5318,8 @@ fn unionDeclInner(
52985318 .src_column = src_column,
52995319 .src_node = node,
53005320 .name_strat = name_strat,
5321 .arg_baseline_src_node = opt_arg_node,
5322 .fields_baseline_src_node = fields_src_baseline,
53015323 .kind = switch (layout) {
53025324 .auto => if (auto_enum_tok == null) l: {
53035325 break :l if (opt_arg_node == .none) .auto else .tagged_explicit;
......@@ -5386,7 +5408,7 @@ fn containerDecl(
53865408 // are in scope, so that tag values can refer to decls within the enum itself.
53875409 var block_scope: GenZir = .{
53885410 .parent = &namespace.base,
5389 .decl_node_index = node,
5411 .src_baseline = node,
53905412 .decl_line = gz.decl_line,
53915413 .astgen = astgen,
53925414 .is_comptime = true,
......@@ -5424,6 +5446,7 @@ fn containerDecl(
54245446 } else null;
54255447
54265448 var next_field_idx: u32 = 0;
5449 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
54275450 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;
54285451 for (container_decl.ast.members) |member_node| {
54295452 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
......@@ -5466,6 +5489,13 @@ fn containerDecl(
54665489 const field_idx = next_field_idx;
54675490 next_field_idx += 1;
54685491
5492 if (field_idx == 0) {
5493 assert(fields_src_baseline == .none);
5494 fields_src_baseline = member_node.toOptional();
5495 }
5496 block_scope.src_baseline = fields_src_baseline.unwrap().?;
5497 defer block_scope.src_baseline = node;
5498
54695499 astgen.src_hasher.update(tree.getNodeSource(member_node));
54705500
54715501 field_names.get(astgen)[field_idx] = @backingInt(try astgen.identAsString(member.ast.main_token));
......@@ -5500,6 +5530,8 @@ fn containerDecl(
55005530 .src_column = src_column,
55015531 .src_node = node,
55025532 .name_strat = name_strat,
5533 .arg_baseline_src_node = container_decl.ast.arg,
5534 .fields_baseline_src_node = fields_src_baseline,
55035535 .tag_type_body_len = tag_type_body_len,
55045536 .nonexhaustive = scan_result.has_underscore_field,
55055537 .decls_len = scan_result.decls_len,
......@@ -5534,7 +5566,7 @@ fn containerDecl(
55345566
55355567 var block_scope: GenZir = .{
55365568 .parent = &namespace.base,
5537 .decl_node_index = node,
5569 .src_baseline = node,
55385570 .decl_line = gz.decl_line,
55395571 .astgen = astgen,
55405572 .is_comptime = true,
......@@ -11252,7 +11284,7 @@ const GenZir = struct {
1125211284 /// exits from this block should use `break_inline` rather than `break`.
1125311285 is_inline: bool = false,
1125411286 /// The containing decl AST node.
11255 decl_node_index: Ast.Node.Index,
11287 src_baseline: Ast.Node.Index,
1125611288 /// The containing decl line index, absolute.
1125711289 decl_line: u32,
1125811290 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`.
......@@ -11338,7 +11370,7 @@ const GenZir = struct {
1133811370 return .{
1133911371 .is_comptime = gz.is_comptime,
1134011372 .is_typeof = gz.is_typeof,
11341 .decl_node_index = gz.decl_node_index,
11373 .src_baseline = gz.src_baseline,
1134211374 .decl_line = gz.decl_line,
1134311375 .parent = scope,
1134411376 .astgen = gz.astgen,
......@@ -11374,15 +11406,11 @@ const GenZir = struct {
1137411406 }
1137511407
1137611408 fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) Ast.Node.Offset {
11377 return gz.decl_node_index.toOffset(node_index);
11409 return gz.src_baseline.toOffset(node_index);
1137811410 }
1137911411
1138011412 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) Ast.TokenOffset {
11381 return .init(gz.srcToken(), token);
11382 }
11383
11384 fn srcToken(gz: GenZir) Ast.TokenIndex {
11385 return gz.astgen.tree.firstToken(gz.decl_node_index);
11413 return .init(gz.astgen.tree.firstToken(gz.src_baseline), token);
1138611414 }
1138711415
1138811416 fn setBreakResultInfo(gz: *GenZir, parent_ri: AstGen.ResultInfo) void {
......@@ -12420,6 +12448,8 @@ const GenZir = struct {
1242012448 src_column: u32,
1242112449 src_node: Ast.Node.Index,
1242212450 name_strat: Zir.Inst.NameStrategy,
12451 arg_baseline_src_node: Ast.Node.OptionalIndex,
12452 fields_baseline_src_node: Ast.Node.OptionalIndex,
1242312453 layout: std.lang.Type.ContainerLayout,
1242412454 backing_int_type_body_len: ?u32,
1242512455 decls_len: u32,
......@@ -12445,7 +12475,9 @@ const GenZir = struct {
1244512475 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1244612476
1244712477 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".field_names.len +
12448 4 + // `captures_len`, `decls_len`, `fields_len`, `backing_int_type_body_len`
12478 3 + // `captures_len`, `decls_len`, `fields_len`
12479 2 + // `arg_baseline_src_node`, `fields_baseline_src_node`
12480 1 + // `backing_int_type_body_len`
1244912481 captures_len * 2 + // `capture`, `capture_name`
1245012482 args.remaining.len);
1245112483
......@@ -12462,6 +12494,12 @@ const GenZir = struct {
1246212494 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
1246312495 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
1246412496 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12497 if (args.backing_int_type_body_len != null) astgen.extra.appendAssumeCapacity(
12498 @backingInt(args.arg_baseline_src_node.unwrap().?),
12499 );
12500 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(
12501 @backingInt(args.fields_baseline_src_node.unwrap().?),
12502 );
1246512503 if (args.backing_int_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
1246612504 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
1246712505 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
......@@ -12492,6 +12530,8 @@ const GenZir = struct {
1249212530 src_column: u32,
1249312531 src_node: Ast.Node.Index,
1249412532 name_strat: Zir.Inst.NameStrategy,
12533 arg_baseline_src_node: Ast.Node.OptionalIndex,
12534 fields_baseline_src_node: Ast.Node.OptionalIndex,
1249512535 kind: Zir.Inst.UnionDecl.Kind,
1249612536 arg_type_body_len: ?u32,
1249712537 decls_len: u32,
......@@ -12515,7 +12555,9 @@ const GenZir = struct {
1251512555 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1251612556
1251712557 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".field_names.len +
12518 4 + // `captures_len`, `decls_len`, `fields_len`, `arg_type_body_len`
12558 3 + // `captures_len`, `decls_len`, `fields_len`
12559 2 + // `arg_baseline_src_node`, `fields_baseline_src_node`
12560 1 + // `arg_type_body_len`
1251912561 captures_len * 2 + // `capture`, `capture_name`
1252012562 args.remaining.len);
1252112563
......@@ -12532,6 +12574,12 @@ const GenZir = struct {
1253212574 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
1253312575 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
1253412576 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12577 if (args.kind.hasArgType()) astgen.extra.appendAssumeCapacity(
12578 @backingInt(args.arg_baseline_src_node.unwrap().?),
12579 );
12580 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(
12581 @backingInt(args.fields_baseline_src_node.unwrap().?),
12582 );
1253512583 if (args.kind.hasArgType()) {
1253612584 astgen.extra.appendAssumeCapacity(args.arg_type_body_len.?);
1253712585 } else {
......@@ -12564,6 +12612,8 @@ const GenZir = struct {
1256412612 src_column: u32,
1256512613 src_node: Ast.Node.Index,
1256612614 name_strat: Zir.Inst.NameStrategy,
12615 arg_baseline_src_node: Ast.Node.OptionalIndex,
12616 fields_baseline_src_node: Ast.Node.OptionalIndex,
1256712617 tag_type_body_len: ?u32,
1256812618 nonexhaustive: bool,
1256912619 decls_len: u32,
......@@ -12586,7 +12636,9 @@ const GenZir = struct {
1258612636 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1258712637
1258812638 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".field_names.len +
12589 4 + // `captures_len`, `decls_len`, `fields_len`, `tag_type_body_len`
12639 3 + // `captures_len`, `decls_len`, `fields_len`
12640 2 + // `arg_baseline_src_node`, `fields_baseline_src_node`
12641 1 + // `tag_type_body_len`
1259012642 captures_len * 2 + // `capture`, `capture_name`
1259112643 args.remaining.len);
1259212644
......@@ -12603,6 +12655,12 @@ const GenZir = struct {
1260312655 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
1260412656 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
1260512657 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12658 if (args.tag_type_body_len != null) astgen.extra.appendAssumeCapacity(
12659 @backingInt(args.arg_baseline_src_node.unwrap().?),
12660 );
12661 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(
12662 @backingInt(args.fields_baseline_src_node.unwrap().?),
12663 );
1260612664 if (args.tag_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
1260712665 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
1260812666 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
lib/std/zig/Zir.zig+54-13
......@@ -3493,18 +3493,20 @@ pub const Inst = struct {
34933493 /// 0. captures_len: u32 // if `has_captures_len`
34943494 /// 1. decls_len: u32, // if `has_decls_len`
34953495 /// 2. fields_len: u32, // if `has_fields_len`
3496 /// 3. backing_int_body_len: u32 // if `has_backing_int`
3497 /// 4. capture: Capture // for every `captures_len`
3498 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3499 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3500 /// 7. field_name: NullTerminatedString // for every `fields_len`
3501 /// 8. field_type_body_len: u32 // for every `fields_len`
3502 /// 9. field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3503 /// 10. field_default_body_len: u32 // for every `fields_len` if `any_field_defaults`
3504 /// 11. field_comptime_bits: u32 // one bit per `fields_len` if `any_comptime_fields`
3496 /// 3. arg_baseline_src_node: Ast.Node.Index // if `has_backing_int`
3497 /// 4. fields_baseline_src_node: Ast.Node.Index // if `has_fields_len`
3498 /// 5. backing_int_body_len: u32 // if `has_backing_int`
3499 /// 6. capture: Capture // for every `captures_len`
3500 /// 7. capture_name: NullTerminatedString // for every `captures_len`
3501 /// 8. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3502 /// 9. field_name: NullTerminatedString // for every `fields_len`
3503 /// 10. field_type_body_len: u32 // for every `fields_len`
3504 /// 11. field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3505 /// 12. field_default_body_len: u32 // for every `fields_len` if `any_field_defaults`
3506 /// 13. field_comptime_bits: u32 // one bit per `fields_len` if `any_comptime_fields`
35053507 /// // LSB is first field, minimum number of `u32` needed
3506 /// 12. backing_int_body_inst: Inst.Index // for each `backing_int_body_len`
3507 /// 13. body_inst: Inst.Index // type body, then align body, then default body, for each field
3508 /// 14. backing_int_body_inst: Inst.Index // for each `backing_int_body_len`
3509 /// 15. body_inst: Inst.Index // type body, then align body, then default body, for each field
35083510 pub const StructDecl = struct {
35093511 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
35103512 // This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).
......@@ -5227,12 +5229,12 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
52275229 .struct_init_anon,
52285230 => {}, // tracked in order, as the owner instructions of anonymous struct types
52295231 .func, .func_inferred => {
5230 // These are tracked provided they are actual function declarations, not just bodies.
5232 // These are tracked if they are actual function declarations rather than prototypes.
52315233 const extra = zir.extraData(Inst.Func, inst.data.pl_node.payload_index);
52325234 assert(extra.data.body_len != 0);
52335235 },
52345236 .func_fancy => {
5235 // These are tracked provided they are actual function declarations, not just bodies.
5237 // These are tracked if they are actual function declarations rather than prototypes.
52365238 const extra = zir.extraData(Inst.FuncFancy, inst.data.pl_node.payload_index);
52375239 assert(extra.data.body_len != 0);
52385240 },
......@@ -5287,6 +5289,14 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe
52875289 extra_index += 1;
52885290 break :blk fields_len;
52895291 } else 0;
5292 const arg_baseline_src_node: Ast.Node.Index = if (small.has_backing_int_type) node: {
5293 defer extra_index += 1;
5294 break :node @fromBackingInt(zir.extra[extra_index]);
5295 } else extra.data.src_node;
5296 const fields_baseline_src_node: Ast.Node.Index = if (small.has_fields_len) node: {
5297 defer extra_index += 1;
5298 break :node @fromBackingInt(zir.extra[extra_index]);
5299 } else extra.data.src_node;
52905300 const backing_int_type_body_len: u32 = if (small.has_backing_int_type) len: {
52915301 const body_len = zir.extra[extra_index];
52925302 extra_index += 1;
......@@ -5329,6 +5339,8 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe
53295339 .src_column = extra.data.src_column,
53305340 .src_node = extra.data.src_node,
53315341 .name_strategy = small.name_strategy,
5342 .arg_baseline_src_node = arg_baseline_src_node,
5343 .fields_baseline_src_node = fields_baseline_src_node,
53325344 .captures = captures,
53335345 .capture_names = capture_names,
53345346 .decls = decls,
......@@ -5348,6 +5360,9 @@ pub const UnwrappedStructDecl = struct {
53485360 src_node: Ast.Node.Index,
53495361 name_strategy: Inst.NameStrategy,
53505362
5363 arg_baseline_src_node: Ast.Node.Index,
5364 fields_baseline_src_node: Ast.Node.Index,
5365
53515366 captures: []const Inst.Capture,
53525367 capture_names: []const NullTerminatedString,
53535368
......@@ -5440,6 +5455,14 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl
54405455 extra_index += 1;
54415456 break :blk fields_len;
54425457 } else 0;
5458 const arg_baseline_src_node: Ast.Node.Index = if (small.kind.hasArgType()) node: {
5459 defer extra_index += 1;
5460 break :node @fromBackingInt(zir.extra[extra_index]);
5461 } else extra.data.src_node;
5462 const fields_baseline_src_node: Ast.Node.Index = if (small.has_fields_len) node: {
5463 defer extra_index += 1;
5464 break :node @fromBackingInt(zir.extra[extra_index]);
5465 } else extra.data.src_node;
54435466 const arg_type_body_len: u32 = if (small.kind.hasArgType()) len: {
54445467 const body_len = zir.extra[extra_index];
54455468 extra_index += 1;
......@@ -5476,6 +5499,8 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl
54765499 .src_column = extra.data.src_column,
54775500 .src_node = extra.data.src_node,
54785501 .name_strategy = small.name_strategy,
5502 .arg_baseline_src_node = arg_baseline_src_node,
5503 .fields_baseline_src_node = fields_baseline_src_node,
54795504 .captures = captures,
54805505 .capture_names = capture_names,
54815506 .decls = decls,
......@@ -5494,6 +5519,9 @@ pub const UnwrappedUnionDecl = struct {
54945519 src_node: Ast.Node.Index,
54955520 name_strategy: Inst.NameStrategy,
54965521
5522 arg_baseline_src_node: Ast.Node.Index,
5523 fields_baseline_src_node: Ast.Node.Index,
5524
54975525 captures: []const Inst.Capture,
54985526 capture_names: []const NullTerminatedString,
54995527
......@@ -5576,6 +5604,14 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {
55765604 extra_index += 1;
55775605 break :blk fields_len;
55785606 } else 0;
5607 const arg_baseline_src_node: Ast.Node.Index = if (small.has_tag_type) node: {
5608 defer extra_index += 1;
5609 break :node @fromBackingInt(zir.extra[extra_index]);
5610 } else extra.data.src_node;
5611 const fields_baseline_src_node: Ast.Node.Index = if (small.has_fields_len) node: {
5612 defer extra_index += 1;
5613 break :node @fromBackingInt(zir.extra[extra_index]);
5614 } else extra.data.src_node;
55795615 const tag_type_body_len: u32 = if (small.has_tag_type) len: {
55805616 const body_len = zir.extra[extra_index];
55815617 extra_index += 1;
......@@ -5605,6 +5641,8 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {
56055641 .src_column = extra.data.src_column,
56065642 .src_node = extra.data.src_node,
56075643 .name_strategy = small.name_strategy,
5644 .arg_baseline_src_node = arg_baseline_src_node,
5645 .fields_baseline_src_node = fields_baseline_src_node,
56085646 .captures = captures,
56095647 .capture_names = capture_names,
56105648 .decls = decls,
......@@ -5621,6 +5659,9 @@ pub const UnwrappedEnumDecl = struct {
56215659 src_node: Ast.Node.Index,
56225660 name_strategy: Inst.NameStrategy,
56235661
5662 arg_baseline_src_node: Ast.Node.Index,
5663 fields_baseline_src_node: Ast.Node.Index,
5664
56245665 captures: []const Inst.Capture,
56255666 capture_names: []const NullTerminatedString,
56265667
src/Sema.zig+83-75
......@@ -395,8 +395,8 @@ pub const Block = struct {
395395 need_debug_scope: ?*bool = null,
396396
397397 /// Relative source locations encountered while traversing this block should be
398 /// treated as relative to the AST node of this ZIR instruction.
399 src_base_inst: InternPool.TrackedInst.Index,
398 /// treated as relative to this baseline AST node.
399 src_baseline: Zcu.LazySrcLoc.Baseline,
400400
401401 /// The name of the current "context" for naming namespace types.
402402 /// The interpretation of this depends on the name strategy in ZIR, but the name
......@@ -406,10 +406,10 @@ pub const Block = struct {
406406 type_fqn_ctx: InternPool.NullTerminatedString,
407407
408408 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
409 /// Specifically, the given `Offset` is treated as relative to `block.src_base_inst`.
409 /// Specifically, the given `Offset` is treated as relative to `block.src_baseline`.
410410 pub fn src(block: Block, offset: LazySrcLoc.Offset) LazySrcLoc {
411411 return .{
412 .base_node_inst = block.src_base_inst,
412 .baseline = block.src_baseline,
413413 .offset = offset,
414414 };
415415 }
......@@ -530,7 +530,7 @@ pub const Block = struct {
530530 .float_mode = parent.float_mode,
531531 .error_return_trace_index = parent.error_return_trace_index,
532532 .need_debug_scope = parent.need_debug_scope,
533 .src_base_inst = parent.src_base_inst,
533 .src_baseline = parent.src_baseline,
534534 .type_name_ctx = parent.type_name_ctx,
535535 .type_fqn_ctx = parent.type_fqn_ctx,
536536 };
......@@ -1110,14 +1110,17 @@ fn analyzeBodyInner(
11101110 block: *Block,
11111111 body: []const Zir.Inst.Index,
11121112) CompileError!void {
1113 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
1114
11151113 const pt = sema.pt;
11161114 const zcu = pt.zcu;
1115 const comp = zcu.comp;
1116 const gpa = comp.gpa;
1117
11171118 const map = &sema.inst_map;
11181119 const tags = sema.code.instructions.items(.tag);
11191120 const datas = sema.code.instructions.items(.data);
11201121
1122 try map.ensureSpaceForInstructions(gpa, body);
1123
11211124 var crash_info: crash_report.AnalyzeBody = undefined;
11221125 crash_info.push(sema, block, body);
11231126 defer crash_info.pop();
......@@ -1130,13 +1133,10 @@ fn analyzeBodyInner(
11301133 crash_info.setBodyIndex(i);
11311134 const inst = body[i];
11321135
1133 // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away.
1136 // This log is a bit expensive, and LLVM fails to optimize it away.
11341137 if (build_options.enable_logging) {
1135 std.log.scoped(.sema_zir).debug("sema ZIR {f} %{d}", .{ path: {
1136 const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool);
1137 const file = zcu.fileByIndex(file_index);
1138 break :path file.path.fmt(zcu.comp);
1139 }, inst });
1138 const path = zcu.namespacePtr(block.namespace).fileScope(zcu).path;
1139 std.log.scoped(.sema_zir).debug("sema ZIR {f} %{d}", .{ path.fmt(comp), inst });
11401140 }
11411141
11421142 const air_ref: Air.Inst.Ref = inst: switch (tags[@backingInt(inst)]) {
......@@ -1757,7 +1757,6 @@ fn analyzeBodyInner(
17571757 const inst_data = datas[@backingInt(inst)].pl_node;
17581758 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
17591759 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1760 const gpa = sema.gpa;
17611760
17621761 const BreakResult = struct {
17631762 block_inst: Zir.Inst.Index,
......@@ -1902,7 +1901,7 @@ fn analyzeBodyInner(
19021901 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
19031902 return sema.failWithOwnedErrorMsg(block, msg: {
19041903 const msg = try sema.errMsg(operand_src, "expected error union type, found '{f}'", .{err_union_ty.fmt(pt)});
1905 errdefer msg.destroy(sema.gpa);
1904 errdefer msg.destroy(gpa);
19061905 try sema.addDeclaredHereNote(msg, err_union_ty);
19071906 try sema.errNote(operand_src, msg, "consider omitting 'try'", .{});
19081907 break :msg msg;
......@@ -2511,7 +2510,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
25112510
25122511 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;
25132512 try sema.errNote(.{
2514 .base_node_inst = struct_type.zir_index,
2513 .baseline = .{ .inst = struct_type.zir_index, .node = .main },
25152514 .offset = .{ .container_field_value = @intCast(field_index) },
25162515 }, msg, "default value set here", .{});
25172516 break :msg msg;
......@@ -2633,7 +2632,7 @@ fn addFieldErrNote(
26332632 @branchHint(.cold);
26342633 const type_src = container_ty.srcLocOrNull(sema.pt.zcu) orelse return;
26352634 const field_src: LazySrcLoc = .{
2636 .base_node_inst = type_src.base_node_inst,
2635 .baseline = type_src.baseline,
26372636 .offset = .{ .container_field_name = @intCast(field_index) },
26382637 };
26392638 try sema.errNote(field_src, parent, format, args);
......@@ -5091,7 +5090,7 @@ fn zirCompileLog(
50915090 gop.value_ptr.last_line = line_idx;
50925091 } else {
50935092 gop.value_ptr.* = .{
5094 .base_node_inst = block.src_base_inst,
5093 .baseline = block.src_baseline,
50955094 .node_offset = src_node,
50965095 .first_line = line_idx,
50975096 .last_line = line_idx,
......@@ -5290,7 +5289,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
52905289 .runtime_loop = parent_block.runtime_loop,
52915290 .runtime_index = parent_block.runtime_index,
52925291 .error_return_trace_index = parent_block.error_return_trace_index,
5293 .src_base_inst = parent_block.src_base_inst,
5292 .src_baseline = parent_block.src_baseline,
52945293 .type_name_ctx = parent_block.type_name_ctx,
52955294 .type_fqn_ctx = parent_block.type_fqn_ctx,
52965295 };
......@@ -6370,7 +6369,7 @@ fn checkCallArgumentCount(
63706369
63716370 if (maybe_func_inst) |func_inst| {
63726371 try sema.errNote(.{
6373 .base_node_inst = func_inst,
6372 .baseline = .{ .inst = func_inst, .node = .main },
63746373 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
63756374 }, msg, "function declared here", .{});
63766375 }
......@@ -6528,7 +6527,7 @@ const CallArgsInfo = union(enum) {
65286527 .r = .{
65296528 .comptime_param = .{
65306529 .comptime_src = if (maybe_func_src_inst) |src_inst| .{
6531 .base_node_inst = src_inst,
6530 .baseline = .{ .inst = src_inst, .node = .main },
65326531 .offset = .{ .func_decl_param_comptime = @intCast(arg_index) },
65336532 } else unreachable, // should be non-null because the function is generic
65346533 },
......@@ -6621,7 +6620,7 @@ fn analyzeCall(
66216620
66226621 const maybe_func_inst = try sema.funcDeclSrcInst(callee);
66236622 const func_ret_ty_src: LazySrcLoc = if (maybe_func_inst) |fn_decl_inst| .{
6624 .base_node_inst = fn_decl_inst,
6623 .baseline = .{ .inst = fn_decl_inst, .node = .main },
66256624 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
66266625 } else func_src;
66276626
......@@ -6650,7 +6649,7 @@ fn analyzeCall(
66506649 );
66516650 errdefer msg.destroy(gpa);
66526651 if (maybe_func_inst) |func_inst| try sema.errNote(.{
6653 .base_node_inst = func_inst,
6652 .baseline = .{ .inst = func_inst, .node = .main },
66546653 .offset = .nodeOffset(.zero),
66556654 }, msg, "function declared here", .{});
66566655 break :msg msg;
......@@ -6774,7 +6773,7 @@ fn analyzeCall(
67746773 .namespace = fn_nav.analysis.?.namespace,
67756774 .instructions = .empty,
67766775 .inlining = &generic_inlining,
6777 .src_base_inst = fn_nav.analysis.?.zir_index,
6776 .src_baseline = .{ .inst = fn_nav.analysis.?.zir_index, .node = .main },
67786777 .type_name_ctx = fn_nav.name,
67796778 .type_fqn_ctx = fn_nav.fqn,
67806779 } else undefined;
......@@ -6853,7 +6852,10 @@ fn analyzeCall(
68536852 assert(!declared_comptime); // `analyzeArg` handles this
68546853 const arg_src = args_info.argSrc(block, arg_idx);
68556854 const param_ty_src: LazySrcLoc = .{
6856 .base_node_inst = maybe_func_inst.?, // the function is generic
6855 .baseline = .{
6856 .inst = maybe_func_inst.?, // the function is generic
6857 .node = .main,
6858 },
68576859 .offset = .{ .func_decl_param_ty = @intCast(arg_idx) },
68586860 };
68596861 return sema.failWithNeededComptime(
......@@ -7311,7 +7313,7 @@ fn analyzeCall(
73117313 .runtime_cond = block.runtime_cond,
73127314 .runtime_loop = block.runtime_loop,
73137315 .runtime_index = block.runtime_index,
7314 .src_base_inst = fn_nav.analysis.?.zir_index,
7316 .src_baseline = .{ .inst = fn_nav.analysis.?.zir_index, .node = .main },
73157317 .type_name_ctx = fn_nav.name,
73167318 .type_fqn_ctx = fn_nav.fqn,
73177319 };
......@@ -8848,7 +8850,7 @@ fn validateResolvedFuncType(
88488850 const param_ty: Type = .fromInterned(param_ty_ip);
88498851 if (!param_ty.validateExtern(.param_ty, zcu)) {
88508852 const param_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8851 .base_node_inst = inst,
8853 .baseline = .{ .inst = inst, .node = .main },
88528854 .offset = .{ .fn_proto_param = .{
88538855 .fn_proto_node_offset = .zero,
88548856 .param_index = @intCast(param_index),
......@@ -8868,7 +8870,7 @@ fn validateResolvedFuncType(
88688870 // Check that the return type is extern-compatible.
88698871 if (!ret_ty.validateExtern(.ret_ty, zcu)) {
88708872 const ret_ty_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8871 .base_node_inst = inst,
8873 .baseline = .{ .inst = inst, .node = .main },
88728874 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
88738875 } else src;
88748876 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -12205,7 +12207,7 @@ fn analyzeSwitchCaptures(
1220512207
1220612208 if (has_tag_capture) {
1220712209 const tag_capture_src: LazySrcLoc = .{
12208 .base_node_inst = capture_src.base_node_inst,
12210 .baseline = capture_src.baseline,
1220912211 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
1221012212 };
1221112213 return sema.failWithInvalidSwitchTagCapture(case_block, tag_capture_src, operand_ty);
......@@ -12307,7 +12309,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
1230712309 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);
1230812310 for (item_srcs, 0..) |*item_src, item_i| {
1230912311 item_src.* = .{
12310 .base_node_inst = capture_src.base_node_inst,
12312 .baseline = capture_src.baseline,
1231112313 .offset = .{ .switch_case_item = .{
1231212314 .switch_node_offset = switch_node_offset,
1231312315 .case_idx = capture_src.offset.switch_capture.case_idx,
......@@ -12347,7 +12349,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
1234712349 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);
1234812350 for (item_srcs, 0..) |*item_src, item_i| {
1234912351 item_src.* = .{
12350 .base_node_inst = capture_src.base_node_inst,
12352 .baseline = capture_src.baseline,
1235112353 .offset = .{ .switch_case_item = .{
1235212354 .switch_node_offset = switch_node_offset,
1235312355 .case_idx = capture_src.offset.switch_capture.case_idx,
......@@ -12429,7 +12431,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
1242912431 defer coerce_block.instructions.deinit(sema.gpa);
1243012432
1243112433 const case_src: LazySrcLoc = .{
12432 .base_node_inst = capture_src.base_node_inst,
12434 .baseline = capture_src.baseline,
1243312435 .offset = .{ .switch_case_item = .{
1243412436 .switch_node_offset = switch_node_offset,
1243512437 .case_idx = capture_src.offset.switch_capture.case_idx,
......@@ -15907,10 +15909,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1590715909 const msg = msg: {
1590815910 const name = name: {
1590915911 // TODO: we should probably store this name in the ZIR to avoid this complexity.
15910 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?;
15911 const tree = file.getTree(zcu) catch |err| {
15912 const file, const src_base_node = block.src_baseline.resolve(zcu).?;
15913 const tree = zcu.fileByIndex(file).getTree(zcu) catch |err| {
1591215914 // In this case we emit a warning + a less precise source location.
15913 log.warn("failed loading {qf}: {t}", .{ file.path.fmt(zcu.comp), err });
15915 log.warn("failed loading {qf}: {t}", .{ zcu.fileByIndex(file).path.fmt(zcu.comp), err });
1591415916 break :name null;
1591515917 };
1591615918 const node = src_node.toAbsolute(src_base_node);
......@@ -15933,10 +15935,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1593315935 if (!block.is_typeof and !block.isComptime() and sema.func_index != .none) {
1593415936 const msg = msg: {
1593515937 const name = name: {
15936 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?;
15937 const tree = file.getTree(zcu) catch |err| {
15938 const file, const src_base_node = block.src_baseline.resolve(zcu).?;
15939 const tree = zcu.fileByIndex(file).getTree(zcu) catch |err| {
1593815940 // In this case we emit a warning + a less precise source location.
15939 log.warn("failed loading {qf}: {t}", .{ file.path.fmt(zcu.comp), err });
15941 log.warn("failed loading {qf}: {t}", .{ zcu.fileByIndex(file).path.fmt(zcu.comp), err });
1594015942 break :name null;
1594115943 };
1594215944 const node = src_node.toAbsolute(src_base_node);
......@@ -17313,7 +17315,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1731317315 .is_typeof = true,
1731417316 .want_safety = false,
1731517317 .error_return_trace_index = block.error_return_trace_index,
17316 .src_base_inst = block.src_base_inst,
17318 .src_baseline = block.src_baseline,
1731717319 .type_name_ctx = block.type_name_ctx,
1731817320 .type_fqn_ctx = block.type_fqn_ctx,
1731917321 };
......@@ -17380,7 +17382,7 @@ fn zirTypeofPeer(
1738017382 .runtime_cond = block.runtime_cond,
1738117383 .runtime_loop = block.runtime_loop,
1738217384 .runtime_index = block.runtime_index,
17383 .src_base_inst = block.src_base_inst,
17385 .src_baseline = block.src_baseline,
1738417386 .type_name_ctx = block.type_name_ctx,
1738517387 .type_fqn_ctx = block.type_fqn_ctx,
1738617388 };
......@@ -17940,7 +17942,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
1794017942 .label = &labeled_block.label,
1794117943 .inlining = block.inlining,
1794217944 .comptime_reason = block.comptime_reason,
17943 .src_base_inst = block.src_base_inst,
17945 .src_baseline = block.src_baseline,
1794417946 .type_name_ctx = block.type_name_ctx,
1794517947 .type_fqn_ctx = block.type_fqn_ctx,
1794617948 },
......@@ -20180,40 +20182,40 @@ fn zirReifyStruct(
2018020182 const tracked_inst = try block.trackZir(inst);
2018120183
2018220184 const src: LazySrcLoc = .{
20183 .base_node_inst = tracked_inst,
20185 .baseline = .{ .inst = tracked_inst, .node = .main },
2018420186 .offset = .nodeOffset(.zero),
2018520187 };
2018620188
2018720189 const layout_src: LazySrcLoc = .{
20188 .base_node_inst = tracked_inst,
20190 .baseline = .{ .inst = tracked_inst, .node = .main },
2018920191 .offset = .{ .node_offset_builtin_call_arg = .{
2019020192 .builtin_call_node = .zero,
2019120193 .arg_index = 0,
2019220194 } },
2019320195 };
2019420196 const backing_ty_src: LazySrcLoc = .{
20195 .base_node_inst = tracked_inst,
20197 .baseline = .{ .inst = tracked_inst, .node = .main },
2019620198 .offset = .{ .node_offset_builtin_call_arg = .{
2019720199 .builtin_call_node = .zero,
2019820200 .arg_index = 1,
2019920201 } },
2020020202 };
2020120203 const field_names_src: LazySrcLoc = .{
20202 .base_node_inst = tracked_inst,
20204 .baseline = .{ .inst = tracked_inst, .node = .main },
2020320205 .offset = .{ .node_offset_builtin_call_arg = .{
2020420206 .builtin_call_node = .zero,
2020520207 .arg_index = 2,
2020620208 } },
2020720209 };
2020820210 const field_types_src: LazySrcLoc = .{
20209 .base_node_inst = tracked_inst,
20211 .baseline = .{ .inst = tracked_inst, .node = .main },
2021020212 .offset = .{ .node_offset_builtin_call_arg = .{
2021120213 .builtin_call_node = .zero,
2021220214 .arg_index = 3,
2021320215 } },
2021420216 };
2021520217 const field_attrs_src: LazySrcLoc = .{
20216 .base_node_inst = tracked_inst,
20218 .baseline = .{ .inst = tracked_inst, .node = .main },
2021720219 .offset = .{ .node_offset_builtin_call_arg = .{
2021820220 .builtin_call_node = .zero,
2021920221 .arg_index = 4,
......@@ -20460,40 +20462,40 @@ fn zirReifyUnion(
2046020462 const extra = sema.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;
2046120463 const tracked_inst = try block.trackZir(inst);
2046220464 const src: LazySrcLoc = .{
20463 .base_node_inst = tracked_inst,
20465 .baseline = .{ .inst = tracked_inst, .node = .main },
2046420466 .offset = .nodeOffset(.zero),
2046520467 };
2046620468
2046720469 const layout_src: LazySrcLoc = .{
20468 .base_node_inst = tracked_inst,
20470 .baseline = .{ .inst = tracked_inst, .node = .main },
2046920471 .offset = .{ .node_offset_builtin_call_arg = .{
2047020472 .builtin_call_node = .zero,
2047120473 .arg_index = 0,
2047220474 } },
2047320475 };
2047420476 const arg_ty_src: LazySrcLoc = .{
20475 .base_node_inst = tracked_inst,
20477 .baseline = .{ .inst = tracked_inst, .node = .main },
2047620478 .offset = .{ .node_offset_builtin_call_arg = .{
2047720479 .builtin_call_node = .zero,
2047820480 .arg_index = 1,
2047920481 } },
2048020482 };
2048120483 const field_names_src: LazySrcLoc = .{
20482 .base_node_inst = tracked_inst,
20484 .baseline = .{ .inst = tracked_inst, .node = .main },
2048320485 .offset = .{ .node_offset_builtin_call_arg = .{
2048420486 .builtin_call_node = .zero,
2048520487 .arg_index = 2,
2048620488 } },
2048720489 };
2048820490 const field_types_src: LazySrcLoc = .{
20489 .base_node_inst = tracked_inst,
20491 .baseline = .{ .inst = tracked_inst, .node = .main },
2049020492 .offset = .{ .node_offset_builtin_call_arg = .{
2049120493 .builtin_call_node = .zero,
2049220494 .arg_index = 3,
2049320495 } },
2049420496 };
2049520497 const field_attrs_src: LazySrcLoc = .{
20496 .base_node_inst = tracked_inst,
20498 .baseline = .{ .inst = tracked_inst, .node = .main },
2049720499 .offset = .{ .node_offset_builtin_call_arg = .{
2049820500 .builtin_call_node = .zero,
2049920501 .arg_index = 4,
......@@ -20681,33 +20683,33 @@ fn zirReifyEnum(
2068120683 const extra = sema.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;
2068220684 const tracked_inst = try block.trackZir(inst);
2068320685 const src: LazySrcLoc = .{
20684 .base_node_inst = tracked_inst,
20686 .baseline = .{ .inst = tracked_inst, .node = .main },
2068520687 .offset = .nodeOffset(.zero),
2068620688 };
2068720689
2068820690 const tag_ty_src: LazySrcLoc = .{
20689 .base_node_inst = tracked_inst,
20691 .baseline = .{ .inst = tracked_inst, .node = .main },
2069020692 .offset = .{ .node_offset_builtin_call_arg = .{
2069120693 .builtin_call_node = .zero,
2069220694 .arg_index = 0,
2069320695 } },
2069420696 };
2069520697 const mode_src: LazySrcLoc = .{
20696 .base_node_inst = tracked_inst,
20698 .baseline = .{ .inst = tracked_inst, .node = .main },
2069720699 .offset = .{ .node_offset_builtin_call_arg = .{
2069820700 .builtin_call_node = .zero,
2069920701 .arg_index = 1,
2070020702 } },
2070120703 };
2070220704 const field_names_src: LazySrcLoc = .{
20703 .base_node_inst = tracked_inst,
20705 .baseline = .{ .inst = tracked_inst, .node = .main },
2070420706 .offset = .{ .node_offset_builtin_call_arg = .{
2070520707 .builtin_call_node = .zero,
2070620708 .arg_index = 2,
2070720709 } },
2070820710 };
2070920711 const field_values_src: LazySrcLoc = .{
20710 .base_node_inst = tracked_inst,
20712 .baseline = .{ .inst = tracked_inst, .node = .main },
2071120713 .offset = .{ .node_offset_builtin_call_arg = .{
2071220714 .builtin_call_node = .zero,
2071320715 .arg_index = 3,
......@@ -20833,11 +20835,11 @@ fn zirReifySpirvType(
2083320835 const extra = sema.code.extraData(Zir.Inst.ReifySpirvType, extended.operand).data;
2083420836 const tracked_inst = try block.trackZir(inst);
2083520837 const src: LazySrcLoc = .{
20836 .base_node_inst = tracked_inst,
20838 .baseline = .{ .inst = tracked_inst, .node = .main },
2083720839 .offset = .nodeOffset(.zero),
2083820840 };
2083920841 const operand_src: LazySrcLoc = .{
20840 .base_node_inst = tracked_inst,
20842 .baseline = .{ .inst = tracked_inst, .node = .main },
2084120843 .offset = .{ .node_offset_builtin_call_arg = .{
2084220844 .builtin_call_node = .zero,
2084320845 .arg_index = 0,
......@@ -25675,7 +25677,7 @@ fn explainWhyTypeIsComptime(
2567525677 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
2567625678 if (!field_ty.comptimeOnly(zcu)) continue;
2567725679 const field_src: LazySrcLoc = .{
25678 .base_node_inst = struct_type.zir_index,
25680 .baseline = .{ .inst = struct_type.zir_index, .node = .main },
2567925681 .offset = .{ .container_field_type = @intCast(i) },
2568025682 };
2568125683 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});
......@@ -25700,7 +25702,7 @@ fn explainWhyTypeIsComptime(
2570025702 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);
2570125703 if (!field_ty.comptimeOnly(zcu)) continue;
2570225704 const field_src: LazySrcLoc = .{
25703 .base_node_inst = union_obj.zir_index,
25705 .baseline = .{ .inst = union_obj.zir_index, .node = .main },
2570425706 .offset = .{ .container_field_type = @intCast(i) },
2570525707 };
2570625708 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
......@@ -25914,7 +25916,7 @@ fn addSafetyCheck(
2591425916 .instructions = .empty,
2591525917 .inlining = parent_block.inlining,
2591625918 .comptime_reason = null,
25917 .src_base_inst = parent_block.src_base_inst,
25919 .src_baseline = parent_block.src_baseline,
2591825920 .type_name_ctx = parent_block.type_name_ctx,
2591925921 .type_fqn_ctx = parent_block.type_fqn_ctx,
2592025922 };
......@@ -26009,7 +26011,7 @@ fn addSafetyCheckUnwrapError(
2600926011 .instructions = .empty,
2601026012 .inlining = parent_block.inlining,
2601126013 .comptime_reason = null,
26012 .src_base_inst = parent_block.src_base_inst,
26014 .src_baseline = parent_block.src_baseline,
2601326015 .type_name_ctx = parent_block.type_name_ctx,
2601426016 .type_fqn_ctx = parent_block.type_fqn_ctx,
2601526017 };
......@@ -26133,7 +26135,7 @@ fn addSafetyCheckCall(
2613326135 .instructions = .empty,
2613426136 .inlining = parent_block.inlining,
2613526137 .comptime_reason = null,
26136 .src_base_inst = parent_block.src_base_inst,
26138 .src_baseline = parent_block.src_baseline,
2613726139 .type_name_ctx = parent_block.type_name_ctx,
2613826140 .type_fqn_ctx = parent_block.type_fqn_ctx,
2613926141 };
......@@ -27966,7 +27968,7 @@ const CoerceOpts = struct {
2796627968 if (info.func_inst == .none) return null;
2796727969 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;
2796827970 return .{
27969 .base_node_inst = func_inst,
27971 .baseline = .{ .inst = func_inst, .node = .main },
2797027972 .offset = .{ .fn_proto_param_type = .{
2797127973 .fn_proto_node_offset = .zero,
2797227974 .param_index = info.param_i,
......@@ -28684,7 +28686,10 @@ fn coerceExtra(
2868428686 errdefer msg.destroy(sema.gpa);
2868528687
2868628688 const ret_ty_src: LazySrcLoc = .{
28687 .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip),
28689 .baseline = .{
28690 .inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip),
28691 .node = .main,
28692 },
2868828693 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
2868928694 };
2869028695 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
......@@ -28724,7 +28729,10 @@ fn coerceExtra(
2872428729 !zcu.test_functions.contains(zcu.funcInfo(sema.func_index).owner_nav))
2872528730 {
2872628731 const ret_ty_src: LazySrcLoc = .{
28727 .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip),
28732 .baseline = .{
28733 .inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip),
28734 .node = .main,
28735 },
2872828736 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
2872928737 };
2873028738 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
......@@ -35008,7 +35016,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
3500835016 .instructions = .empty,
3500935017 .inlining = null,
3501035018 .comptime_reason = null,
35011 .src_base_inst = std_type.typeDeclInst(zcu).?,
35019 .src_baseline = .{ .inst = std_type.typeDeclInst(zcu).?, .node = .main },
3501235020 .type_name_ctx = .empty,
3501335021 .type_fqn_ctx = .empty,
3501435022 };
......@@ -35023,7 +35031,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
3502335031 };
3502435032 const uncoerced_val = try sema.analyzeNavVal(&block, std_src, nav);
3502535033 const decl_src: LazySrcLoc = .{
35026 .base_node_inst = ip.getNav(nav).srcInst(ip),
35034 .baseline = .{ .inst = ip.getNav(nav).srcInst(ip), .node = .main },
3502735035 .offset = .nodeOffset(.zero),
3502835036 };
3502935037 break :ty try sema.analyzeAsType(&block, decl_src, .std_lang_decl, uncoerced_val);
......@@ -35053,7 +35061,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
3505335061 const uncoerced_val = try sema.analyzeNavVal(&block, parent_ty_src, nav);
3505435062
3505535063 const decl_src: LazySrcLoc = .{
35056 .base_node_inst = ip.getNav(nav).srcInst(ip),
35064 .baseline = .{ .inst = ip.getNav(nav).srcInst(ip), .node = .main },
3505735065 .offset = .nodeOffset(.zero),
3505835066 };
3505935067
......@@ -35343,7 +35351,7 @@ fn zirStructDecl(
3534335351 const tracked_inst = try block.trackZir(inst);
3534435352
3534535353 const src: LazySrcLoc = .{
35346 .base_node_inst = tracked_inst,
35354 .baseline = .{ .inst = tracked_inst, .node = .main },
3534735355 .offset = .nodeOffset(.zero),
3534835356 };
3534935357
......@@ -35401,7 +35409,7 @@ fn zirUnionDecl(
3540135409 const tracked_inst = try block.trackZir(inst);
3540235410
3540335411 const src: LazySrcLoc = .{
35404 .base_node_inst = tracked_inst,
35412 .baseline = .{ .inst = tracked_inst, .node = .main },
3540535413 .offset = .nodeOffset(.zero),
3540635414 };
3540735415
......@@ -35477,7 +35485,7 @@ fn zirEnumDecl(
3547735485 const tracked_inst = try block.trackZir(inst);
3547835486
3547935487 const src: LazySrcLoc = .{
35480 .base_node_inst = tracked_inst,
35488 .baseline = .{ .inst = tracked_inst, .node = .main },
3548135489 .offset = .nodeOffset(.zero),
3548235490 };
3548335491
......@@ -35532,7 +35540,7 @@ fn zirOpaqueDecl(
3553235540 const tracked_inst = try block.trackZir(inst);
3553335541
3553435542 const src: LazySrcLoc = .{
35535 .base_node_inst = tracked_inst,
35543 .baseline = .{ .inst = tracked_inst, .node = .main },
3553635544 .offset = .nodeOffset(.zero),
3553735545 };
3553835546
src/Sema/LowerZon.zig+52-54
......@@ -22,11 +22,11 @@ const Zoir = std.zig.Zoir;
2222const LowerZon = @This();
2323
2424sema: *Sema,
25file: *File,
26file_index: Zcu.File.Index,
27import_loc: LazySrcLoc,
2825block: *Sema.Block,
29base_node_inst: InternPool.TrackedInst.Index,
26tracked_inst: InternPool.TrackedInst.Index,
27zoir: *const Zoir,
28file_index: Zcu.File.Index,
29import_src: LazySrcLoc,
3030
3131/// Lowers the given file as ZON.
3232pub fn run(
......@@ -34,28 +34,26 @@ pub fn run(
3434 file: *File,
3535 file_index: Zcu.File.Index,
3636 res_ty_interned: InternPool.Index,
37 import_loc: LazySrcLoc,
37 import_src: LazySrcLoc,
3838 block: *Sema.Block,
3939) CompileError!InternPool.Index {
4040 const pt = sema.pt;
41 const comp = pt.zcu.comp;
41 const zcu = pt.zcu;
42 const comp = zcu.comp;
4243 const gpa = comp.gpa;
4344 const io = comp.io;
4445
45 const tracked_inst = try pt.zcu.intern_pool.trackZir(gpa, io, pt.tid, .{
46 .file = file_index,
47 .inst = .main_struct_inst, // this is the only trackable instruction in a ZON file
48 });
49
5046 var lower_zon: LowerZon = .{
5147 .sema = sema,
52 .file = file,
53 .file_index = file_index,
54 .import_loc = import_loc,
5548 .block = block,
56 .base_node_inst = tracked_inst,
49 .tracked_inst = try zcu.intern_pool.trackZir(gpa, io, pt.tid, .{
50 .file = file_index,
51 .inst = .main_struct_inst, // this is the only trackable instruction in a ZON file
52 }),
53 .zoir = &file.zoir.?,
54 .file_index = file_index,
55 .import_src = import_src,
5756 };
58
5957 if (res_ty_interned == .none) {
6058 return lower_zon.lowerExprAnonResTy(.root);
6159 } else {
......@@ -71,7 +69,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
7169 const gpa = comp.gpa;
7270 const io = comp.io;
7371 const ip = &pt.zcu.intern_pool;
74 switch (node.get(self.file.zoir.?)) {
72 switch (node.get(self.zoir.*)) {
7573 .true => return .bool_true,
7674 .false => return .bool_false,
7775 .null => return .null_value,
......@@ -101,7 +99,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
10199 gpa,
102100 io,
103101 pt.tid,
104 val.get(self.file.zoir.?),
102 val.get(self.zoir.*),
105103 .no_embedded_nulls,
106104 ),
107105 }),
......@@ -130,7 +128,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
130128 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
131129 }
132130 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
133 .zir_index = self.base_node_inst,
131 .zir_index = self.tracked_inst,
134132 .type_hash = hash: {
135133 var hasher: std.hash.Wyhash = .init(0);
136134 hasher.update(std.mem.asBytes(&node));
......@@ -150,7 +148,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
150148 errdefer wip.cancel(ip, pt.tid);
151149 const block = self.block;
152150 const zcu = pt.zcu;
153 try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?);
151 try self.sema.setTypeName(block, &wip, .anon, "struct", .main_struct_inst);
154152
155153 // Reified structs have field information populated immediately.
156154 @memcpy(wip.field_values.get(ip), elems);
......@@ -174,7 +172,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
174172 gpa,
175173 io,
176174 pt.tid,
177 zoir_name.get(self.file.zoir.?),
175 zoir_name.get(self.zoir.*),
178176 .no_embedded_nulls,
179177 );
180178 field_ty.* = ip.typeOf(field_val);
......@@ -289,7 +287,7 @@ fn checkTypeInner(
289287 } else {
290288 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
291289 if (gop.found_existing) return;
292 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
290 try sema.ensureLayoutResolved(ty, self.import_src, .init);
293291 const struct_info = zcu.typeToStruct(ty).?;
294292 for (struct_info.field_types.get(ip)) |field_type| {
295293 try self.checkTypeInner(.fromInterned(field_type), null, visited);
......@@ -298,7 +296,7 @@ fn checkTypeInner(
298296 .@"union" => {
299297 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
300298 if (gop.found_existing) return;
301 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
299 try sema.ensureLayoutResolved(ty, self.import_src, .init);
302300 const union_info = zcu.typeToUnion(ty).?;
303301 for (union_info.field_types.get(ip)) |field_type| {
304302 if (field_type != .void_type) {
......@@ -311,8 +309,8 @@ fn checkTypeInner(
311309
312310fn nodeSrc(self: *LowerZon, node: Zoir.Node.Index) LazySrcLoc {
313311 return .{
314 .base_node_inst = self.base_node_inst,
315 .offset = .{ .node_abs = node.getAstNode(self.file.zoir.?) },
312 .baseline = .{ .inst = self.tracked_inst, .node = .main },
313 .offset = .{ .node_abs = node.getAstNode(self.zoir.*) },
316314 };
317315}
318316
......@@ -326,9 +324,9 @@ fn failUnsupportedResultType(
326324 const gpa = sema.gpa;
327325 const pt = sema.pt;
328326 return sema.failWithOwnedErrorMsg(self.block, msg: {
329 const msg = try sema.errMsg(self.import_loc, "type '{f}' is not available in ZON", .{ty.fmt(pt)});
327 const msg = try sema.errMsg(self.import_src, "type '{f}' is not available in ZON", .{ty.fmt(pt)});
330328 errdefer msg.destroy(gpa);
331 if (opt_note) |n| try sema.errNote(self.import_loc, msg, "{s}", .{n});
329 if (opt_note) |n| try sema.errNote(self.import_src, msg, "{s}", .{n});
332330 break :msg msg;
333331 });
334332}
......@@ -341,7 +339,7 @@ fn fail(
341339) Zcu.SemaError {
342340 @branchHint(.cold);
343341 const err_msg = try Zcu.ErrorMsg.create(self.sema.pt.zcu.gpa, self.nodeSrc(node), format, args);
344 try self.sema.pt.zcu.errNote(self.import_loc, err_msg, "imported here", .{});
342 try self.sema.pt.zcu.errNote(self.import_src, err_msg, "imported here", .{});
345343 return self.sema.failWithOwnedErrorMsg(self.block, err_msg);
346344}
347345
......@@ -363,7 +361,7 @@ fn lowerExprKnownResTyInner(
363361 .optional => return pt.intern(.{
364362 .opt = .{
365363 .ty = res_ty.toIntern(),
366 .val = if (node.get(self.file.zoir.?) == .null) b: {
364 .val = if (node.get(self.zoir.*) == .null) b: {
367365 break :b .none;
368366 } else b: {
369367 const child_type = res_ty.optionalChild(pt.zcu);
......@@ -418,7 +416,7 @@ fn lowerExprKnownResTyInner(
418416}
419417
420418fn lowerBool(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
421 return switch (node.get(self.file.zoir.?)) {
419 return switch (node.get(self.zoir.*)) {
422420 .true => .bool_true,
423421 .false => .bool_false,
424422 else => return error.WrongType,
......@@ -431,7 +429,7 @@ fn lowerInt(
431429 res_ty: Type,
432430) !InternPool.Index {
433431 @setFloatMode(.strict);
434 return switch (node.get(self.file.zoir.?)) {
432 return switch (node.get(self.zoir.*)) {
435433 .int_literal => |int| switch (int) {
436434 .small => |val| {
437435 const rhs: i32 = val;
......@@ -555,7 +553,7 @@ fn lowerFloat(
555553 res_ty: Type,
556554) !InternPool.Index {
557555 @setFloatMode(.strict);
558 const value = switch (node.get(self.file.zoir.?)) {
556 const value = switch (node.get(self.zoir.*)) {
559557 .int_literal => |int| switch (int) {
560558 .small => |val| try self.sema.pt.floatValue(res_ty, @as(f128, @floatFromInt(val))),
561559 .big => |val| try self.sema.pt.floatValue(res_ty, val.toFloat(f128, .nearest_even)[0]),
......@@ -592,7 +590,7 @@ fn lowerFloat(
592590}
593591
594592fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
595 switch (node.get(self.file.zoir.?)) {
593 switch (node.get(self.zoir.*)) {
596594 .null => return .null_value,
597595 else => return error.WrongType,
598596 }
......@@ -600,7 +598,7 @@ fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
600598
601599fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.Index {
602600 const array_info = res_ty.arrayInfo(self.sema.pt.zcu);
603 const nodes: Zoir.Node.Index.Range = switch (node.get(self.file.zoir.?)) {
601 const nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir.*)) {
604602 .array_literal => |nodes| nodes,
605603 .empty_literal => .{ .start = node, .len = 0 },
606604 else => return error.WrongType,
......@@ -632,14 +630,14 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
632630 const gpa = comp.gpa;
633631 const io = comp.io;
634632 const ip = &pt.zcu.intern_pool;
635 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
636 switch (node.get(self.file.zoir.?)) {
633 try self.sema.ensureLayoutResolved(res_ty, self.import_src, .init);
634 switch (node.get(self.zoir.*)) {
637635 .enum_literal => |field_name| {
638636 const field_name_interned = try ip.getOrPutString(
639637 gpa,
640638 io,
641639 self.sema.pt.tid,
642 field_name.get(self.file.zoir.?),
640 field_name.get(self.zoir.*),
643641 .no_embedded_nulls,
644642 );
645643 const field_index = res_ty.enumFieldIndex(field_name_interned, self.sema.pt.zcu) orelse {
......@@ -648,7 +646,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
648646 "enum {f} has no member named '{f}'",
649647 .{
650648 res_ty.fmt(self.sema.pt),
651 std.zig.fmtId(field_name.get(self.file.zoir.?)),
649 std.zig.fmtId(field_name.get(self.zoir.*)),
652650 },
653651 );
654652 };
......@@ -667,13 +665,13 @@ fn lowerEnumLiteral(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
667665 const gpa = comp.gpa;
668666 const io = comp.io;
669667 const ip = &pt.zcu.intern_pool;
670 switch (node.get(self.file.zoir.?)) {
668 switch (node.get(self.zoir.*)) {
671669 .enum_literal => |field_name| {
672670 const field_name_interned = try ip.getOrPutString(
673671 gpa,
674672 io,
675673 self.sema.pt.tid,
676 field_name.get(self.file.zoir.?),
674 field_name.get(self.zoir.*),
677675 .no_embedded_nulls,
678676 );
679677 return self.sema.pt.intern(.{ .enum_literal = field_name_interned });
......@@ -696,7 +694,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
696694
697695 const tuple_info = ip.indexToKey(res_ty.toIntern()).tuple_type;
698696
699 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.file.zoir.?)) {
697 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir.*)) {
700698 .array_literal => |nodes| nodes,
701699 .empty_literal => .{ .start = node, .len = 0 },
702700 else => return error.WrongType,
......@@ -720,7 +718,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
720718 "index {} outside tuple of length {}",
721719 .{
722720 elems.len,
723 elem_nodes.at(@intCast(i)).getAstNode(self.file.zoir.?),
721 elem_nodes.at(@intCast(i)).getAstNode(self.zoir.*),
724722 },
725723 );
726724 }
......@@ -756,11 +754,11 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
756754 const io = comp.io;
757755 const ip = &pt.zcu.intern_pool;
758756
759 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
760 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);
757 try self.sema.ensureLayoutResolved(res_ty, self.import_src, .init);
758 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_src);
761759 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;
762760
763 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {
761 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.zoir.*)) {
764762 .struct_literal => |fields| fields,
765763 .empty_literal => .{ .names = &.{}, .vals = .{ .start = node, .len = 0 } },
766764 else => return error.WrongType,
......@@ -780,7 +778,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
780778 gpa,
781779 io,
782780 self.sema.pt.tid,
783 fields.names[i].get(self.file.zoir.?),
781 fields.names[i].get(self.zoir.*),
784782 .no_embedded_nulls,
785783 );
786784 const field_node = fields.vals.at(@intCast(i));
......@@ -844,7 +842,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
844842 const string_alignment = ptr_info.flags.alignment == .none or ptr_info.flags.alignment == .@"1";
845843 const string_sentinel = ptr_info.sentinel == .none or ptr_info.sentinel == .zero_u8;
846844 if (string_alignment and ptr_info.child == .u8_type and string_sentinel) {
847 switch (node.get(self.file.zoir.?)) {
845 switch (node.get(self.zoir.*)) {
848846 .string_literal => |val| {
849847 const ip_str = try ip.getOrPutString(gpa, io, self.sema.pt.tid, val, .maybe_embedded_nulls);
850848 const str_ref = try self.sema.addStrLit(ip_str, val.len);
......@@ -860,7 +858,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
860858 }
861859
862860 // Slice literals
863 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.file.zoir.?)) {
861 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir.*)) {
864862 .array_literal => |nodes| nodes,
865863 .empty_literal => .{ .start = node, .len = 0 },
866864 else => return error.WrongType,
......@@ -923,23 +921,23 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
923921 const gpa = comp.gpa;
924922 const io = comp.io;
925923 const ip = &pt.zcu.intern_pool;
926 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
924 try self.sema.ensureLayoutResolved(res_ty, self.import_src, .init);
927925 const union_info = pt.zcu.typeToUnion(res_ty).?;
928926 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);
929927
930 const field_name, const maybe_field_node = switch (node.get(self.file.zoir.?)) {
928 const field_name, const maybe_field_node = switch (node.get(self.zoir.*)) {
931929 .enum_literal => |name| b: {
932930 const field_name = try ip.getOrPutString(
933931 gpa,
934932 io,
935933 self.sema.pt.tid,
936 name.get(self.file.zoir.?),
934 name.get(self.zoir.*),
937935 .no_embedded_nulls,
938936 );
939937 break :b .{ field_name, null };
940938 },
941939 .struct_literal => b: {
942 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {
940 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.zoir.*)) {
943941 .struct_literal => |fields| fields,
944942 else => return self.fail(node, "expected type '{f}'", .{res_ty.fmt(self.sema.pt)}),
945943 };
......@@ -950,7 +948,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
950948 gpa,
951949 io,
952950 self.sema.pt.tid,
953 fields.names[0].get(self.file.zoir.?),
951 fields.names[0].get(self.zoir.*),
954952 .no_embedded_nulls,
955953 );
956954 break :b .{ field_name, fields.vals.at(0) };
......@@ -986,7 +984,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
986984
987985 const vector_info = ip.indexToKey(res_ty.toIntern()).vector_type;
988986
989 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.file.zoir.?)) {
987 const elem_nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir.*)) {
990988 .array_literal => |nodes| nodes,
991989 .empty_literal => .{ .start = node, .len = 0 },
992990 else => return error.WrongType,
src/Sema/type_resolution.zig+61-16
......@@ -205,7 +205,10 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
205205 .instructions = .empty,
206206 .inlining = null,
207207 .comptime_reason = undefined, // always set before using `block`
208 .src_base_inst = struct_obj.zir_index,
208 .src_baseline = .{
209 .inst = struct_obj.zir_index,
210 .node = .main,
211 },
209212 .type_name_ctx = struct_obj.name,
210213 .type_fqn_ctx = struct_obj.fqn,
211214 };
......@@ -261,6 +264,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
261264 {
262265 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
263266 const field_ty: Type = field_ty: {
267 block.src_baseline.node = .type_decl_fields;
268 defer block.src_baseline.node = .main;
264269 block.comptime_reason = .{ .reason = .{
265270 .src = field_ty_src,
266271 .r = .{ .simple = .struct_field_types },
......@@ -276,6 +281,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
276281 } else {
277282 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
278283 const field_align: Alignment = a: {
284 block.src_baseline.node = .type_decl_fields;
285 defer block.src_baseline.node = .main;
279286 block.comptime_reason = .{ .reason = .{
280287 .src = field_align_src,
281288 .r = .{ .simple = .struct_field_attrs },
......@@ -538,6 +545,8 @@ fn resolvePackedStructLayout(
538545 field_bits += field_ty.bitSize(zcu);
539546 }
540547
548 const backing_int_ty_src = block.src(.container_arg);
549
541550 const explicit_backing_int_ty: ?Type = if (struct_obj.is_reified) ty: {
542551 break :ty switch (struct_obj.packed_backing_mode) {
543552 .explicit => .fromInterned(struct_obj.packed_backing_int_type),
......@@ -550,20 +559,21 @@ fn resolvePackedStructLayout(
550559 break :ty null; // inferred backing type
551560 };
552561 // Explicitly specified, so evaluate the backing int type expression.
553 const backing_int_type_src = block.src(.container_arg);
562 block.src_baseline.node = .type_decl_arg;
563 defer block.src_baseline.node = .main;
554564 block.comptime_reason = .{ .reason = .{
555 .src = backing_int_type_src,
565 .src = backing_int_ty_src,
556566 .r = .{ .simple = .packed_struct_backing_int_type },
557567 } };
558568 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);
559 break :ty try sema.analyzeAsType(block, backing_int_type_src, .packed_struct_backing_int_type, type_ref);
569 break :ty try sema.analyzeAsType(block, backing_int_ty_src, .packed_struct_backing_int_type, type_ref);
560570 };
561571
562572 // Finally, either validate or infer the backing int type.
563573 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
564574 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
565575 block,
566 block.src(.container_arg),
576 backing_int_ty_src,
567577 "expected backing integer type, found '{f}'",
568578 .{backing_ty.fmt(pt)},
569579 );
......@@ -572,7 +582,7 @@ fn resolvePackedStructLayout(
572582 const msg = try sema.errMsg(src, "backing integer bit width does not match total bit width of fields", .{});
573583 errdefer msg.destroy(gpa);
574584 try sema.errNote(
575 block.src(.container_arg),
585 backing_int_ty_src,
576586 msg,
577587 "backing integer '{f}' has bit width '{d}'",
578588 .{ backing_ty.fmt(pt), backing_ty.bitSize(zcu) },
......@@ -652,7 +662,10 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {
652662 .instructions = .empty,
653663 .inlining = null,
654664 .comptime_reason = undefined, // always set before using `block`
655 .src_base_inst = struct_obj.zir_index,
665 .src_baseline = .{
666 .inst = struct_obj.zir_index,
667 .node = .main,
668 },
656669 .type_name_ctx = struct_obj.name,
657670 .type_fqn_ctx = struct_obj.fqn,
658671 };
......@@ -675,6 +688,7 @@ fn resolveStructDefaultsInner(
675688 const ip = &zcu.intern_pool;
676689
677690 assert(struct_obj.field_defaults.len > 0);
691 assert(block.src_baseline.node == .main);
678692
679693 // We'll need to map the struct decl instruction to provide result types
680694 const zir_index = struct_obj.zir_index.resolve(ip) orelse {
......@@ -693,6 +707,8 @@ fn resolveStructDefaultsInner(
693707 }
694708
695709 const default_val_src = block.src(.{ .container_field_value = zir_field.idx });
710 block.src_baseline.node = .type_decl_fields;
711 defer block.src_baseline.node = .main;
696712 block.comptime_reason = .{ .reason = .{
697713 .src = default_val_src,
698714 .r = .{ .simple = .struct_field_default_value },
......@@ -747,7 +763,10 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
747763 .instructions = .empty,
748764 .inlining = null,
749765 .comptime_reason = undefined, // always set before using `block`
750 .src_base_inst = union_obj.zir_index,
766 .src_baseline = .{
767 .inst = union_obj.zir_index,
768 .node = .main,
769 },
751770 .type_name_ctx = union_obj.name,
752771 .type_fqn_ctx = union_obj.fqn,
753772 };
......@@ -764,6 +783,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
764783 assert(zir_union.kind == .tagged_explicit); // `Zcu.mapOldZirToNew` guarantees that the ZIR mapping preserves `kind`
765784 const tag_type_body = zir_union.arg_type_body.?;
766785 const tag_type_src = block.src(.container_arg);
786 block.src_baseline.node = .type_decl_fields;
787 defer block.src_baseline.node = .main;
767788 block.comptime_reason = .{ .reason = .{
768789 .src = tag_type_src,
769790 .r = .{ .simple = .union_enum_tag_type },
......@@ -882,6 +903,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
882903 while (field_it.next()) |zir_field| {
883904 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
884905 const field_ty: Type = field_ty: {
906 block.src_baseline.node = .type_decl_fields;
907 defer block.src_baseline.node = .main;
885908 block.comptime_reason = .{ .reason = .{
886909 .src = field_ty_src,
887910 .r = .{ .simple = .union_field_types },
......@@ -894,6 +917,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
894917
895918 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
896919 const explicit_field_align: Alignment = a: {
920 block.src_baseline.node = .type_decl_fields;
921 defer block.src_baseline.node = .main;
897922 block.comptime_reason = .{ .reason = .{
898923 .src = field_align_src,
899924 .r = .{ .simple = .union_field_attrs },
......@@ -1066,7 +1091,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const
10661091 if (union_field_index != null) continue;
10671092 const field_name_ip = enum_obj.field_names.get(ip)[enum_field_index];
10681093 const enum_field_src: LazySrcLoc = .{
1069 .base_node_inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
1094 .baseline = .{
1095 .inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
1096 .node = .main,
1097 },
10701098 .offset = .{ .container_field_name = @intCast(enum_field_index) },
10711099 };
10721100 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -1082,7 +1110,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const
10821110 const field_name = enum_obj.field_names.get(ip)[enum_field_index];
10831111 const union_field_src = block.src(.{ .container_field_name = union_field_index.? });
10841112 const enum_field_src: LazySrcLoc = .{
1085 .base_node_inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
1113 .baseline = .{
1114 .inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
1115 .node = .main,
1116 },
10861117 .offset = .{ .container_field_name = @intCast(enum_field_index) },
10871118 };
10881119 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -1138,6 +1169,8 @@ fn resolvePackedUnionLayout(
11381169 assert(!field_ty.comptimeOnly(zcu)); // packable types are not comptime-only
11391170 }
11401171
1172 const backing_int_ty_src = block.src(.container_arg);
1173
11411174 const explicit_backing_int_ty: ?Type = if (union_obj.is_reified) ty: {
11421175 switch (union_obj.packed_backing_mode) {
11431176 .explicit => break :ty .fromInterned(union_obj.packed_backing_int_type),
......@@ -1150,20 +1183,21 @@ fn resolvePackedUnionLayout(
11501183 break :ty null; // inferred backing type
11511184 };
11521185 // Explicitly specified, so evaluate the backing int type expression.
1153 const backing_int_type_src = block.src(.container_arg);
1186 block.src_baseline.node = .type_decl_arg;
1187 defer block.src_baseline.node = .main;
11541188 block.comptime_reason = .{ .reason = .{
1155 .src = backing_int_type_src,
1189 .src = backing_int_ty_src,
11561190 .r = .{ .simple = .packed_union_backing_int_type },
11571191 } };
11581192 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);
1159 break :ty try sema.analyzeAsType(block, backing_int_type_src, .packed_union_backing_int_type, type_ref);
1193 break :ty try sema.analyzeAsType(block, backing_int_ty_src, .packed_union_backing_int_type, type_ref);
11601194 };
11611195
11621196 // Finally, either validate or infer the backing int type.
11631197 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
11641198 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
11651199 block,
1166 block.src(.container_arg),
1200 backing_int_ty_src,
11671201 "expected backing integer type, found '{f}'",
11681202 .{backing_ty.fmt(pt)},
11691203 );
......@@ -1177,7 +1211,7 @@ fn resolvePackedUnionLayout(
11771211 errdefer msg.destroy(gpa);
11781212 try sema.errNote(field_ty_src, msg, "field type '{f}' has bit width '{d}'", .{ field_type.fmt(pt), field_bits });
11791213 try sema.errNote(
1180 block.src(.container_arg),
1214 backing_int_ty_src,
11811215 msg,
11821216 "backing integer '{f}' has bit width '{d}'",
11831217 .{ backing_ty.fmt(pt), backing_int_bits },
......@@ -1256,7 +1290,10 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
12561290 .instructions = .empty,
12571291 .inlining = null,
12581292 .comptime_reason = undefined, // always set before using `block`
1259 .src_base_inst = tracked_inst,
1293 .src_baseline = .{
1294 .inst = tracked_inst,
1295 .node = .main,
1296 },
12601297 .type_name_ctx = enum_obj.name,
12611298 .type_fqn_ctx = enum_obj.fqn,
12621299 };
......@@ -1341,6 +1378,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
13411378 // Explicitly specified, so evaluate the int tag type expression.
13421379 const tag_type_body = zir_union.arg_type_body.?;
13431380 const tag_type_src = block.src(.container_arg);
1381 block.src_baseline.node = .type_decl_arg;
1382 defer block.src_baseline.node = .main;
13441383 block.comptime_reason = .{ .reason = .{
13451384 .src = tag_type_src,
13461385 .r = .{ .simple = .enum_int_tag_type },
......@@ -1354,6 +1393,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
13541393 };
13551394 // Explicitly specified, so evaluate the int tag type expression.
13561395 const tag_type_src = block.src(.container_arg);
1396 block.src_baseline.node = .type_decl_arg;
1397 defer block.src_baseline.node = .main;
13571398 block.comptime_reason = .{ .reason = .{
13581399 .src = tag_type_src,
13591400 .r = .{ .simple = .enum_int_tag_type },
......@@ -1425,6 +1466,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
14251466 var field_it = zir_union.iterateFields();
14261467 while (field_it.next()) |zir_field| {
14271468 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });
1469 block.src_baseline.node = .type_decl_fields;
1470 defer block.src_baseline.node = .main;
14281471 block.comptime_reason = .{ .reason = .{
14291472 .src = field_val_src,
14301473 .r = .{ .simple = .enum_field_values },
......@@ -1447,6 +1490,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
14471490 var field_it = zir_enum.iterateFields();
14481491 while (field_it.next()) |zir_field| {
14491492 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });
1493 block.src_baseline.node = .type_decl_fields;
1494 defer block.src_baseline.node = .main;
14501495 block.comptime_reason = .{ .reason = .{
14511496 .src = field_val_src,
14521497 .r = .{ .simple = .enum_field_values },
src/Type.zig+9-6
......@@ -2586,13 +2586,16 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
25862586pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
25872587 const ip = &zcu.intern_pool;
25882588 return .{
2589 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {
2590 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2591 .declared => |d| d.zir_index,
2592 .reified => |r| r.zir_index,
2593 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
2589 .baseline = .{
2590 .inst = switch (ip.indexToKey(ty.toIntern())) {
2591 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2592 .declared => |d| d.zir_index,
2593 .reified => |r| r.zir_index,
2594 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
2595 },
2596 else => return null,
25942597 },
2595 else => return null,
2598 .node = .main,
25962599 },
25972600 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),
25982601 };
src/Zcu.zig+109-54
......@@ -209,14 +209,14 @@ dependency_loop_nodes: std.array_hash_map.Auto(AnalUnit, struct {
209209/// Keep track of `@compileLog`s per `AnalUnit`.
210210/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.
211211/// The list is singly linked, but we do track its tail for fast appends (optimizing many logs in one unit).
212compile_logs: std.array_hash_map.Auto(AnalUnit, extern struct {
213 base_node_inst: InternPool.TrackedInst.Index,
212compile_logs: std.array_hash_map.Auto(AnalUnit, struct {
213 baseline: LazySrcLoc.Baseline,
214214 node_offset: Ast.Node.Offset,
215215 first_line: CompileLogLine.Index,
216216 last_line: CompileLogLine.Index,
217217 pub fn src(self: @This()) LazySrcLoc {
218218 return .{
219 .base_node_inst = self.base_node_inst,
219 .baseline = self.baseline,
220220 .offset = LazySrcLoc.Offset.nodeOffset(self.node_offset),
221221 };
222222 }
......@@ -2341,21 +2341,115 @@ pub const SrcLoc = struct {
23412341};
23422342
23432343pub const LazySrcLoc = struct {
2344 /// This instruction provides the source node locations are resolved relative to.
2345 /// It is a `declaration`, `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl`.
2346 /// This must be valid even if `relative` is an absolute value, since it is required to
2347 /// determine the file which the `LazySrcLoc` refers to.
2348 base_node_inst: InternPool.TrackedInst.Index,
2349 /// This field determines the source location relative to `base_node_inst`.
2344 /// The baseline is a reference to a single AST node which `offset` is relative to. We use this
2345 /// offset-based approach because AST node indices change across incremental updates, but we can
2346 /// track the changes for certain instructions (e.g. declarations). `Baseline` is a stable
2347 /// reference to a source location in such an instruction. By representing all source locations
2348 /// as relative to one of these baselines, we make them independent of changes in a file which
2349 /// happen outside of (e.g.) a specific declaration.
2350 baseline: Baseline,
2351 /// This field determines the source location relative to `baseline`.
23502352 offset: Offset,
23512353
2354 pub const Baseline = struct {
2355 inst: InternPool.TrackedInst.Index,
2356 node: enum {
2357 /// `inst` refers to any trackable instruction (see `Zir.assertTrackable`).
2358 ///
2359 /// The baseline node is its main source node.
2360 main,
2361 /// `inst` refers to a `.struct_decl`, `.union_decl`, or `.enum_decl`.
2362 ///
2363 /// The baseline node is the `Zir.Unwrapped[Type]Decl.fields_baseline_src_node`.
2364 type_decl_fields,
2365 /// `inst` refers to a `.struct_decl`, `.union_decl`, or `.enum_decl`.
2366 ///
2367 /// The baseline node is the `Zir.Unwrapped[Type]Decl.arg_baseline_src_node`.
2368 type_decl_arg,
2369 },
2370
2371 /// Returns `null` if the ZIR instruction has been lost across incremental updates.
2372 pub fn resolve(b: Baseline, zcu: *Zcu) ?struct { File.Index, Ast.Node.Index } {
2373 const ip = &zcu.intern_pool;
2374 const resolved_ti = b.inst.resolveFull(ip) orelse return null;
2375 const file = zcu.fileByIndex(resolved_ti.file);
2376 const zir = switch (file.getMode()) {
2377 .zig => &file.zir.?,
2378 .zon => {
2379 // ZON files don't have ZIR. Instead they will always set their baseline to a
2380 // specific dummy value which must resolve to the file's root node.
2381 assert(resolved_ti.inst == .main_struct_inst);
2382 assert(b.node == .main);
2383 return .{ resolved_ti.file, .root };
2384 },
2385 };
2386
2387 comptime assert(Zir.inst_tracking_version == 0);
2388 const inst = zir.instructions.get(@backingInt(resolved_ti.inst));
2389 return .{
2390 resolved_ti.file,
2391 switch (b.node) {
2392 .main => switch (inst.tag) {
2393 .declaration => inst.data.declaration.src_node,
2394 .struct_init, .struct_init_ref => zir.extraData(
2395 Zir.Inst.StructInit,
2396 inst.data.pl_node.payload_index,
2397 ).data.abs_node,
2398 .struct_init_anon => zir.extraData(
2399 Zir.Inst.StructInitAnon,
2400 inst.data.pl_node.payload_index,
2401 ).data.abs_node,
2402 .extended => switch (inst.data.extended.opcode) {
2403 .struct_decl => zir.getStructDecl(resolved_ti.inst).src_node,
2404 .union_decl => zir.getUnionDecl(resolved_ti.inst).src_node,
2405 .enum_decl => zir.getEnumDecl(resolved_ti.inst).src_node,
2406 .opaque_decl => zir.getOpaqueDecl(resolved_ti.inst).src_node,
2407 .reify_enum => zir.extraData(
2408 Zir.Inst.ReifyEnum,
2409 inst.data.extended.operand,
2410 ).data.node,
2411 .reify_struct => zir.extraData(
2412 Zir.Inst.ReifyStruct,
2413 inst.data.extended.operand,
2414 ).data.node,
2415 .reify_union => zir.extraData(
2416 Zir.Inst.ReifyUnion,
2417 inst.data.extended.operand,
2418 ).data.node,
2419 .reify_spirv_type => zir.extraData(
2420 Zir.Inst.ReifySpirvType,
2421 inst.data.extended.operand,
2422 ).data.node,
2423 else => unreachable,
2424 },
2425 else => unreachable,
2426 },
2427 .type_decl_fields => switch (inst.data.extended.opcode) {
2428 .struct_decl => zir.getStructDecl(resolved_ti.inst).fields_baseline_src_node,
2429 .union_decl => zir.getUnionDecl(resolved_ti.inst).fields_baseline_src_node,
2430 .enum_decl => zir.getEnumDecl(resolved_ti.inst).fields_baseline_src_node,
2431 .opaque_decl => unreachable, // opaque type decls do not have fields
2432 else => unreachable,
2433 },
2434 .type_decl_arg => switch (inst.data.extended.opcode) {
2435 .struct_decl => zir.getStructDecl(resolved_ti.inst).arg_baseline_src_node,
2436 .union_decl => zir.getUnionDecl(resolved_ti.inst).arg_baseline_src_node,
2437 .enum_decl => zir.getEnumDecl(resolved_ti.inst).arg_baseline_src_node,
2438 .opaque_decl => unreachable, // opaque type decls do not accept an argument ('opaque(...)')
2439 else => unreachable,
2440 },
2441 },
2442 };
2443 }
2444 };
2445
23522446 pub const Offset = union(enum) {
23532447 /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting
23542448 /// that all code paths which would need to resolve the source location are
23552449 /// unreachable. If you are debugging this tag incorrectly being this value,
23562450 /// look into using reverse-continue with a memory watchpoint to see where the
23572451 /// value is being set to this tag.
2358 /// `base_node_inst` is unused.
2452 /// `baseline` is unused.
23592453 unneeded,
23602454 /// The source location points to a byte offset within a source file,
23612455 /// offset from 0. The source file is determined contextually.
......@@ -2734,50 +2828,11 @@ pub const LazySrcLoc = struct {
27342828 };
27352829
27362830 pub const unneeded: LazySrcLoc = .{
2737 .base_node_inst = undefined,
2831 .baseline = undefined,
27382832 .offset = .unneeded,
27392833 };
27402834
2741 /// Returns `null` if the ZIR instruction has been lost across incremental updates.
2742 pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) ?struct { *File, Ast.Node.Index } {
2743 comptime assert(Zir.inst_tracking_version == 0);
2744
2745 const ip = &zcu.intern_pool;
2746 const file_index, const zir_inst = inst: {
2747 const info = base_node_inst.resolveFull(ip) orelse return null;
2748 break :inst .{ info.file, info.inst };
2749 };
2750 const file = zcu.fileByIndex(file_index);
2751
2752 // If we're relative to .main_struct_inst, we know the ast node is the root and don't need to resolve the ZIR,
2753 // which may not exist e.g. in the case of errors in ZON files.
2754 if (zir_inst == .main_struct_inst) return .{ file, .root };
2755
2756 // Otherwise, make sure ZIR is loaded.
2757 const zir = &file.zir.?;
2758
2759 const inst = zir.instructions.get(@backingInt(zir_inst));
2760 const base_node: Ast.Node.Index = switch (inst.tag) {
2761 .declaration => inst.data.declaration.src_node,
2762 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_node,
2763 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
2764 .extended => switch (inst.data.extended.opcode) {
2765 .struct_decl => zir.getStructDecl(zir_inst).src_node,
2766 .union_decl => zir.getUnionDecl(zir_inst).src_node,
2767 .enum_decl => zir.getEnumDecl(zir_inst).src_node,
2768 .opaque_decl => zir.getOpaqueDecl(zir_inst).src_node,
2769 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,
2770 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
2771 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,
2772 .reify_spirv_type => zir.extraData(Zir.Inst.ReifySpirvType, inst.data.extended.operand).data.node,
2773 else => unreachable,
2774 },
2775 else => unreachable,
2776 };
2777 return .{ file, base_node };
2778 }
2779
2780 /// Resolve the file and AST node of `base_node_inst` to get a resolved `SrcLoc`.
2835 /// Resolve the file and AST node of `baseline` to get a resolved `SrcLoc`.
27812836 /// The resulting `SrcLoc` should only be used ephemerally, as it is not correct across incremental updates.
27822837 pub fn upgrade(lazy: LazySrcLoc, zcu: *Zcu) SrcLoc {
27832838 return lazy.upgradeOrLost(zcu).?;
......@@ -2785,9 +2840,9 @@ pub const LazySrcLoc = struct {
27852840
27862841 /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates.
27872842 pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc {
2788 const file, const base_node: Ast.Node.Index = resolveBaseNode(lazy.base_node_inst, zcu) orelse return null;
2843 const file, const base_node: Ast.Node.Index = lazy.baseline.resolve(zcu) orelse return null;
27892844 return .{
2790 .file_scope = file,
2845 .file_scope = zcu.fileByIndex(file),
27912846 .base_node = base_node,
27922847 .lazy = lazy.offset,
27932848 };
......@@ -4459,7 +4514,7 @@ pub fn setFileRootType(zcu: *Zcu, file_index: File.Index, root_type: InternPool.
44594514pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc {
44604515 const ip = &zcu.intern_pool;
44614516 return .{
4462 .base_node_inst = ip.getNav(nav_index).srcInst(ip),
4517 .baseline = .{ .inst = ip.getNav(nav_index).srcInst(ip), .node = .main },
44634518 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
44644519 };
44654520}
src/Zcu/PerThread.zig+18-6
......@@ -1317,12 +1317,15 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
13171317 .inlining = null,
13181318 .comptime_reason = .{ .reason = .{
13191319 .src = .{
1320 .base_node_inst = comptime_unit.zir_index,
1320 .baseline = .{ .inst = comptime_unit.zir_index, .node = .main },
13211321 .offset = .{ .token_offset = .zero },
13221322 },
13231323 .r = .{ .simple = .comptime_keyword },
13241324 } },
1325 .src_base_inst = comptime_unit.zir_index,
1325 .src_baseline = .{
1326 .inst = comptime_unit.zir_index,
1327 .node = .main,
1328 },
13261329 .type_name_ctx = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.comptime", .{
13271330 parent_ns.name.fmt(ip),
13281331 }, .no_embedded_nulls),
......@@ -1723,7 +1726,10 @@ fn analyzeNavVal(
17231726 .instructions = .empty,
17241727 .inlining = null,
17251728 .comptime_reason = undefined, // set below
1726 .src_base_inst = old_nav.analysis.?.zir_index,
1729 .src_baseline = .{
1730 .inst = old_nav.analysis.?.zir_index,
1731 .node = .main,
1732 },
17271733 .type_name_ctx = old_nav.name,
17281734 .type_fqn_ctx = old_nav.fqn,
17291735 };
......@@ -2093,7 +2099,10 @@ fn analyzeNavType(
20932099 .instructions = .empty,
20942100 .inlining = null,
20952101 .comptime_reason = undefined, // set below
2096 .src_base_inst = old_nav.analysis.?.zir_index,
2102 .src_baseline = .{
2103 .inst = old_nav.analysis.?.zir_index,
2104 .node = .main,
2105 },
20972106 .type_name_ctx = old_nav.name,
20982107 .type_fqn_ctx = old_nav.fqn,
20992108 };
......@@ -3373,7 +3382,10 @@ fn analyzeFuncBodyInner(
33733382 .instructions = .empty,
33743383 .inlining = null,
33753384 .comptime_reason = null,
3376 .src_base_inst = decl_analysis.zir_index,
3385 .src_baseline = .{
3386 .inst = decl_analysis.zir_index,
3387 .node = .main,
3388 },
33773389 .type_name_ctx = func_nav.name,
33783390 .type_fqn_ctx = func_nav.fqn,
33793391 };
......@@ -3511,7 +3523,7 @@ fn analyzeFuncBodyInner(
35113523 // can be emitted here.
35123524 if (sema.fn_ret_ty_ies) |ies| {
35133525 sema.resolveInferredErrorSetPtr(&inner_block, .{
3514 .base_node_inst = inner_block.src_base_inst,
3526 .baseline = inner_block.src_baseline,
35153527 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),
35163528 }, ies) catch |err| switch (err) {
35173529 error.ComptimeReturn => unreachable,
src/crash_report.zig+5-4
......@@ -150,11 +150,12 @@ fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8
150150
151151 var fba: std.heap.FixedBufferAllocator = .init(crash_heap);
152152
153 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse {
154 const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));
153 const file_index, const src_base_node = block.src_baseline.resolve(zcu) orelse {
154 const file = zcu.fileByIndex(block.src_baseline.inst.resolveFile(&zcu.intern_pool));
155155 try stderr.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(comp)});
156156 return;
157157 };
158 const file = zcu.fileByIndex(file_index);
158159
159160 try stderr.print("Analyzing '{f}'\n", .{file.path.fmt(comp)});
160161
......@@ -180,9 +181,9 @@ fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8
180181 var parent = anal.parent;
181182 while (parent) |curr| {
182183 fba.reset();
183 const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));
184 const cur_block_file = zcu.fileByIndex(curr.block.src_baseline.inst.resolveFile(&zcu.intern_pool));
184185 try stderr.print(" in {f}\n", .{cur_block_file.path.fmt(comp)});
185 _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {
186 _, const cur_block_src_base_node = curr.block.src_baseline.resolve(zcu) orelse {
186187 try stderr.writeAll(" > [lost instruction; this should not happen]\n");
187188 parent = curr.parent;
188189 continue;
test/incremental/add_decls_around_bad_field_expr created+40
......@@ -0,0 +1,40 @@
1#exe {
2-Mroot=main.zig
3#}
4
5#write main.zig {
6const pre = {};
7
8thing: @This().does_not_exist,
9
10const post = {};
11
12pub fn main() void {
13 _ = @as(@This(), undefined);
14}
15#}
16#update
17#check errors {
18main.zig:3:15: error: root source file struct 'main' has no member named 'does_not_exist'
19main.zig:1:1: note: struct declared here
20#}
21
22#write main.zig {
23const pre = {};
24const pre_1 = {};
25
26thing: @This().does_not_exist,
27
28const post = {};
29const post_1 = {};
30
31pub fn main() void {
32 _ = @as(@This(), undefined);
33}
34#}
35#update {
36add more decls around error#}
37#check errors {
38main.zig:4:15: error: root source file struct 'main' has no member named 'does_not_exist'
39main.zig:1:1: note: struct declared here
40#}