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 {...@@ -176,7 +176,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
176 var gen_scope: GenZir = .{176 var gen_scope: GenZir = .{
177 .is_comptime = true,177 .is_comptime = true,
178 .parent = &top_scope.base,178 .parent = &top_scope.base,
179 .decl_node_index = .root,179 .src_baseline = .root,
180 .decl_line = 0,180 .decl_line = 0,
181 .astgen = &astgen,181 .astgen = &astgen,
182 .instructions = &gz_instructions,182 .instructions = &gz_instructions,
...@@ -4048,7 +4048,7 @@ fn fnDecl(...@@ -4048,7 +4048,7 @@ fn fnDecl(
40484048
4049 var type_gz: GenZir = .{4049 var type_gz: GenZir = .{
4050 .is_comptime = true,4050 .is_comptime = true,
4051 .decl_node_index = fn_proto.ast.proto_node,4051 .src_baseline = fn_proto.ast.proto_node,
4052 .decl_line = astgen.source_line,4052 .decl_line = astgen.source_line,
4053 .parent = scope,4053 .parent = scope,
4054 .astgen = astgen,4054 .astgen = astgen,
...@@ -4314,7 +4314,7 @@ fn fnDeclInner(...@@ -4314,7 +4314,7 @@ fn fnDeclInner(
43144314
4315 var body_gz: GenZir = .{4315 var body_gz: GenZir = .{
4316 .is_comptime = false,4316 .is_comptime = false,
4317 .decl_node_index = fn_proto.ast.proto_node,4317 .src_baseline = fn_proto.ast.proto_node,
4318 .decl_line = decl_gz.decl_line,4318 .decl_line = decl_gz.decl_line,
4319 .parent = params_scope,4319 .parent = params_scope,
4320 .astgen = astgen,4320 .astgen = astgen,
...@@ -4468,7 +4468,7 @@ fn globalVarDecl(...@@ -4468,7 +4468,7 @@ fn globalVarDecl(
44684468
4469 var type_gz: GenZir = .{4469 var type_gz: GenZir = .{
4470 .parent = scope,4470 .parent = scope,
4471 .decl_node_index = node,4471 .src_baseline = node,
4472 .decl_line = astgen.source_line,4472 .decl_line = astgen.source_line,
4473 .astgen = astgen,4473 .astgen = astgen,
4474 .is_comptime = true,4474 .is_comptime = true,
...@@ -4570,7 +4570,7 @@ fn comptimeDecl(...@@ -4570,7 +4570,7 @@ fn comptimeDecl(
45704570
4571 var comptime_gz: GenZir = .{4571 var comptime_gz: GenZir = .{
4572 .is_comptime = true,4572 .is_comptime = true,
4573 .decl_node_index = node,4573 .src_baseline = node,
4574 .decl_line = astgen.source_line,4574 .decl_line = astgen.source_line,
4575 .parent = scope,4575 .parent = scope,
4576 .astgen = astgen,4576 .astgen = astgen,
...@@ -4634,7 +4634,7 @@ fn testDecl(...@@ -4634,7 +4634,7 @@ fn testDecl(
46344634
4635 var decl_block: GenZir = .{4635 var decl_block: GenZir = .{
4636 .is_comptime = true,4636 .is_comptime = true,
4637 .decl_node_index = node,4637 .src_baseline = node,
4638 .decl_line = astgen.source_line,4638 .decl_line = astgen.source_line,
4639 .parent = scope,4639 .parent = scope,
4640 .astgen = astgen,4640 .astgen = astgen,
...@@ -4732,7 +4732,7 @@ fn testDecl(...@@ -4732,7 +4732,7 @@ fn testDecl(
47324732
4733 var fn_block: GenZir = .{4733 var fn_block: GenZir = .{
4734 .is_comptime = false,4734 .is_comptime = false,
4735 .decl_node_index = node,4735 .src_baseline = node,
4736 .decl_line = decl_block.decl_line,4736 .decl_line = decl_block.decl_line,
4737 .parent = &decl_block.base,4737 .parent = &decl_block.base,
4738 .astgen = astgen,4738 .astgen = astgen,
...@@ -4857,6 +4857,8 @@ fn structDeclInner(...@@ -4857,6 +4857,8 @@ fn structDeclInner(
4857 .src_column = src_column,4857 .src_column = src_column,
4858 .src_node = node,4858 .src_node = node,
4859 .name_strat = name_strat,4859 .name_strat = name_strat,
4860 .arg_baseline_src_node = .none,
4861 .fields_baseline_src_node = .none,
4860 .layout = layout,4862 .layout = layout,
4861 .backing_int_type_body_len = null,4863 .backing_int_type_body_len = null,
4862 .decls_len = 0,4864 .decls_len = 0,
...@@ -4886,7 +4888,7 @@ fn structDeclInner(...@@ -4886,7 +4888,7 @@ fn structDeclInner(
4886 // can refer to decls within the struct itself.4888 // can refer to decls within the struct itself.
4887 var block_scope: GenZir = .{4889 var block_scope: GenZir = .{
4888 .parent = &namespace.base,4890 .parent = &namespace.base,
4889 .decl_node_index = node,4891 .src_baseline = node,
4890 .decl_line = gz.decl_line,4892 .decl_line = gz.decl_line,
4891 .astgen = astgen,4893 .astgen = astgen,
4892 .is_comptime = true,4894 .is_comptime = true,
...@@ -4933,6 +4935,7 @@ fn structDeclInner(...@@ -4933,6 +4935,7 @@ fn structDeclInner(
4933 break :len body_len;4935 break :len body_len;
4934 } else null;4936 } else null;
49354937
4938 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
4936 var next_field_idx: u32 = 0;4939 var next_field_idx: u32 = 0;
4937 for (container_decl.ast.members) |member_node| {4940 for (container_decl.ast.members) |member_node| {
4938 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {4941 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
...@@ -4942,6 +4945,13 @@ fn structDeclInner(...@@ -4942,6 +4945,13 @@ fn structDeclInner(
4942 const field_idx = next_field_idx;4945 const field_idx = next_field_idx;
4943 next_field_idx += 1;4946 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
4945 astgen.src_hasher.update(tree.getNodeSource(member_node));4955 astgen.src_hasher.update(tree.getNodeSource(member_node));
49464956
4947 member.convertToNonTupleLike(astgen.tree);4957 member.convertToNonTupleLike(astgen.tree);
...@@ -5013,6 +5023,8 @@ fn structDeclInner(...@@ -5013,6 +5023,8 @@ fn structDeclInner(
5013 .src_column = src_column,5023 .src_column = src_column,
5014 .src_node = node,5024 .src_node = node,
5015 .name_strat = name_strat,5025 .name_strat = name_strat,
5026 .arg_baseline_src_node = maybe_backing_int_node,
5027 .fields_baseline_src_node = fields_src_baseline,
5016 .layout = layout,5028 .layout = layout,
5017 .backing_int_type_body_len = backing_int_type_body_len,5029 .backing_int_type_body_len = backing_int_type_body_len,
5018 .decls_len = scan_result.decls_len,5030 .decls_len = scan_result.decls_len,
...@@ -5176,7 +5188,7 @@ fn unionDeclInner(...@@ -5176,7 +5188,7 @@ fn unionDeclInner(
5176 // can refer to decls within the union itself.5188 // can refer to decls within the union itself.
5177 var block_scope: GenZir = .{5189 var block_scope: GenZir = .{
5178 .parent = &namespace.base,5190 .parent = &namespace.base,
5179 .decl_node_index = node,5191 .src_baseline = node,
5180 .decl_line = gz.decl_line,5192 .decl_line = gz.decl_line,
5181 .astgen = astgen,5193 .astgen = astgen,
5182 .is_comptime = true,5194 .is_comptime = true,
...@@ -5213,6 +5225,7 @@ fn unionDeclInner(...@@ -5213,6 +5225,7 @@ fn unionDeclInner(
5213 break :len body_len;5225 break :len body_len;
5214 } else null;5226 } else null;
52155227
5228 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
5216 var next_field_idx: u32 = 0;5229 var next_field_idx: u32 = 0;
5217 for (members) |member_node| {5230 for (members) |member_node| {
5218 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {5231 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
...@@ -5222,6 +5235,13 @@ fn unionDeclInner(...@@ -5222,6 +5235,13 @@ fn unionDeclInner(
5222 const field_idx = next_field_idx;5235 const field_idx = next_field_idx;
5223 next_field_idx += 1;5236 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
5225 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));5245 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));
5226 member.convertToNonTupleLike(astgen.tree);5246 member.convertToNonTupleLike(astgen.tree);
5227 if (member.ast.tuple_like) {5247 if (member.ast.tuple_like) {
...@@ -5298,6 +5318,8 @@ fn unionDeclInner(...@@ -5298,6 +5318,8 @@ fn unionDeclInner(
5298 .src_column = src_column,5318 .src_column = src_column,
5299 .src_node = node,5319 .src_node = node,
5300 .name_strat = name_strat,5320 .name_strat = name_strat,
5321 .arg_baseline_src_node = opt_arg_node,
5322 .fields_baseline_src_node = fields_src_baseline,
5301 .kind = switch (layout) {5323 .kind = switch (layout) {
5302 .auto => if (auto_enum_tok == null) l: {5324 .auto => if (auto_enum_tok == null) l: {
5303 break :l if (opt_arg_node == .none) .auto else .tagged_explicit;5325 break :l if (opt_arg_node == .none) .auto else .tagged_explicit;
...@@ -5386,7 +5408,7 @@ fn containerDecl(...@@ -5386,7 +5408,7 @@ fn containerDecl(
5386 // are in scope, so that tag values can refer to decls within the enum itself.5408 // are in scope, so that tag values can refer to decls within the enum itself.
5387 var block_scope: GenZir = .{5409 var block_scope: GenZir = .{
5388 .parent = &namespace.base,5410 .parent = &namespace.base,
5389 .decl_node_index = node,5411 .src_baseline = node,
5390 .decl_line = gz.decl_line,5412 .decl_line = gz.decl_line,
5391 .astgen = astgen,5413 .astgen = astgen,
5392 .is_comptime = true,5414 .is_comptime = true,
...@@ -5424,6 +5446,7 @@ fn containerDecl(...@@ -5424,6 +5446,7 @@ fn containerDecl(
5424 } else null;5446 } else null;
54255447
5426 var next_field_idx: u32 = 0;5448 var next_field_idx: u32 = 0;
5449 var fields_src_baseline: Ast.Node.OptionalIndex = .none;
5427 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;5450 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;
5428 for (container_decl.ast.members) |member_node| {5451 for (container_decl.ast.members) |member_node| {
5429 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {5452 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
...@@ -5466,6 +5489,13 @@ fn containerDecl(...@@ -5466,6 +5489,13 @@ fn containerDecl(
5466 const field_idx = next_field_idx;5489 const field_idx = next_field_idx;
5467 next_field_idx += 1;5490 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
5469 astgen.src_hasher.update(tree.getNodeSource(member_node));5499 astgen.src_hasher.update(tree.getNodeSource(member_node));
54705500
5471 field_names.get(astgen)[field_idx] = @backingInt(try astgen.identAsString(member.ast.main_token));5501 field_names.get(astgen)[field_idx] = @backingInt(try astgen.identAsString(member.ast.main_token));
...@@ -5500,6 +5530,8 @@ fn containerDecl(...@@ -5500,6 +5530,8 @@ fn containerDecl(
5500 .src_column = src_column,5530 .src_column = src_column,
5501 .src_node = node,5531 .src_node = node,
5502 .name_strat = name_strat,5532 .name_strat = name_strat,
5533 .arg_baseline_src_node = container_decl.ast.arg,
5534 .fields_baseline_src_node = fields_src_baseline,
5503 .tag_type_body_len = tag_type_body_len,5535 .tag_type_body_len = tag_type_body_len,
5504 .nonexhaustive = scan_result.has_underscore_field,5536 .nonexhaustive = scan_result.has_underscore_field,
5505 .decls_len = scan_result.decls_len,5537 .decls_len = scan_result.decls_len,
...@@ -5534,7 +5566,7 @@ fn containerDecl(...@@ -5534,7 +5566,7 @@ fn containerDecl(
55345566
5535 var block_scope: GenZir = .{5567 var block_scope: GenZir = .{
5536 .parent = &namespace.base,5568 .parent = &namespace.base,
5537 .decl_node_index = node,5569 .src_baseline = node,
5538 .decl_line = gz.decl_line,5570 .decl_line = gz.decl_line,
5539 .astgen = astgen,5571 .astgen = astgen,
5540 .is_comptime = true,5572 .is_comptime = true,
...@@ -11252,7 +11284,7 @@ const GenZir = struct {...@@ -11252,7 +11284,7 @@ const GenZir = struct {
11252 /// exits from this block should use `break_inline` rather than `break`.11284 /// exits from this block should use `break_inline` rather than `break`.
11253 is_inline: bool = false,11285 is_inline: bool = false,
11254 /// The containing decl AST node.11286 /// The containing decl AST node.
11255 decl_node_index: Ast.Node.Index,11287 src_baseline: Ast.Node.Index,
11256 /// The containing decl line index, absolute.11288 /// The containing decl line index, absolute.
11257 decl_line: u32,11289 decl_line: u32,
11258 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`.11290 /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`.
...@@ -11338,7 +11370,7 @@ const GenZir = struct {...@@ -11338,7 +11370,7 @@ const GenZir = struct {
11338 return .{11370 return .{
11339 .is_comptime = gz.is_comptime,11371 .is_comptime = gz.is_comptime,
11340 .is_typeof = gz.is_typeof,11372 .is_typeof = gz.is_typeof,
11341 .decl_node_index = gz.decl_node_index,11373 .src_baseline = gz.src_baseline,
11342 .decl_line = gz.decl_line,11374 .decl_line = gz.decl_line,
11343 .parent = scope,11375 .parent = scope,
11344 .astgen = gz.astgen,11376 .astgen = gz.astgen,
...@@ -11374,15 +11406,11 @@ const GenZir = struct {...@@ -11374,15 +11406,11 @@ const GenZir = struct {
11374 }11406 }
1137511407
11376 fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) Ast.Node.Offset {11408 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);
11378 }11410 }
1137911411
11380 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) Ast.TokenOffset {11412 fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) Ast.TokenOffset {
11381 return .init(gz.srcToken(), token);11413 return .init(gz.astgen.tree.firstToken(gz.src_baseline), token);
11382 }
11383
11384 fn srcToken(gz: GenZir) Ast.TokenIndex {
11385 return gz.astgen.tree.firstToken(gz.decl_node_index);
11386 }11414 }
1138711415
11388 fn setBreakResultInfo(gz: *GenZir, parent_ri: AstGen.ResultInfo) void {11416 fn setBreakResultInfo(gz: *GenZir, parent_ri: AstGen.ResultInfo) void {
...@@ -12420,6 +12448,8 @@ const GenZir = struct {...@@ -12420,6 +12448,8 @@ const GenZir = struct {
12420 src_column: u32,12448 src_column: u32,
12421 src_node: Ast.Node.Index,12449 src_node: Ast.Node.Index,
12422 name_strat: Zir.Inst.NameStrategy,12450 name_strat: Zir.Inst.NameStrategy,
12451 arg_baseline_src_node: Ast.Node.OptionalIndex,
12452 fields_baseline_src_node: Ast.Node.OptionalIndex,
12423 layout: std.lang.Type.ContainerLayout,12453 layout: std.lang.Type.ContainerLayout,
12424 backing_int_type_body_len: ?u32,12454 backing_int_type_body_len: ?u32,
12425 decls_len: u32,12455 decls_len: u32,
...@@ -12445,7 +12475,9 @@ const GenZir = struct {...@@ -12445,7 +12475,9 @@ const GenZir = struct {
12445 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12475 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1244612476
12447 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".field_names.len +12477 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`
12449 captures_len * 2 + // `capture`, `capture_name`12481 captures_len * 2 + // `capture`, `capture_name`
12450 args.remaining.len);12482 args.remaining.len);
1245112483
...@@ -12462,6 +12494,12 @@ const GenZir = struct {...@@ -12462,6 +12494,12 @@ const GenZir = struct {
12462 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);12494 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12463 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);12495 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12464 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);12496 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 );
12465 if (args.backing_int_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);12503 if (args.backing_int_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
12466 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));12504 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12467 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));12505 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
...@@ -12492,6 +12530,8 @@ const GenZir = struct {...@@ -12492,6 +12530,8 @@ const GenZir = struct {
12492 src_column: u32,12530 src_column: u32,
12493 src_node: Ast.Node.Index,12531 src_node: Ast.Node.Index,
12494 name_strat: Zir.Inst.NameStrategy,12532 name_strat: Zir.Inst.NameStrategy,
12533 arg_baseline_src_node: Ast.Node.OptionalIndex,
12534 fields_baseline_src_node: Ast.Node.OptionalIndex,
12495 kind: Zir.Inst.UnionDecl.Kind,12535 kind: Zir.Inst.UnionDecl.Kind,
12496 arg_type_body_len: ?u32,12536 arg_type_body_len: ?u32,
12497 decls_len: u32,12537 decls_len: u32,
...@@ -12515,7 +12555,9 @@ const GenZir = struct {...@@ -12515,7 +12555,9 @@ const GenZir = struct {
12515 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12555 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1251612556
12517 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".field_names.len +12557 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`
12519 captures_len * 2 + // `capture`, `capture_name`12561 captures_len * 2 + // `capture`, `capture_name`
12520 args.remaining.len);12562 args.remaining.len);
1252112563
...@@ -12532,6 +12574,12 @@ const GenZir = struct {...@@ -12532,6 +12574,12 @@ const GenZir = struct {
12532 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);12574 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12533 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);12575 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12534 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);12576 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 );
12535 if (args.kind.hasArgType()) {12583 if (args.kind.hasArgType()) {
12536 astgen.extra.appendAssumeCapacity(args.arg_type_body_len.?);12584 astgen.extra.appendAssumeCapacity(args.arg_type_body_len.?);
12537 } else {12585 } else {
...@@ -12564,6 +12612,8 @@ const GenZir = struct {...@@ -12564,6 +12612,8 @@ const GenZir = struct {
12564 src_column: u32,12612 src_column: u32,
12565 src_node: Ast.Node.Index,12613 src_node: Ast.Node.Index,
12566 name_strat: Zir.Inst.NameStrategy,12614 name_strat: Zir.Inst.NameStrategy,
12615 arg_baseline_src_node: Ast.Node.OptionalIndex,
12616 fields_baseline_src_node: Ast.Node.OptionalIndex,
12567 tag_type_body_len: ?u32,12617 tag_type_body_len: ?u32,
12568 nonexhaustive: bool,12618 nonexhaustive: bool,
12569 decls_len: u32,12619 decls_len: u32,
...@@ -12586,7 +12636,9 @@ const GenZir = struct {...@@ -12586,7 +12636,9 @@ const GenZir = struct {
12586 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);12636 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1258712637
12588 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".field_names.len +12638 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`
12590 captures_len * 2 + // `capture`, `capture_name`12642 captures_len * 2 + // `capture`, `capture_name`
12591 args.remaining.len);12643 args.remaining.len);
1259212644
...@@ -12603,6 +12655,12 @@ const GenZir = struct {...@@ -12603,6 +12655,12 @@ const GenZir = struct {
12603 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);12655 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12604 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);12656 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12605 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);12657 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 );
12606 if (args.tag_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);12664 if (args.tag_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
12607 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));12665 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12608 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));12666 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
lib/std/zig/Zir.zig+54-13
...@@ -3493,18 +3493,20 @@ pub const Inst = struct {...@@ -3493,18 +3493,20 @@ pub const Inst = struct {
3493 /// 0. captures_len: u32 // if `has_captures_len`3493 /// 0. captures_len: u32 // if `has_captures_len`
3494 /// 1. decls_len: u32, // if `has_decls_len`3494 /// 1. decls_len: u32, // if `has_decls_len`
3495 /// 2. fields_len: u32, // if `has_fields_len`3495 /// 2. fields_len: u32, // if `has_fields_len`
3496 /// 3. backing_int_body_len: u32 // if `has_backing_int`3496 /// 3. arg_baseline_src_node: Ast.Node.Index // if `has_backing_int`
3497 /// 4. capture: Capture // for every `captures_len`3497 /// 4. fields_baseline_src_node: Ast.Node.Index // if `has_fields_len`
3498 /// 5. capture_name: NullTerminatedString // for every `captures_len`3498 /// 5. backing_int_body_len: u32 // if `has_backing_int`
3499 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction3499 /// 6. capture: Capture // for every `captures_len`
3500 /// 7. field_name: NullTerminatedString // for every `fields_len`3500 /// 7. capture_name: NullTerminatedString // for every `captures_len`
3501 /// 8. field_type_body_len: u32 // for every `fields_len`3501 /// 8. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3502 /// 9. field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`3502 /// 9. field_name: NullTerminatedString // for every `fields_len`
3503 /// 10. field_default_body_len: u32 // for every `fields_len` if `any_field_defaults`3503 /// 10. field_type_body_len: u32 // for every `fields_len`
3504 /// 11. field_comptime_bits: u32 // one bit per `fields_len` if `any_comptime_fields`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`
3505 /// // LSB is first field, minimum number of `u32` needed3507 /// // LSB is first field, minimum number of `u32` needed
3506 /// 12. backing_int_body_inst: Inst.Index // for each `backing_int_body_len`3508 /// 14. 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 field3509 /// 15. body_inst: Inst.Index // type body, then align body, then default body, for each field
3508 pub const StructDecl = struct {3510 pub const StructDecl = struct {
3509 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.3511 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
3510 // This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).3512 // 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 {...@@ -5227,12 +5229,12 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
5227 .struct_init_anon,5229 .struct_init_anon,
5228 => {}, // tracked in order, as the owner instructions of anonymous struct types5230 => {}, // tracked in order, as the owner instructions of anonymous struct types
5229 .func, .func_inferred => {5231 .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.
5231 const extra = zir.extraData(Inst.Func, inst.data.pl_node.payload_index);5233 const extra = zir.extraData(Inst.Func, inst.data.pl_node.payload_index);
5232 assert(extra.data.body_len != 0);5234 assert(extra.data.body_len != 0);
5233 },5235 },
5234 .func_fancy => {5236 .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.
5236 const extra = zir.extraData(Inst.FuncFancy, inst.data.pl_node.payload_index);5238 const extra = zir.extraData(Inst.FuncFancy, inst.data.pl_node.payload_index);
5237 assert(extra.data.body_len != 0);5239 assert(extra.data.body_len != 0);
5238 },5240 },
...@@ -5287,6 +5289,14 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe...@@ -5287,6 +5289,14 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe
5287 extra_index += 1;5289 extra_index += 1;
5288 break :blk fields_len;5290 break :blk fields_len;
5289 } else 0;5291 } 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;
5290 const backing_int_type_body_len: u32 = if (small.has_backing_int_type) len: {5300 const backing_int_type_body_len: u32 = if (small.has_backing_int_type) len: {
5291 const body_len = zir.extra[extra_index];5301 const body_len = zir.extra[extra_index];
5292 extra_index += 1;5302 extra_index += 1;
...@@ -5329,6 +5339,8 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe...@@ -5329,6 +5339,8 @@ pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDe
5329 .src_column = extra.data.src_column,5339 .src_column = extra.data.src_column,
5330 .src_node = extra.data.src_node,5340 .src_node = extra.data.src_node,
5331 .name_strategy = small.name_strategy,5341 .name_strategy = small.name_strategy,
5342 .arg_baseline_src_node = arg_baseline_src_node,
5343 .fields_baseline_src_node = fields_baseline_src_node,
5332 .captures = captures,5344 .captures = captures,
5333 .capture_names = capture_names,5345 .capture_names = capture_names,
5334 .decls = decls,5346 .decls = decls,
...@@ -5348,6 +5360,9 @@ pub const UnwrappedStructDecl = struct {...@@ -5348,6 +5360,9 @@ pub const UnwrappedStructDecl = struct {
5348 src_node: Ast.Node.Index,5360 src_node: Ast.Node.Index,
5349 name_strategy: Inst.NameStrategy,5361 name_strategy: Inst.NameStrategy,
53505362
5363 arg_baseline_src_node: Ast.Node.Index,
5364 fields_baseline_src_node: Ast.Node.Index,
5365
5351 captures: []const Inst.Capture,5366 captures: []const Inst.Capture,
5352 capture_names: []const NullTerminatedString,5367 capture_names: []const NullTerminatedString,
53535368
...@@ -5440,6 +5455,14 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl...@@ -5440,6 +5455,14 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl
5440 extra_index += 1;5455 extra_index += 1;
5441 break :blk fields_len;5456 break :blk fields_len;
5442 } else 0;5457 } 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;
5443 const arg_type_body_len: u32 = if (small.kind.hasArgType()) len: {5466 const arg_type_body_len: u32 = if (small.kind.hasArgType()) len: {
5444 const body_len = zir.extra[extra_index];5467 const body_len = zir.extra[extra_index];
5445 extra_index += 1;5468 extra_index += 1;
...@@ -5476,6 +5499,8 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl...@@ -5476,6 +5499,8 @@ pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl
5476 .src_column = extra.data.src_column,5499 .src_column = extra.data.src_column,
5477 .src_node = extra.data.src_node,5500 .src_node = extra.data.src_node,
5478 .name_strategy = small.name_strategy,5501 .name_strategy = small.name_strategy,
5502 .arg_baseline_src_node = arg_baseline_src_node,
5503 .fields_baseline_src_node = fields_baseline_src_node,
5479 .captures = captures,5504 .captures = captures,
5480 .capture_names = capture_names,5505 .capture_names = capture_names,
5481 .decls = decls,5506 .decls = decls,
...@@ -5494,6 +5519,9 @@ pub const UnwrappedUnionDecl = struct {...@@ -5494,6 +5519,9 @@ pub const UnwrappedUnionDecl = struct {
5494 src_node: Ast.Node.Index,5519 src_node: Ast.Node.Index,
5495 name_strategy: Inst.NameStrategy,5520 name_strategy: Inst.NameStrategy,
54965521
5522 arg_baseline_src_node: Ast.Node.Index,
5523 fields_baseline_src_node: Ast.Node.Index,
5524
5497 captures: []const Inst.Capture,5525 captures: []const Inst.Capture,
5498 capture_names: []const NullTerminatedString,5526 capture_names: []const NullTerminatedString,
54995527
...@@ -5576,6 +5604,14 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {...@@ -5576,6 +5604,14 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {
5576 extra_index += 1;5604 extra_index += 1;
5577 break :blk fields_len;5605 break :blk fields_len;
5578 } else 0;5606 } 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;
5579 const tag_type_body_len: u32 = if (small.has_tag_type) len: {5615 const tag_type_body_len: u32 = if (small.has_tag_type) len: {
5580 const body_len = zir.extra[extra_index];5616 const body_len = zir.extra[extra_index];
5581 extra_index += 1;5617 extra_index += 1;
...@@ -5605,6 +5641,8 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {...@@ -5605,6 +5641,8 @@ pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {
5605 .src_column = extra.data.src_column,5641 .src_column = extra.data.src_column,
5606 .src_node = extra.data.src_node,5642 .src_node = extra.data.src_node,
5607 .name_strategy = small.name_strategy,5643 .name_strategy = small.name_strategy,
5644 .arg_baseline_src_node = arg_baseline_src_node,
5645 .fields_baseline_src_node = fields_baseline_src_node,
5608 .captures = captures,5646 .captures = captures,
5609 .capture_names = capture_names,5647 .capture_names = capture_names,
5610 .decls = decls,5648 .decls = decls,
...@@ -5621,6 +5659,9 @@ pub const UnwrappedEnumDecl = struct {...@@ -5621,6 +5659,9 @@ pub const UnwrappedEnumDecl = struct {
5621 src_node: Ast.Node.Index,5659 src_node: Ast.Node.Index,
5622 name_strategy: Inst.NameStrategy,5660 name_strategy: Inst.NameStrategy,
56235661
5662 arg_baseline_src_node: Ast.Node.Index,
5663 fields_baseline_src_node: Ast.Node.Index,
5664
5624 captures: []const Inst.Capture,5665 captures: []const Inst.Capture,
5625 capture_names: []const NullTerminatedString,5666 capture_names: []const NullTerminatedString,
56265667
src/Sema.zig+83-75
...@@ -395,8 +395,8 @@ pub const Block = struct {...@@ -395,8 +395,8 @@ pub const Block = struct {
395 need_debug_scope: ?*bool = null,395 need_debug_scope: ?*bool = null,
396396
397 /// Relative source locations encountered while traversing this block should be397 /// Relative source locations encountered while traversing this block should be
398 /// treated as relative to the AST node of this ZIR instruction.398 /// treated as relative to this baseline AST node.
399 src_base_inst: InternPool.TrackedInst.Index,399 src_baseline: Zcu.LazySrcLoc.Baseline,
400400
401 /// The name of the current "context" for naming namespace types.401 /// The name of the current "context" for naming namespace types.
402 /// The interpretation of this depends on the name strategy in ZIR, but the name402 /// The interpretation of this depends on the name strategy in ZIR, but the name
...@@ -406,10 +406,10 @@ pub const Block = struct {...@@ -406,10 +406,10 @@ pub const Block = struct {
406 type_fqn_ctx: InternPool.NullTerminatedString,406 type_fqn_ctx: InternPool.NullTerminatedString,
407407
408 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.408 /// 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`.
410 pub fn src(block: Block, offset: LazySrcLoc.Offset) LazySrcLoc {410 pub fn src(block: Block, offset: LazySrcLoc.Offset) LazySrcLoc {
411 return .{411 return .{
412 .base_node_inst = block.src_base_inst,412 .baseline = block.src_baseline,
413 .offset = offset,413 .offset = offset,
414 };414 };
415 }415 }
...@@ -530,7 +530,7 @@ pub const Block = struct {...@@ -530,7 +530,7 @@ pub const Block = struct {
530 .float_mode = parent.float_mode,530 .float_mode = parent.float_mode,
531 .error_return_trace_index = parent.error_return_trace_index,531 .error_return_trace_index = parent.error_return_trace_index,
532 .need_debug_scope = parent.need_debug_scope,532 .need_debug_scope = parent.need_debug_scope,
533 .src_base_inst = parent.src_base_inst,533 .src_baseline = parent.src_baseline,
534 .type_name_ctx = parent.type_name_ctx,534 .type_name_ctx = parent.type_name_ctx,
535 .type_fqn_ctx = parent.type_fqn_ctx,535 .type_fqn_ctx = parent.type_fqn_ctx,
536 };536 };
...@@ -1110,14 +1110,17 @@ fn analyzeBodyInner(...@@ -1110,14 +1110,17 @@ fn analyzeBodyInner(
1110 block: *Block,1110 block: *Block,
1111 body: []const Zir.Inst.Index,1111 body: []const Zir.Inst.Index,
1112) CompileError!void {1112) CompileError!void {
1113 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
1114
1115 const pt = sema.pt;1113 const pt = sema.pt;
1116 const zcu = pt.zcu;1114 const zcu = pt.zcu;
1115 const comp = zcu.comp;
1116 const gpa = comp.gpa;
1117
1117 const map = &sema.inst_map;1118 const map = &sema.inst_map;
1118 const tags = sema.code.instructions.items(.tag);1119 const tags = sema.code.instructions.items(.tag);
1119 const datas = sema.code.instructions.items(.data);1120 const datas = sema.code.instructions.items(.data);
11201121
1122 try map.ensureSpaceForInstructions(gpa, body);
1123
1121 var crash_info: crash_report.AnalyzeBody = undefined;1124 var crash_info: crash_report.AnalyzeBody = undefined;
1122 crash_info.push(sema, block, body);1125 crash_info.push(sema, block, body);
1123 defer crash_info.pop();1126 defer crash_info.pop();
...@@ -1130,13 +1133,10 @@ fn analyzeBodyInner(...@@ -1130,13 +1133,10 @@ fn analyzeBodyInner(
1130 crash_info.setBodyIndex(i);1133 crash_info.setBodyIndex(i);
1131 const inst = body[i];1134 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.
1134 if (build_options.enable_logging) {1137 if (build_options.enable_logging) {
1135 std.log.scoped(.sema_zir).debug("sema ZIR {f} %{d}", .{ path: {1138 const path = zcu.namespacePtr(block.namespace).fileScope(zcu).path;
1136 const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool);1139 std.log.scoped(.sema_zir).debug("sema ZIR {f} %{d}", .{ path.fmt(comp), inst });
1137 const file = zcu.fileByIndex(file_index);
1138 break :path file.path.fmt(zcu.comp);
1139 }, inst });
1140 }1140 }
11411141
1142 const air_ref: Air.Inst.Ref = inst: switch (tags[@backingInt(inst)]) {1142 const air_ref: Air.Inst.Ref = inst: switch (tags[@backingInt(inst)]) {
...@@ -1757,7 +1757,6 @@ fn analyzeBodyInner(...@@ -1757,7 +1757,6 @@ fn analyzeBodyInner(
1757 const inst_data = datas[@backingInt(inst)].pl_node;1757 const inst_data = datas[@backingInt(inst)].pl_node;
1758 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);1758 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
1759 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);1759 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1760 const gpa = sema.gpa;
17611760
1762 const BreakResult = struct {1761 const BreakResult = struct {
1763 block_inst: Zir.Inst.Index,1762 block_inst: Zir.Inst.Index,
...@@ -1902,7 +1901,7 @@ fn analyzeBodyInner(...@@ -1902,7 +1901,7 @@ fn analyzeBodyInner(
1902 if (err_union_ty.zigTypeTag(zcu) != .error_union) {1901 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
1903 return sema.failWithOwnedErrorMsg(block, msg: {1902 return sema.failWithOwnedErrorMsg(block, msg: {
1904 const msg = try sema.errMsg(operand_src, "expected error union type, found '{f}'", .{err_union_ty.fmt(pt)});1903 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);
1906 try sema.addDeclaredHereNote(msg, err_union_ty);1905 try sema.addDeclaredHereNote(msg, err_union_ty);
1907 try sema.errNote(operand_src, msg, "consider omitting 'try'", .{});1906 try sema.errNote(operand_src, msg, "consider omitting 'try'", .{});
1908 break :msg msg;1907 break :msg msg;
...@@ -2511,7 +2510,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS...@@ -2511,7 +2510,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
25112510
2512 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;2511 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;
2513 try sema.errNote(.{2512 try sema.errNote(.{
2514 .base_node_inst = struct_type.zir_index,2513 .baseline = .{ .inst = struct_type.zir_index, .node = .main },
2515 .offset = .{ .container_field_value = @intCast(field_index) },2514 .offset = .{ .container_field_value = @intCast(field_index) },
2516 }, msg, "default value set here", .{});2515 }, msg, "default value set here", .{});
2517 break :msg msg;2516 break :msg msg;
...@@ -2633,7 +2632,7 @@ fn addFieldErrNote(...@@ -2633,7 +2632,7 @@ fn addFieldErrNote(
2633 @branchHint(.cold);2632 @branchHint(.cold);
2634 const type_src = container_ty.srcLocOrNull(sema.pt.zcu) orelse return;2633 const type_src = container_ty.srcLocOrNull(sema.pt.zcu) orelse return;
2635 const field_src: LazySrcLoc = .{2634 const field_src: LazySrcLoc = .{
2636 .base_node_inst = type_src.base_node_inst,2635 .baseline = type_src.baseline,
2637 .offset = .{ .container_field_name = @intCast(field_index) },2636 .offset = .{ .container_field_name = @intCast(field_index) },
2638 };2637 };
2639 try sema.errNote(field_src, parent, format, args);2638 try sema.errNote(field_src, parent, format, args);
...@@ -5091,7 +5090,7 @@ fn zirCompileLog(...@@ -5091,7 +5090,7 @@ fn zirCompileLog(
5091 gop.value_ptr.last_line = line_idx;5090 gop.value_ptr.last_line = line_idx;
5092 } else {5091 } else {
5093 gop.value_ptr.* = .{5092 gop.value_ptr.* = .{
5094 .base_node_inst = block.src_base_inst,5093 .baseline = block.src_baseline,
5095 .node_offset = src_node,5094 .node_offset = src_node,
5096 .first_line = line_idx,5095 .first_line = line_idx,
5097 .last_line = line_idx,5096 .last_line = line_idx,
...@@ -5290,7 +5289,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5290,7 +5289,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5290 .runtime_loop = parent_block.runtime_loop,5289 .runtime_loop = parent_block.runtime_loop,
5291 .runtime_index = parent_block.runtime_index,5290 .runtime_index = parent_block.runtime_index,
5292 .error_return_trace_index = parent_block.error_return_trace_index,5291 .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,
5294 .type_name_ctx = parent_block.type_name_ctx,5293 .type_name_ctx = parent_block.type_name_ctx,
5295 .type_fqn_ctx = parent_block.type_fqn_ctx,5294 .type_fqn_ctx = parent_block.type_fqn_ctx,
5296 };5295 };
...@@ -6370,7 +6369,7 @@ fn checkCallArgumentCount(...@@ -6370,7 +6369,7 @@ fn checkCallArgumentCount(
63706369
6371 if (maybe_func_inst) |func_inst| {6370 if (maybe_func_inst) |func_inst| {
6372 try sema.errNote(.{6371 try sema.errNote(.{
6373 .base_node_inst = func_inst,6372 .baseline = .{ .inst = func_inst, .node = .main },
6374 .offset = LazySrcLoc.Offset.nodeOffset(.zero),6373 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
6375 }, msg, "function declared here", .{});6374 }, msg, "function declared here", .{});
6376 }6375 }
...@@ -6528,7 +6527,7 @@ const CallArgsInfo = union(enum) {...@@ -6528,7 +6527,7 @@ const CallArgsInfo = union(enum) {
6528 .r = .{6527 .r = .{
6529 .comptime_param = .{6528 .comptime_param = .{
6530 .comptime_src = if (maybe_func_src_inst) |src_inst| .{6529 .comptime_src = if (maybe_func_src_inst) |src_inst| .{
6531 .base_node_inst = src_inst,6530 .baseline = .{ .inst = src_inst, .node = .main },
6532 .offset = .{ .func_decl_param_comptime = @intCast(arg_index) },6531 .offset = .{ .func_decl_param_comptime = @intCast(arg_index) },
6533 } else unreachable, // should be non-null because the function is generic6532 } else unreachable, // should be non-null because the function is generic
6534 },6533 },
...@@ -6621,7 +6620,7 @@ fn analyzeCall(...@@ -6621,7 +6620,7 @@ fn analyzeCall(
66216620
6622 const maybe_func_inst = try sema.funcDeclSrcInst(callee);6621 const maybe_func_inst = try sema.funcDeclSrcInst(callee);
6623 const func_ret_ty_src: LazySrcLoc = if (maybe_func_inst) |fn_decl_inst| .{6622 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 },
6625 .offset = .{ .node_offset_fn_type_ret_ty = .zero },6624 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
6626 } else func_src;6625 } else func_src;
66276626
...@@ -6650,7 +6649,7 @@ fn analyzeCall(...@@ -6650,7 +6649,7 @@ fn analyzeCall(
6650 );6649 );
6651 errdefer msg.destroy(gpa);6650 errdefer msg.destroy(gpa);
6652 if (maybe_func_inst) |func_inst| try sema.errNote(.{6651 if (maybe_func_inst) |func_inst| try sema.errNote(.{
6653 .base_node_inst = func_inst,6652 .baseline = .{ .inst = func_inst, .node = .main },
6654 .offset = .nodeOffset(.zero),6653 .offset = .nodeOffset(.zero),
6655 }, msg, "function declared here", .{});6654 }, msg, "function declared here", .{});
6656 break :msg msg;6655 break :msg msg;
...@@ -6774,7 +6773,7 @@ fn analyzeCall(...@@ -6774,7 +6773,7 @@ fn analyzeCall(
6774 .namespace = fn_nav.analysis.?.namespace,6773 .namespace = fn_nav.analysis.?.namespace,
6775 .instructions = .empty,6774 .instructions = .empty,
6776 .inlining = &generic_inlining,6775 .inlining = &generic_inlining,
6777 .src_base_inst = fn_nav.analysis.?.zir_index,6776 .src_baseline = .{ .inst = fn_nav.analysis.?.zir_index, .node = .main },
6778 .type_name_ctx = fn_nav.name,6777 .type_name_ctx = fn_nav.name,
6779 .type_fqn_ctx = fn_nav.fqn,6778 .type_fqn_ctx = fn_nav.fqn,
6780 } else undefined;6779 } else undefined;
...@@ -6853,7 +6852,10 @@ fn analyzeCall(...@@ -6853,7 +6852,10 @@ fn analyzeCall(
6853 assert(!declared_comptime); // `analyzeArg` handles this6852 assert(!declared_comptime); // `analyzeArg` handles this
6854 const arg_src = args_info.argSrc(block, arg_idx);6853 const arg_src = args_info.argSrc(block, arg_idx);
6855 const param_ty_src: LazySrcLoc = .{6854 const param_ty_src: LazySrcLoc = .{
6856 .base_node_inst = maybe_func_inst.?, // the function is generic6855 .baseline = .{
6856 .inst = maybe_func_inst.?, // the function is generic
6857 .node = .main,
6858 },
6857 .offset = .{ .func_decl_param_ty = @intCast(arg_idx) },6859 .offset = .{ .func_decl_param_ty = @intCast(arg_idx) },
6858 };6860 };
6859 return sema.failWithNeededComptime(6861 return sema.failWithNeededComptime(
...@@ -7311,7 +7313,7 @@ fn analyzeCall(...@@ -7311,7 +7313,7 @@ fn analyzeCall(
7311 .runtime_cond = block.runtime_cond,7313 .runtime_cond = block.runtime_cond,
7312 .runtime_loop = block.runtime_loop,7314 .runtime_loop = block.runtime_loop,
7313 .runtime_index = block.runtime_index,7315 .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 },
7315 .type_name_ctx = fn_nav.name,7317 .type_name_ctx = fn_nav.name,
7316 .type_fqn_ctx = fn_nav.fqn,7318 .type_fqn_ctx = fn_nav.fqn,
7317 };7319 };
...@@ -8848,7 +8850,7 @@ fn validateResolvedFuncType(...@@ -8848,7 +8850,7 @@ fn validateResolvedFuncType(
8848 const param_ty: Type = .fromInterned(param_ty_ip);8850 const param_ty: Type = .fromInterned(param_ty_ip);
8849 if (!param_ty.validateExtern(.param_ty, zcu)) {8851 if (!param_ty.validateExtern(.param_ty, zcu)) {
8850 const param_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{8852 const param_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8851 .base_node_inst = inst,8853 .baseline = .{ .inst = inst, .node = .main },
8852 .offset = .{ .fn_proto_param = .{8854 .offset = .{ .fn_proto_param = .{
8853 .fn_proto_node_offset = .zero,8855 .fn_proto_node_offset = .zero,
8854 .param_index = @intCast(param_index),8856 .param_index = @intCast(param_index),
...@@ -8868,7 +8870,7 @@ fn validateResolvedFuncType(...@@ -8868,7 +8870,7 @@ fn validateResolvedFuncType(
8868 // Check that the return type is extern-compatible.8870 // Check that the return type is extern-compatible.
8869 if (!ret_ty.validateExtern(.ret_ty, zcu)) {8871 if (!ret_ty.validateExtern(.ret_ty, zcu)) {
8870 const ret_ty_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{8872 const ret_ty_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8871 .base_node_inst = inst,8873 .baseline = .{ .inst = inst, .node = .main },
8872 .offset = .{ .node_offset_fn_type_ret_ty = .zero },8874 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
8873 } else src;8875 } else src;
8874 return sema.failWithOwnedErrorMsg(block, msg: {8876 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -12205,7 +12207,7 @@ fn analyzeSwitchCaptures(...@@ -12205,7 +12207,7 @@ fn analyzeSwitchCaptures(
1220512207
12206 if (has_tag_capture) {12208 if (has_tag_capture) {
12207 const tag_capture_src: LazySrcLoc = .{12209 const tag_capture_src: LazySrcLoc = .{
12208 .base_node_inst = capture_src.base_node_inst,12210 .baseline = capture_src.baseline,
12209 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },12211 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
12210 };12212 };
12211 return sema.failWithInvalidSwitchTagCapture(case_block, tag_capture_src, operand_ty);12213 return sema.failWithInvalidSwitchTagCapture(case_block, tag_capture_src, operand_ty);
...@@ -12307,7 +12309,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(...@@ -12307,7 +12309,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
12307 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);12309 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);
12308 for (item_srcs, 0..) |*item_src, item_i| {12310 for (item_srcs, 0..) |*item_src, item_i| {
12309 item_src.* = .{12311 item_src.* = .{
12310 .base_node_inst = capture_src.base_node_inst,12312 .baseline = capture_src.baseline,
12311 .offset = .{ .switch_case_item = .{12313 .offset = .{ .switch_case_item = .{
12312 .switch_node_offset = switch_node_offset,12314 .switch_node_offset = switch_node_offset,
12313 .case_idx = capture_src.offset.switch_capture.case_idx,12315 .case_idx = capture_src.offset.switch_capture.case_idx,
...@@ -12347,7 +12349,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(...@@ -12347,7 +12349,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
12347 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);12349 const item_srcs = try sema.arena.alloc(?LazySrcLoc, item_refs.len);
12348 for (item_srcs, 0..) |*item_src, item_i| {12350 for (item_srcs, 0..) |*item_src, item_i| {
12349 item_src.* = .{12351 item_src.* = .{
12350 .base_node_inst = capture_src.base_node_inst,12352 .baseline = capture_src.baseline,
12351 .offset = .{ .switch_case_item = .{12353 .offset = .{ .switch_case_item = .{
12352 .switch_node_offset = switch_node_offset,12354 .switch_node_offset = switch_node_offset,
12353 .case_idx = capture_src.offset.switch_capture.case_idx,12355 .case_idx = capture_src.offset.switch_capture.case_idx,
...@@ -12429,7 +12431,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(...@@ -12429,7 +12431,7 @@ fn analyzeSwitchPayloadCaptureTaggedUnion(
12429 defer coerce_block.instructions.deinit(sema.gpa);12431 defer coerce_block.instructions.deinit(sema.gpa);
1243012432
12431 const case_src: LazySrcLoc = .{12433 const case_src: LazySrcLoc = .{
12432 .base_node_inst = capture_src.base_node_inst,12434 .baseline = capture_src.baseline,
12433 .offset = .{ .switch_case_item = .{12435 .offset = .{ .switch_case_item = .{
12434 .switch_node_offset = switch_node_offset,12436 .switch_node_offset = switch_node_offset,
12435 .case_idx = capture_src.offset.switch_capture.case_idx,12437 .case_idx = capture_src.offset.switch_capture.case_idx,
...@@ -15907,10 +15909,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -15907,10 +15909,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
15907 const msg = msg: {15909 const msg = msg: {
15908 const name = name: {15910 const name = name: {
15909 // TODO: we should probably store this name in the ZIR to avoid this complexity.15911 // 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).?;15912 const file, const src_base_node = block.src_baseline.resolve(zcu).?;
15911 const tree = file.getTree(zcu) catch |err| {15913 const tree = zcu.fileByIndex(file).getTree(zcu) catch |err| {
15912 // In this case we emit a warning + a less precise source location.15914 // 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 });
15914 break :name null;15916 break :name null;
15915 };15917 };
15916 const node = src_node.toAbsolute(src_base_node);15918 const node = src_node.toAbsolute(src_base_node);
...@@ -15933,10 +15935,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -15933,10 +15935,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
15933 if (!block.is_typeof and !block.isComptime() and sema.func_index != .none) {15935 if (!block.is_typeof and !block.isComptime() and sema.func_index != .none) {
15934 const msg = msg: {15936 const msg = msg: {
15935 const name = name: {15937 const name = name: {
15936 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?;15938 const file, const src_base_node = block.src_baseline.resolve(zcu).?;
15937 const tree = file.getTree(zcu) catch |err| {15939 const tree = zcu.fileByIndex(file).getTree(zcu) catch |err| {
15938 // In this case we emit a warning + a less precise source location.15940 // 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 });
15940 break :name null;15942 break :name null;
15941 };15943 };
15942 const node = src_node.toAbsolute(src_base_node);15944 const node = src_node.toAbsolute(src_base_node);
...@@ -17313,7 +17315,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -17313,7 +17315,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
17313 .is_typeof = true,17315 .is_typeof = true,
17314 .want_safety = false,17316 .want_safety = false,
17315 .error_return_trace_index = block.error_return_trace_index,17317 .error_return_trace_index = block.error_return_trace_index,
17316 .src_base_inst = block.src_base_inst,17318 .src_baseline = block.src_baseline,
17317 .type_name_ctx = block.type_name_ctx,17319 .type_name_ctx = block.type_name_ctx,
17318 .type_fqn_ctx = block.type_fqn_ctx,17320 .type_fqn_ctx = block.type_fqn_ctx,
17319 };17321 };
...@@ -17380,7 +17382,7 @@ fn zirTypeofPeer(...@@ -17380,7 +17382,7 @@ fn zirTypeofPeer(
17380 .runtime_cond = block.runtime_cond,17382 .runtime_cond = block.runtime_cond,
17381 .runtime_loop = block.runtime_loop,17383 .runtime_loop = block.runtime_loop,
17382 .runtime_index = block.runtime_index,17384 .runtime_index = block.runtime_index,
17383 .src_base_inst = block.src_base_inst,17385 .src_baseline = block.src_baseline,
17384 .type_name_ctx = block.type_name_ctx,17386 .type_name_ctx = block.type_name_ctx,
17385 .type_fqn_ctx = block.type_fqn_ctx,17387 .type_fqn_ctx = block.type_fqn_ctx,
17386 };17388 };
...@@ -17940,7 +17942,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label...@@ -17940,7 +17942,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
17940 .label = &labeled_block.label,17942 .label = &labeled_block.label,
17941 .inlining = block.inlining,17943 .inlining = block.inlining,
17942 .comptime_reason = block.comptime_reason,17944 .comptime_reason = block.comptime_reason,
17943 .src_base_inst = block.src_base_inst,17945 .src_baseline = block.src_baseline,
17944 .type_name_ctx = block.type_name_ctx,17946 .type_name_ctx = block.type_name_ctx,
17945 .type_fqn_ctx = block.type_fqn_ctx,17947 .type_fqn_ctx = block.type_fqn_ctx,
17946 },17948 },
...@@ -20180,40 +20182,40 @@ fn zirReifyStruct(...@@ -20180,40 +20182,40 @@ fn zirReifyStruct(
20180 const tracked_inst = try block.trackZir(inst);20182 const tracked_inst = try block.trackZir(inst);
2018120183
20182 const src: LazySrcLoc = .{20184 const src: LazySrcLoc = .{
20183 .base_node_inst = tracked_inst,20185 .baseline = .{ .inst = tracked_inst, .node = .main },
20184 .offset = .nodeOffset(.zero),20186 .offset = .nodeOffset(.zero),
20185 };20187 };
2018620188
20187 const layout_src: LazySrcLoc = .{20189 const layout_src: LazySrcLoc = .{
20188 .base_node_inst = tracked_inst,20190 .baseline = .{ .inst = tracked_inst, .node = .main },
20189 .offset = .{ .node_offset_builtin_call_arg = .{20191 .offset = .{ .node_offset_builtin_call_arg = .{
20190 .builtin_call_node = .zero,20192 .builtin_call_node = .zero,
20191 .arg_index = 0,20193 .arg_index = 0,
20192 } },20194 } },
20193 };20195 };
20194 const backing_ty_src: LazySrcLoc = .{20196 const backing_ty_src: LazySrcLoc = .{
20195 .base_node_inst = tracked_inst,20197 .baseline = .{ .inst = tracked_inst, .node = .main },
20196 .offset = .{ .node_offset_builtin_call_arg = .{20198 .offset = .{ .node_offset_builtin_call_arg = .{
20197 .builtin_call_node = .zero,20199 .builtin_call_node = .zero,
20198 .arg_index = 1,20200 .arg_index = 1,
20199 } },20201 } },
20200 };20202 };
20201 const field_names_src: LazySrcLoc = .{20203 const field_names_src: LazySrcLoc = .{
20202 .base_node_inst = tracked_inst,20204 .baseline = .{ .inst = tracked_inst, .node = .main },
20203 .offset = .{ .node_offset_builtin_call_arg = .{20205 .offset = .{ .node_offset_builtin_call_arg = .{
20204 .builtin_call_node = .zero,20206 .builtin_call_node = .zero,
20205 .arg_index = 2,20207 .arg_index = 2,
20206 } },20208 } },
20207 };20209 };
20208 const field_types_src: LazySrcLoc = .{20210 const field_types_src: LazySrcLoc = .{
20209 .base_node_inst = tracked_inst,20211 .baseline = .{ .inst = tracked_inst, .node = .main },
20210 .offset = .{ .node_offset_builtin_call_arg = .{20212 .offset = .{ .node_offset_builtin_call_arg = .{
20211 .builtin_call_node = .zero,20213 .builtin_call_node = .zero,
20212 .arg_index = 3,20214 .arg_index = 3,
20213 } },20215 } },
20214 };20216 };
20215 const field_attrs_src: LazySrcLoc = .{20217 const field_attrs_src: LazySrcLoc = .{
20216 .base_node_inst = tracked_inst,20218 .baseline = .{ .inst = tracked_inst, .node = .main },
20217 .offset = .{ .node_offset_builtin_call_arg = .{20219 .offset = .{ .node_offset_builtin_call_arg = .{
20218 .builtin_call_node = .zero,20220 .builtin_call_node = .zero,
20219 .arg_index = 4,20221 .arg_index = 4,
...@@ -20460,40 +20462,40 @@ fn zirReifyUnion(...@@ -20460,40 +20462,40 @@ fn zirReifyUnion(
20460 const extra = sema.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;20462 const extra = sema.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;
20461 const tracked_inst = try block.trackZir(inst);20463 const tracked_inst = try block.trackZir(inst);
20462 const src: LazySrcLoc = .{20464 const src: LazySrcLoc = .{
20463 .base_node_inst = tracked_inst,20465 .baseline = .{ .inst = tracked_inst, .node = .main },
20464 .offset = .nodeOffset(.zero),20466 .offset = .nodeOffset(.zero),
20465 };20467 };
2046620468
20467 const layout_src: LazySrcLoc = .{20469 const layout_src: LazySrcLoc = .{
20468 .base_node_inst = tracked_inst,20470 .baseline = .{ .inst = tracked_inst, .node = .main },
20469 .offset = .{ .node_offset_builtin_call_arg = .{20471 .offset = .{ .node_offset_builtin_call_arg = .{
20470 .builtin_call_node = .zero,20472 .builtin_call_node = .zero,
20471 .arg_index = 0,20473 .arg_index = 0,
20472 } },20474 } },
20473 };20475 };
20474 const arg_ty_src: LazySrcLoc = .{20476 const arg_ty_src: LazySrcLoc = .{
20475 .base_node_inst = tracked_inst,20477 .baseline = .{ .inst = tracked_inst, .node = .main },
20476 .offset = .{ .node_offset_builtin_call_arg = .{20478 .offset = .{ .node_offset_builtin_call_arg = .{
20477 .builtin_call_node = .zero,20479 .builtin_call_node = .zero,
20478 .arg_index = 1,20480 .arg_index = 1,
20479 } },20481 } },
20480 };20482 };
20481 const field_names_src: LazySrcLoc = .{20483 const field_names_src: LazySrcLoc = .{
20482 .base_node_inst = tracked_inst,20484 .baseline = .{ .inst = tracked_inst, .node = .main },
20483 .offset = .{ .node_offset_builtin_call_arg = .{20485 .offset = .{ .node_offset_builtin_call_arg = .{
20484 .builtin_call_node = .zero,20486 .builtin_call_node = .zero,
20485 .arg_index = 2,20487 .arg_index = 2,
20486 } },20488 } },
20487 };20489 };
20488 const field_types_src: LazySrcLoc = .{20490 const field_types_src: LazySrcLoc = .{
20489 .base_node_inst = tracked_inst,20491 .baseline = .{ .inst = tracked_inst, .node = .main },
20490 .offset = .{ .node_offset_builtin_call_arg = .{20492 .offset = .{ .node_offset_builtin_call_arg = .{
20491 .builtin_call_node = .zero,20493 .builtin_call_node = .zero,
20492 .arg_index = 3,20494 .arg_index = 3,
20493 } },20495 } },
20494 };20496 };
20495 const field_attrs_src: LazySrcLoc = .{20497 const field_attrs_src: LazySrcLoc = .{
20496 .base_node_inst = tracked_inst,20498 .baseline = .{ .inst = tracked_inst, .node = .main },
20497 .offset = .{ .node_offset_builtin_call_arg = .{20499 .offset = .{ .node_offset_builtin_call_arg = .{
20498 .builtin_call_node = .zero,20500 .builtin_call_node = .zero,
20499 .arg_index = 4,20501 .arg_index = 4,
...@@ -20681,33 +20683,33 @@ fn zirReifyEnum(...@@ -20681,33 +20683,33 @@ fn zirReifyEnum(
20681 const extra = sema.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;20683 const extra = sema.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;
20682 const tracked_inst = try block.trackZir(inst);20684 const tracked_inst = try block.trackZir(inst);
20683 const src: LazySrcLoc = .{20685 const src: LazySrcLoc = .{
20684 .base_node_inst = tracked_inst,20686 .baseline = .{ .inst = tracked_inst, .node = .main },
20685 .offset = .nodeOffset(.zero),20687 .offset = .nodeOffset(.zero),
20686 };20688 };
2068720689
20688 const tag_ty_src: LazySrcLoc = .{20690 const tag_ty_src: LazySrcLoc = .{
20689 .base_node_inst = tracked_inst,20691 .baseline = .{ .inst = tracked_inst, .node = .main },
20690 .offset = .{ .node_offset_builtin_call_arg = .{20692 .offset = .{ .node_offset_builtin_call_arg = .{
20691 .builtin_call_node = .zero,20693 .builtin_call_node = .zero,
20692 .arg_index = 0,20694 .arg_index = 0,
20693 } },20695 } },
20694 };20696 };
20695 const mode_src: LazySrcLoc = .{20697 const mode_src: LazySrcLoc = .{
20696 .base_node_inst = tracked_inst,20698 .baseline = .{ .inst = tracked_inst, .node = .main },
20697 .offset = .{ .node_offset_builtin_call_arg = .{20699 .offset = .{ .node_offset_builtin_call_arg = .{
20698 .builtin_call_node = .zero,20700 .builtin_call_node = .zero,
20699 .arg_index = 1,20701 .arg_index = 1,
20700 } },20702 } },
20701 };20703 };
20702 const field_names_src: LazySrcLoc = .{20704 const field_names_src: LazySrcLoc = .{
20703 .base_node_inst = tracked_inst,20705 .baseline = .{ .inst = tracked_inst, .node = .main },
20704 .offset = .{ .node_offset_builtin_call_arg = .{20706 .offset = .{ .node_offset_builtin_call_arg = .{
20705 .builtin_call_node = .zero,20707 .builtin_call_node = .zero,
20706 .arg_index = 2,20708 .arg_index = 2,
20707 } },20709 } },
20708 };20710 };
20709 const field_values_src: LazySrcLoc = .{20711 const field_values_src: LazySrcLoc = .{
20710 .base_node_inst = tracked_inst,20712 .baseline = .{ .inst = tracked_inst, .node = .main },
20711 .offset = .{ .node_offset_builtin_call_arg = .{20713 .offset = .{ .node_offset_builtin_call_arg = .{
20712 .builtin_call_node = .zero,20714 .builtin_call_node = .zero,
20713 .arg_index = 3,20715 .arg_index = 3,
...@@ -20833,11 +20835,11 @@ fn zirReifySpirvType(...@@ -20833,11 +20835,11 @@ fn zirReifySpirvType(
20833 const extra = sema.code.extraData(Zir.Inst.ReifySpirvType, extended.operand).data;20835 const extra = sema.code.extraData(Zir.Inst.ReifySpirvType, extended.operand).data;
20834 const tracked_inst = try block.trackZir(inst);20836 const tracked_inst = try block.trackZir(inst);
20835 const src: LazySrcLoc = .{20837 const src: LazySrcLoc = .{
20836 .base_node_inst = tracked_inst,20838 .baseline = .{ .inst = tracked_inst, .node = .main },
20837 .offset = .nodeOffset(.zero),20839 .offset = .nodeOffset(.zero),
20838 };20840 };
20839 const operand_src: LazySrcLoc = .{20841 const operand_src: LazySrcLoc = .{
20840 .base_node_inst = tracked_inst,20842 .baseline = .{ .inst = tracked_inst, .node = .main },
20841 .offset = .{ .node_offset_builtin_call_arg = .{20843 .offset = .{ .node_offset_builtin_call_arg = .{
20842 .builtin_call_node = .zero,20844 .builtin_call_node = .zero,
20843 .arg_index = 0,20845 .arg_index = 0,
...@@ -25675,7 +25677,7 @@ fn explainWhyTypeIsComptime(...@@ -25675,7 +25677,7 @@ fn explainWhyTypeIsComptime(
25675 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);25677 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
25676 if (!field_ty.comptimeOnly(zcu)) continue;25678 if (!field_ty.comptimeOnly(zcu)) continue;
25677 const field_src: LazySrcLoc = .{25679 const field_src: LazySrcLoc = .{
25678 .base_node_inst = struct_type.zir_index,25680 .baseline = .{ .inst = struct_type.zir_index, .node = .main },
25679 .offset = .{ .container_field_type = @intCast(i) },25681 .offset = .{ .container_field_type = @intCast(i) },
25680 };25682 };
25681 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});25683 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});
...@@ -25700,7 +25702,7 @@ fn explainWhyTypeIsComptime(...@@ -25700,7 +25702,7 @@ fn explainWhyTypeIsComptime(
25700 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);25702 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);
25701 if (!field_ty.comptimeOnly(zcu)) continue;25703 if (!field_ty.comptimeOnly(zcu)) continue;
25702 const field_src: LazySrcLoc = .{25704 const field_src: LazySrcLoc = .{
25703 .base_node_inst = union_obj.zir_index,25705 .baseline = .{ .inst = union_obj.zir_index, .node = .main },
25704 .offset = .{ .container_field_type = @intCast(i) },25706 .offset = .{ .container_field_type = @intCast(i) },
25705 };25707 };
25706 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});25708 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
...@@ -25914,7 +25916,7 @@ fn addSafetyCheck(...@@ -25914,7 +25916,7 @@ fn addSafetyCheck(
25914 .instructions = .empty,25916 .instructions = .empty,
25915 .inlining = parent_block.inlining,25917 .inlining = parent_block.inlining,
25916 .comptime_reason = null,25918 .comptime_reason = null,
25917 .src_base_inst = parent_block.src_base_inst,25919 .src_baseline = parent_block.src_baseline,
25918 .type_name_ctx = parent_block.type_name_ctx,25920 .type_name_ctx = parent_block.type_name_ctx,
25919 .type_fqn_ctx = parent_block.type_fqn_ctx,25921 .type_fqn_ctx = parent_block.type_fqn_ctx,
25920 };25922 };
...@@ -26009,7 +26011,7 @@ fn addSafetyCheckUnwrapError(...@@ -26009,7 +26011,7 @@ fn addSafetyCheckUnwrapError(
26009 .instructions = .empty,26011 .instructions = .empty,
26010 .inlining = parent_block.inlining,26012 .inlining = parent_block.inlining,
26011 .comptime_reason = null,26013 .comptime_reason = null,
26012 .src_base_inst = parent_block.src_base_inst,26014 .src_baseline = parent_block.src_baseline,
26013 .type_name_ctx = parent_block.type_name_ctx,26015 .type_name_ctx = parent_block.type_name_ctx,
26014 .type_fqn_ctx = parent_block.type_fqn_ctx,26016 .type_fqn_ctx = parent_block.type_fqn_ctx,
26015 };26017 };
...@@ -26133,7 +26135,7 @@ fn addSafetyCheckCall(...@@ -26133,7 +26135,7 @@ fn addSafetyCheckCall(
26133 .instructions = .empty,26135 .instructions = .empty,
26134 .inlining = parent_block.inlining,26136 .inlining = parent_block.inlining,
26135 .comptime_reason = null,26137 .comptime_reason = null,
26136 .src_base_inst = parent_block.src_base_inst,26138 .src_baseline = parent_block.src_baseline,
26137 .type_name_ctx = parent_block.type_name_ctx,26139 .type_name_ctx = parent_block.type_name_ctx,
26138 .type_fqn_ctx = parent_block.type_fqn_ctx,26140 .type_fqn_ctx = parent_block.type_fqn_ctx,
26139 };26141 };
...@@ -27966,7 +27968,7 @@ const CoerceOpts = struct {...@@ -27966,7 +27968,7 @@ const CoerceOpts = struct {
27966 if (info.func_inst == .none) return null;27968 if (info.func_inst == .none) return null;
27967 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;27969 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;
27968 return .{27970 return .{
27969 .base_node_inst = func_inst,27971 .baseline = .{ .inst = func_inst, .node = .main },
27970 .offset = .{ .fn_proto_param_type = .{27972 .offset = .{ .fn_proto_param_type = .{
27971 .fn_proto_node_offset = .zero,27973 .fn_proto_node_offset = .zero,
27972 .param_index = info.param_i,27974 .param_index = info.param_i,
...@@ -28684,7 +28686,10 @@ fn coerceExtra(...@@ -28684,7 +28686,10 @@ fn coerceExtra(
28684 errdefer msg.destroy(sema.gpa);28686 errdefer msg.destroy(sema.gpa);
2868528687
28686 const ret_ty_src: LazySrcLoc = .{28688 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 },
28688 .offset = .{ .node_offset_fn_type_ret_ty = .zero },28693 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
28689 };28694 };
28690 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});28695 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
...@@ -28724,7 +28729,10 @@ fn coerceExtra(...@@ -28724,7 +28729,10 @@ fn coerceExtra(
28724 !zcu.test_functions.contains(zcu.funcInfo(sema.func_index).owner_nav))28729 !zcu.test_functions.contains(zcu.funcInfo(sema.func_index).owner_nav))
28725 {28730 {
28726 const ret_ty_src: LazySrcLoc = .{28731 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 },
28728 .offset = .{ .node_offset_fn_type_ret_ty = .zero },28736 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
28729 };28737 };
28730 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {28738 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
...@@ -35008,7 +35016,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C...@@ -35008,7 +35016,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
35008 .instructions = .empty,35016 .instructions = .empty,
35009 .inlining = null,35017 .inlining = null,
35010 .comptime_reason = null,35018 .comptime_reason = null,
35011 .src_base_inst = std_type.typeDeclInst(zcu).?,35019 .src_baseline = .{ .inst = std_type.typeDeclInst(zcu).?, .node = .main },
35012 .type_name_ctx = .empty,35020 .type_name_ctx = .empty,
35013 .type_fqn_ctx = .empty,35021 .type_fqn_ctx = .empty,
35014 };35022 };
...@@ -35023,7 +35031,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C...@@ -35023,7 +35031,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
35023 };35031 };
35024 const uncoerced_val = try sema.analyzeNavVal(&block, std_src, nav);35032 const uncoerced_val = try sema.analyzeNavVal(&block, std_src, nav);
35025 const decl_src: LazySrcLoc = .{35033 const decl_src: LazySrcLoc = .{
35026 .base_node_inst = ip.getNav(nav).srcInst(ip),35034 .baseline = .{ .inst = ip.getNav(nav).srcInst(ip), .node = .main },
35027 .offset = .nodeOffset(.zero),35035 .offset = .nodeOffset(.zero),
35028 };35036 };
35029 break :ty try sema.analyzeAsType(&block, decl_src, .std_lang_decl, uncoerced_val);35037 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...@@ -35053,7 +35061,7 @@ pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) C
35053 const uncoerced_val = try sema.analyzeNavVal(&block, parent_ty_src, nav);35061 const uncoerced_val = try sema.analyzeNavVal(&block, parent_ty_src, nav);
3505435062
35055 const decl_src: LazySrcLoc = .{35063 const decl_src: LazySrcLoc = .{
35056 .base_node_inst = ip.getNav(nav).srcInst(ip),35064 .baseline = .{ .inst = ip.getNav(nav).srcInst(ip), .node = .main },
35057 .offset = .nodeOffset(.zero),35065 .offset = .nodeOffset(.zero),
35058 };35066 };
3505935067
...@@ -35343,7 +35351,7 @@ fn zirStructDecl(...@@ -35343,7 +35351,7 @@ fn zirStructDecl(
35343 const tracked_inst = try block.trackZir(inst);35351 const tracked_inst = try block.trackZir(inst);
3534435352
35345 const src: LazySrcLoc = .{35353 const src: LazySrcLoc = .{
35346 .base_node_inst = tracked_inst,35354 .baseline = .{ .inst = tracked_inst, .node = .main },
35347 .offset = .nodeOffset(.zero),35355 .offset = .nodeOffset(.zero),
35348 };35356 };
3534935357
...@@ -35401,7 +35409,7 @@ fn zirUnionDecl(...@@ -35401,7 +35409,7 @@ fn zirUnionDecl(
35401 const tracked_inst = try block.trackZir(inst);35409 const tracked_inst = try block.trackZir(inst);
3540235410
35403 const src: LazySrcLoc = .{35411 const src: LazySrcLoc = .{
35404 .base_node_inst = tracked_inst,35412 .baseline = .{ .inst = tracked_inst, .node = .main },
35405 .offset = .nodeOffset(.zero),35413 .offset = .nodeOffset(.zero),
35406 };35414 };
3540735415
...@@ -35477,7 +35485,7 @@ fn zirEnumDecl(...@@ -35477,7 +35485,7 @@ fn zirEnumDecl(
35477 const tracked_inst = try block.trackZir(inst);35485 const tracked_inst = try block.trackZir(inst);
3547835486
35479 const src: LazySrcLoc = .{35487 const src: LazySrcLoc = .{
35480 .base_node_inst = tracked_inst,35488 .baseline = .{ .inst = tracked_inst, .node = .main },
35481 .offset = .nodeOffset(.zero),35489 .offset = .nodeOffset(.zero),
35482 };35490 };
3548335491
...@@ -35532,7 +35540,7 @@ fn zirOpaqueDecl(...@@ -35532,7 +35540,7 @@ fn zirOpaqueDecl(
35532 const tracked_inst = try block.trackZir(inst);35540 const tracked_inst = try block.trackZir(inst);
3553335541
35534 const src: LazySrcLoc = .{35542 const src: LazySrcLoc = .{
35535 .base_node_inst = tracked_inst,35543 .baseline = .{ .inst = tracked_inst, .node = .main },
35536 .offset = .nodeOffset(.zero),35544 .offset = .nodeOffset(.zero),
35537 };35545 };
3553835546
src/Sema/LowerZon.zig+52-54
...@@ -22,11 +22,11 @@ const Zoir = std.zig.Zoir;...@@ -22,11 +22,11 @@ const Zoir = std.zig.Zoir;
22const LowerZon = @This();22const LowerZon = @This();
2323
24sema: *Sema,24sema: *Sema,
25file: *File,
26file_index: Zcu.File.Index,
27import_loc: LazySrcLoc,
28block: *Sema.Block,25block: *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
31/// Lowers the given file as ZON.31/// Lowers the given file as ZON.
32pub fn run(32pub fn run(
...@@ -34,28 +34,26 @@ pub fn run(...@@ -34,28 +34,26 @@ pub fn run(
34 file: *File,34 file: *File,
35 file_index: Zcu.File.Index,35 file_index: Zcu.File.Index,
36 res_ty_interned: InternPool.Index,36 res_ty_interned: InternPool.Index,
37 import_loc: LazySrcLoc,37 import_src: LazySrcLoc,
38 block: *Sema.Block,38 block: *Sema.Block,
39) CompileError!InternPool.Index {39) CompileError!InternPool.Index {
40 const pt = sema.pt;40 const pt = sema.pt;
41 const comp = pt.zcu.comp;41 const zcu = pt.zcu;
42 const comp = zcu.comp;
42 const gpa = comp.gpa;43 const gpa = comp.gpa;
43 const io = comp.io;44 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
50 var lower_zon: LowerZon = .{46 var lower_zon: LowerZon = .{
51 .sema = sema,47 .sema = sema,
52 .file = file,
53 .file_index = file_index,
54 .import_loc = import_loc,
55 .block = block,48 .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,
57 };56 };
58
59 if (res_ty_interned == .none) {57 if (res_ty_interned == .none) {
60 return lower_zon.lowerExprAnonResTy(.root);58 return lower_zon.lowerExprAnonResTy(.root);
61 } else {59 } else {
...@@ -71,7 +69,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -71,7 +69,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
71 const gpa = comp.gpa;69 const gpa = comp.gpa;
72 const io = comp.io;70 const io = comp.io;
73 const ip = &pt.zcu.intern_pool;71 const ip = &pt.zcu.intern_pool;
74 switch (node.get(self.file.zoir.?)) {72 switch (node.get(self.zoir.*)) {
75 .true => return .bool_true,73 .true => return .bool_true,
76 .false => return .bool_false,74 .false => return .bool_false,
77 .null => return .null_value,75 .null => return .null_value,
...@@ -101,7 +99,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -101,7 +99,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
101 gpa,99 gpa,
102 io,100 io,
103 pt.tid,101 pt.tid,
104 val.get(self.file.zoir.?),102 val.get(self.zoir.*),
105 .no_embedded_nulls,103 .no_embedded_nulls,
106 ),104 ),
107 }),105 }),
...@@ -130,7 +128,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -130,7 +128,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
130 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));128 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
131 }129 }
132 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{130 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,
134 .type_hash = hash: {132 .type_hash = hash: {
135 var hasher: std.hash.Wyhash = .init(0);133 var hasher: std.hash.Wyhash = .init(0);
136 hasher.update(std.mem.asBytes(&node));134 hasher.update(std.mem.asBytes(&node));
...@@ -150,7 +148,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -150,7 +148,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
150 errdefer wip.cancel(ip, pt.tid);148 errdefer wip.cancel(ip, pt.tid);
151 const block = self.block;149 const block = self.block;
152 const zcu = pt.zcu;150 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
155 // Reified structs have field information populated immediately.153 // Reified structs have field information populated immediately.
156 @memcpy(wip.field_values.get(ip), elems);154 @memcpy(wip.field_values.get(ip), elems);
...@@ -174,7 +172,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter...@@ -174,7 +172,7 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
174 gpa,172 gpa,
175 io,173 io,
176 pt.tid,174 pt.tid,
177 zoir_name.get(self.file.zoir.?),175 zoir_name.get(self.zoir.*),
178 .no_embedded_nulls,176 .no_embedded_nulls,
179 );177 );
180 field_ty.* = ip.typeOf(field_val);178 field_ty.* = ip.typeOf(field_val);
...@@ -289,7 +287,7 @@ fn checkTypeInner(...@@ -289,7 +287,7 @@ fn checkTypeInner(
289 } else {287 } else {
290 const gop = try visited.getOrPut(sema.arena, ty.toIntern());288 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
291 if (gop.found_existing) return;289 if (gop.found_existing) return;
292 try sema.ensureLayoutResolved(ty, self.import_loc, .init);290 try sema.ensureLayoutResolved(ty, self.import_src, .init);
293 const struct_info = zcu.typeToStruct(ty).?;291 const struct_info = zcu.typeToStruct(ty).?;
294 for (struct_info.field_types.get(ip)) |field_type| {292 for (struct_info.field_types.get(ip)) |field_type| {
295 try self.checkTypeInner(.fromInterned(field_type), null, visited);293 try self.checkTypeInner(.fromInterned(field_type), null, visited);
...@@ -298,7 +296,7 @@ fn checkTypeInner(...@@ -298,7 +296,7 @@ fn checkTypeInner(
298 .@"union" => {296 .@"union" => {
299 const gop = try visited.getOrPut(sema.arena, ty.toIntern());297 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
300 if (gop.found_existing) return;298 if (gop.found_existing) return;
301 try sema.ensureLayoutResolved(ty, self.import_loc, .init);299 try sema.ensureLayoutResolved(ty, self.import_src, .init);
302 const union_info = zcu.typeToUnion(ty).?;300 const union_info = zcu.typeToUnion(ty).?;
303 for (union_info.field_types.get(ip)) |field_type| {301 for (union_info.field_types.get(ip)) |field_type| {
304 if (field_type != .void_type) {302 if (field_type != .void_type) {
...@@ -311,8 +309,8 @@ fn checkTypeInner(...@@ -311,8 +309,8 @@ fn checkTypeInner(
311309
312fn nodeSrc(self: *LowerZon, node: Zoir.Node.Index) LazySrcLoc {310fn nodeSrc(self: *LowerZon, node: Zoir.Node.Index) LazySrcLoc {
313 return .{311 return .{
314 .base_node_inst = self.base_node_inst,312 .baseline = .{ .inst = self.tracked_inst, .node = .main },
315 .offset = .{ .node_abs = node.getAstNode(self.file.zoir.?) },313 .offset = .{ .node_abs = node.getAstNode(self.zoir.*) },
316 };314 };
317}315}
318316
...@@ -326,9 +324,9 @@ fn failUnsupportedResultType(...@@ -326,9 +324,9 @@ fn failUnsupportedResultType(
326 const gpa = sema.gpa;324 const gpa = sema.gpa;
327 const pt = sema.pt;325 const pt = sema.pt;
328 return sema.failWithOwnedErrorMsg(self.block, msg: {326 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)});
330 errdefer msg.destroy(gpa);328 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});
332 break :msg msg;330 break :msg msg;
333 });331 });
334}332}
...@@ -341,7 +339,7 @@ fn fail(...@@ -341,7 +339,7 @@ fn fail(
341) Zcu.SemaError {339) Zcu.SemaError {
342 @branchHint(.cold);340 @branchHint(.cold);
343 const err_msg = try Zcu.ErrorMsg.create(self.sema.pt.zcu.gpa, self.nodeSrc(node), format, args);341 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", .{});
345 return self.sema.failWithOwnedErrorMsg(self.block, err_msg);343 return self.sema.failWithOwnedErrorMsg(self.block, err_msg);
346}344}
347345
...@@ -363,7 +361,7 @@ fn lowerExprKnownResTyInner(...@@ -363,7 +361,7 @@ fn lowerExprKnownResTyInner(
363 .optional => return pt.intern(.{361 .optional => return pt.intern(.{
364 .opt = .{362 .opt = .{
365 .ty = res_ty.toIntern(),363 .ty = res_ty.toIntern(),
366 .val = if (node.get(self.file.zoir.?) == .null) b: {364 .val = if (node.get(self.zoir.*) == .null) b: {
367 break :b .none;365 break :b .none;
368 } else b: {366 } else b: {
369 const child_type = res_ty.optionalChild(pt.zcu);367 const child_type = res_ty.optionalChild(pt.zcu);
...@@ -418,7 +416,7 @@ fn lowerExprKnownResTyInner(...@@ -418,7 +416,7 @@ fn lowerExprKnownResTyInner(
418}416}
419417
420fn lowerBool(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {418fn lowerBool(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
421 return switch (node.get(self.file.zoir.?)) {419 return switch (node.get(self.zoir.*)) {
422 .true => .bool_true,420 .true => .bool_true,
423 .false => .bool_false,421 .false => .bool_false,
424 else => return error.WrongType,422 else => return error.WrongType,
...@@ -431,7 +429,7 @@ fn lowerInt(...@@ -431,7 +429,7 @@ fn lowerInt(
431 res_ty: Type,429 res_ty: Type,
432) !InternPool.Index {430) !InternPool.Index {
433 @setFloatMode(.strict);431 @setFloatMode(.strict);
434 return switch (node.get(self.file.zoir.?)) {432 return switch (node.get(self.zoir.*)) {
435 .int_literal => |int| switch (int) {433 .int_literal => |int| switch (int) {
436 .small => |val| {434 .small => |val| {
437 const rhs: i32 = val;435 const rhs: i32 = val;
...@@ -555,7 +553,7 @@ fn lowerFloat(...@@ -555,7 +553,7 @@ fn lowerFloat(
555 res_ty: Type,553 res_ty: Type,
556) !InternPool.Index {554) !InternPool.Index {
557 @setFloatMode(.strict);555 @setFloatMode(.strict);
558 const value = switch (node.get(self.file.zoir.?)) {556 const value = switch (node.get(self.zoir.*)) {
559 .int_literal => |int| switch (int) {557 .int_literal => |int| switch (int) {
560 .small => |val| try self.sema.pt.floatValue(res_ty, @as(f128, @floatFromInt(val))),558 .small => |val| try self.sema.pt.floatValue(res_ty, @as(f128, @floatFromInt(val))),
561 .big => |val| try self.sema.pt.floatValue(res_ty, val.toFloat(f128, .nearest_even)[0]),559 .big => |val| try self.sema.pt.floatValue(res_ty, val.toFloat(f128, .nearest_even)[0]),
...@@ -592,7 +590,7 @@ fn lowerFloat(...@@ -592,7 +590,7 @@ fn lowerFloat(
592}590}
593591
594fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {592fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
595 switch (node.get(self.file.zoir.?)) {593 switch (node.get(self.zoir.*)) {
596 .null => return .null_value,594 .null => return .null_value,
597 else => return error.WrongType,595 else => return error.WrongType,
598 }596 }
...@@ -600,7 +598,7 @@ fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {...@@ -600,7 +598,7 @@ fn lowerNull(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
600598
601fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.Index {599fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.Index {
602 const array_info = res_ty.arrayInfo(self.sema.pt.zcu);600 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.*)) {
604 .array_literal => |nodes| nodes,602 .array_literal => |nodes| nodes,
605 .empty_literal => .{ .start = node, .len = 0 },603 .empty_literal => .{ .start = node, .len = 0 },
606 else => return error.WrongType,604 else => return error.WrongType,
...@@ -632,14 +630,14 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I...@@ -632,14 +630,14 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
632 const gpa = comp.gpa;630 const gpa = comp.gpa;
633 const io = comp.io;631 const io = comp.io;
634 const ip = &pt.zcu.intern_pool;632 const ip = &pt.zcu.intern_pool;
635 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);633 try self.sema.ensureLayoutResolved(res_ty, self.import_src, .init);
636 switch (node.get(self.file.zoir.?)) {634 switch (node.get(self.zoir.*)) {
637 .enum_literal => |field_name| {635 .enum_literal => |field_name| {
638 const field_name_interned = try ip.getOrPutString(636 const field_name_interned = try ip.getOrPutString(
639 gpa,637 gpa,
640 io,638 io,
641 self.sema.pt.tid,639 self.sema.pt.tid,
642 field_name.get(self.file.zoir.?),640 field_name.get(self.zoir.*),
643 .no_embedded_nulls,641 .no_embedded_nulls,
644 );642 );
645 const field_index = res_ty.enumFieldIndex(field_name_interned, self.sema.pt.zcu) orelse {643 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...@@ -648,7 +646,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
648 "enum {f} has no member named '{f}'",646 "enum {f} has no member named '{f}'",
649 .{647 .{
650 res_ty.fmt(self.sema.pt),648 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.*)),
652 },650 },
653 );651 );
654 };652 };
...@@ -667,13 +665,13 @@ fn lowerEnumLiteral(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {...@@ -667,13 +665,13 @@ fn lowerEnumLiteral(self: *LowerZon, node: Zoir.Node.Index) !InternPool.Index {
667 const gpa = comp.gpa;665 const gpa = comp.gpa;
668 const io = comp.io;666 const io = comp.io;
669 const ip = &pt.zcu.intern_pool;667 const ip = &pt.zcu.intern_pool;
670 switch (node.get(self.file.zoir.?)) {668 switch (node.get(self.zoir.*)) {
671 .enum_literal => |field_name| {669 .enum_literal => |field_name| {
672 const field_name_interned = try ip.getOrPutString(670 const field_name_interned = try ip.getOrPutString(
673 gpa,671 gpa,
674 io,672 io,
675 self.sema.pt.tid,673 self.sema.pt.tid,
676 field_name.get(self.file.zoir.?),674 field_name.get(self.zoir.*),
677 .no_embedded_nulls,675 .no_embedded_nulls,
678 );676 );
679 return self.sema.pt.intern(.{ .enum_literal = field_name_interned });677 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....@@ -696,7 +694,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
696694
697 const tuple_info = ip.indexToKey(res_ty.toIntern()).tuple_type;695 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.*)) {
700 .array_literal => |nodes| nodes,698 .array_literal => |nodes| nodes,
701 .empty_literal => .{ .start = node, .len = 0 },699 .empty_literal => .{ .start = node, .len = 0 },
702 else => return error.WrongType,700 else => return error.WrongType,
...@@ -720,7 +718,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -720,7 +718,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
720 "index {} outside tuple of length {}",718 "index {} outside tuple of length {}",
721 .{719 .{
722 elems.len,720 elems.len,
723 elem_nodes.at(@intCast(i)).getAstNode(self.file.zoir.?),721 elem_nodes.at(@intCast(i)).getAstNode(self.zoir.*),
724 },722 },
725 );723 );
726 }724 }
...@@ -756,11 +754,11 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -756,11 +754,11 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
756 const io = comp.io;754 const io = comp.io;
757 const ip = &pt.zcu.intern_pool;755 const ip = &pt.zcu.intern_pool;
758756
759 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);757 try self.sema.ensureLayoutResolved(res_ty, self.import_src, .init);
760 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);758 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_src);
761 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;759 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.*)) {
764 .struct_literal => |fields| fields,762 .struct_literal => |fields| fields,
765 .empty_literal => .{ .names = &.{}, .vals = .{ .start = node, .len = 0 } },763 .empty_literal => .{ .names = &.{}, .vals = .{ .start = node, .len = 0 } },
766 else => return error.WrongType,764 else => return error.WrongType,
...@@ -780,7 +778,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -780,7 +778,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
780 gpa,778 gpa,
781 io,779 io,
782 self.sema.pt.tid,780 self.sema.pt.tid,
783 fields.names[i].get(self.file.zoir.?),781 fields.names[i].get(self.zoir.*),
784 .no_embedded_nulls,782 .no_embedded_nulls,
785 );783 );
786 const field_node = fields.vals.at(@intCast(i));784 const field_node = fields.vals.at(@intCast(i));
...@@ -844,7 +842,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -844,7 +842,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
844 const string_alignment = ptr_info.flags.alignment == .none or ptr_info.flags.alignment == .@"1";842 const string_alignment = ptr_info.flags.alignment == .none or ptr_info.flags.alignment == .@"1";
845 const string_sentinel = ptr_info.sentinel == .none or ptr_info.sentinel == .zero_u8;843 const string_sentinel = ptr_info.sentinel == .none or ptr_info.sentinel == .zero_u8;
846 if (string_alignment and ptr_info.child == .u8_type and string_sentinel) {844 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.*)) {
848 .string_literal => |val| {846 .string_literal => |val| {
849 const ip_str = try ip.getOrPutString(gpa, io, self.sema.pt.tid, val, .maybe_embedded_nulls);847 const ip_str = try ip.getOrPutString(gpa, io, self.sema.pt.tid, val, .maybe_embedded_nulls);
850 const str_ref = try self.sema.addStrLit(ip_str, val.len);848 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....@@ -860,7 +858,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
860 }858 }
861859
862 // Slice literals860 // 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.*)) {
864 .array_literal => |nodes| nodes,862 .array_literal => |nodes| nodes,
865 .empty_literal => .{ .start = node, .len = 0 },863 .empty_literal => .{ .start = node, .len = 0 },
866 else => return error.WrongType,864 else => return error.WrongType,
...@@ -923,23 +921,23 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -923,23 +921,23 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
923 const gpa = comp.gpa;921 const gpa = comp.gpa;
924 const io = comp.io;922 const io = comp.io;
925 const ip = &pt.zcu.intern_pool;923 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);
927 const union_info = pt.zcu.typeToUnion(res_ty).?;925 const union_info = pt.zcu.typeToUnion(res_ty).?;
928 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);926 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.*)) {
931 .enum_literal => |name| b: {929 .enum_literal => |name| b: {
932 const field_name = try ip.getOrPutString(930 const field_name = try ip.getOrPutString(
933 gpa,931 gpa,
934 io,932 io,
935 self.sema.pt.tid,933 self.sema.pt.tid,
936 name.get(self.file.zoir.?),934 name.get(self.zoir.*),
937 .no_embedded_nulls,935 .no_embedded_nulls,
938 );936 );
939 break :b .{ field_name, null };937 break :b .{ field_name, null };
940 },938 },
941 .struct_literal => b: {939 .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.*)) {
943 .struct_literal => |fields| fields,941 .struct_literal => |fields| fields,
944 else => return self.fail(node, "expected type '{f}'", .{res_ty.fmt(self.sema.pt)}),942 else => return self.fail(node, "expected type '{f}'", .{res_ty.fmt(self.sema.pt)}),
945 };943 };
...@@ -950,7 +948,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool....@@ -950,7 +948,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
950 gpa,948 gpa,
951 io,949 io,
952 self.sema.pt.tid,950 self.sema.pt.tid,
953 fields.names[0].get(self.file.zoir.?),951 fields.names[0].get(self.zoir.*),
954 .no_embedded_nulls,952 .no_embedded_nulls,
955 );953 );
956 break :b .{ field_name, fields.vals.at(0) };954 break :b .{ field_name, fields.vals.at(0) };
...@@ -986,7 +984,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool...@@ -986,7 +984,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
986984
987 const vector_info = ip.indexToKey(res_ty.toIntern()).vector_type;985 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.*)) {
990 .array_literal => |nodes| nodes,988 .array_literal => |nodes| nodes,
991 .empty_literal => .{ .start = node, .len = 0 },989 .empty_literal => .{ .start = node, .len = 0 },
992 else => return error.WrongType,990 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 {...@@ -205,7 +205,10 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
205 .instructions = .empty,205 .instructions = .empty,
206 .inlining = null,206 .inlining = null,
207 .comptime_reason = undefined, // always set before using `block`207 .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 },
209 .type_name_ctx = struct_obj.name,212 .type_name_ctx = struct_obj.name,
210 .type_fqn_ctx = struct_obj.fqn,213 .type_fqn_ctx = struct_obj.fqn,
211 };214 };
...@@ -261,6 +264,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -261,6 +264,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
261 {264 {
262 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });265 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
263 const field_ty: Type = field_ty: {266 const field_ty: Type = field_ty: {
267 block.src_baseline.node = .type_decl_fields;
268 defer block.src_baseline.node = .main;
264 block.comptime_reason = .{ .reason = .{269 block.comptime_reason = .{ .reason = .{
265 .src = field_ty_src,270 .src = field_ty_src,
266 .r = .{ .simple = .struct_field_types },271 .r = .{ .simple = .struct_field_types },
...@@ -276,6 +281,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -276,6 +281,8 @@ pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
276 } else {281 } else {
277 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });282 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
278 const field_align: Alignment = a: {283 const field_align: Alignment = a: {
284 block.src_baseline.node = .type_decl_fields;
285 defer block.src_baseline.node = .main;
279 block.comptime_reason = .{ .reason = .{286 block.comptime_reason = .{ .reason = .{
280 .src = field_align_src,287 .src = field_align_src,
281 .r = .{ .simple = .struct_field_attrs },288 .r = .{ .simple = .struct_field_attrs },
...@@ -538,6 +545,8 @@ fn resolvePackedStructLayout(...@@ -538,6 +545,8 @@ fn resolvePackedStructLayout(
538 field_bits += field_ty.bitSize(zcu);545 field_bits += field_ty.bitSize(zcu);
539 }546 }
540547
548 const backing_int_ty_src = block.src(.container_arg);
549
541 const explicit_backing_int_ty: ?Type = if (struct_obj.is_reified) ty: {550 const explicit_backing_int_ty: ?Type = if (struct_obj.is_reified) ty: {
542 break :ty switch (struct_obj.packed_backing_mode) {551 break :ty switch (struct_obj.packed_backing_mode) {
543 .explicit => .fromInterned(struct_obj.packed_backing_int_type),552 .explicit => .fromInterned(struct_obj.packed_backing_int_type),
...@@ -550,20 +559,21 @@ fn resolvePackedStructLayout(...@@ -550,20 +559,21 @@ fn resolvePackedStructLayout(
550 break :ty null; // inferred backing type559 break :ty null; // inferred backing type
551 };560 };
552 // Explicitly specified, so evaluate the backing int type expression.561 // 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;
554 block.comptime_reason = .{ .reason = .{564 block.comptime_reason = .{ .reason = .{
555 .src = backing_int_type_src,565 .src = backing_int_ty_src,
556 .r = .{ .simple = .packed_struct_backing_int_type },566 .r = .{ .simple = .packed_struct_backing_int_type },
557 } };567 } };
558 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);568 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);
560 };570 };
561571
562 // Finally, either validate or infer the backing int type.572 // Finally, either validate or infer the backing int type.
563 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {573 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
564 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(574 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
565 block,575 block,
566 block.src(.container_arg),576 backing_int_ty_src,
567 "expected backing integer type, found '{f}'",577 "expected backing integer type, found '{f}'",
568 .{backing_ty.fmt(pt)},578 .{backing_ty.fmt(pt)},
569 );579 );
...@@ -572,7 +582,7 @@ fn resolvePackedStructLayout(...@@ -572,7 +582,7 @@ fn resolvePackedStructLayout(
572 const msg = try sema.errMsg(src, "backing integer bit width does not match total bit width of fields", .{});582 const msg = try sema.errMsg(src, "backing integer bit width does not match total bit width of fields", .{});
573 errdefer msg.destroy(gpa);583 errdefer msg.destroy(gpa);
574 try sema.errNote(584 try sema.errNote(
575 block.src(.container_arg),585 backing_int_ty_src,
576 msg,586 msg,
577 "backing integer '{f}' has bit width '{d}'",587 "backing integer '{f}' has bit width '{d}'",
578 .{ backing_ty.fmt(pt), backing_ty.bitSize(zcu) },588 .{ backing_ty.fmt(pt), backing_ty.bitSize(zcu) },
...@@ -652,7 +662,10 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {...@@ -652,7 +662,10 @@ pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {
652 .instructions = .empty,662 .instructions = .empty,
653 .inlining = null,663 .inlining = null,
654 .comptime_reason = undefined, // always set before using `block`664 .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 },
656 .type_name_ctx = struct_obj.name,669 .type_name_ctx = struct_obj.name,
657 .type_fqn_ctx = struct_obj.fqn,670 .type_fqn_ctx = struct_obj.fqn,
658 };671 };
...@@ -675,6 +688,7 @@ fn resolveStructDefaultsInner(...@@ -675,6 +688,7 @@ fn resolveStructDefaultsInner(
675 const ip = &zcu.intern_pool;688 const ip = &zcu.intern_pool;
676689
677 assert(struct_obj.field_defaults.len > 0);690 assert(struct_obj.field_defaults.len > 0);
691 assert(block.src_baseline.node == .main);
678692
679 // We'll need to map the struct decl instruction to provide result types693 // We'll need to map the struct decl instruction to provide result types
680 const zir_index = struct_obj.zir_index.resolve(ip) orelse {694 const zir_index = struct_obj.zir_index.resolve(ip) orelse {
...@@ -693,6 +707,8 @@ fn resolveStructDefaultsInner(...@@ -693,6 +707,8 @@ fn resolveStructDefaultsInner(
693 }707 }
694708
695 const default_val_src = block.src(.{ .container_field_value = zir_field.idx });709 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;
696 block.comptime_reason = .{ .reason = .{712 block.comptime_reason = .{ .reason = .{
697 .src = default_val_src,713 .src = default_val_src,
698 .r = .{ .simple = .struct_field_default_value },714 .r = .{ .simple = .struct_field_default_value },
...@@ -747,7 +763,10 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -747,7 +763,10 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
747 .instructions = .empty,763 .instructions = .empty,
748 .inlining = null,764 .inlining = null,
749 .comptime_reason = undefined, // always set before using `block`765 .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 },
751 .type_name_ctx = union_obj.name,770 .type_name_ctx = union_obj.name,
752 .type_fqn_ctx = union_obj.fqn,771 .type_fqn_ctx = union_obj.fqn,
753 };772 };
...@@ -764,6 +783,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -764,6 +783,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
764 assert(zir_union.kind == .tagged_explicit); // `Zcu.mapOldZirToNew` guarantees that the ZIR mapping preserves `kind`783 assert(zir_union.kind == .tagged_explicit); // `Zcu.mapOldZirToNew` guarantees that the ZIR mapping preserves `kind`
765 const tag_type_body = zir_union.arg_type_body.?;784 const tag_type_body = zir_union.arg_type_body.?;
766 const tag_type_src = block.src(.container_arg);785 const tag_type_src = block.src(.container_arg);
786 block.src_baseline.node = .type_decl_fields;
787 defer block.src_baseline.node = .main;
767 block.comptime_reason = .{ .reason = .{788 block.comptime_reason = .{ .reason = .{
768 .src = tag_type_src,789 .src = tag_type_src,
769 .r = .{ .simple = .union_enum_tag_type },790 .r = .{ .simple = .union_enum_tag_type },
...@@ -882,6 +903,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -882,6 +903,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
882 while (field_it.next()) |zir_field| {903 while (field_it.next()) |zir_field| {
883 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });904 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
884 const field_ty: Type = field_ty: {905 const field_ty: Type = field_ty: {
906 block.src_baseline.node = .type_decl_fields;
907 defer block.src_baseline.node = .main;
885 block.comptime_reason = .{ .reason = .{908 block.comptime_reason = .{ .reason = .{
886 .src = field_ty_src,909 .src = field_ty_src,
887 .r = .{ .simple = .union_field_types },910 .r = .{ .simple = .union_field_types },
...@@ -894,6 +917,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {...@@ -894,6 +917,8 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
894917
895 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });918 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
896 const explicit_field_align: Alignment = a: {919 const explicit_field_align: Alignment = a: {
920 block.src_baseline.node = .type_decl_fields;
921 defer block.src_baseline.node = .main;
897 block.comptime_reason = .{ .reason = .{922 block.comptime_reason = .{ .reason = .{
898 .src = field_align_src,923 .src = field_align_src,
899 .r = .{ .simple = .union_field_attrs },924 .r = .{ .simple = .union_field_attrs },
...@@ -1066,7 +1091,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const...@@ -1066,7 +1091,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const
1066 if (union_field_index != null) continue;1091 if (union_field_index != null) continue;
1067 const field_name_ip = enum_obj.field_names.get(ip)[enum_field_index];1092 const field_name_ip = enum_obj.field_names.get(ip)[enum_field_index];
1068 const enum_field_src: LazySrcLoc = .{1093 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 },
1070 .offset = .{ .container_field_name = @intCast(enum_field_index) },1098 .offset = .{ .container_field_name = @intCast(enum_field_index) },
1071 };1099 };
1072 return sema.failWithOwnedErrorMsg(block, msg: {1100 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -1082,7 +1110,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const...@@ -1082,7 +1110,10 @@ fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const
1082 const field_name = enum_obj.field_names.get(ip)[enum_field_index];1110 const field_name = enum_obj.field_names.get(ip)[enum_field_index];
1083 const union_field_src = block.src(.{ .container_field_name = union_field_index.? });1111 const union_field_src = block.src(.{ .container_field_name = union_field_index.? });
1084 const enum_field_src: LazySrcLoc = .{1112 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 },
1086 .offset = .{ .container_field_name = @intCast(enum_field_index) },1117 .offset = .{ .container_field_name = @intCast(enum_field_index) },
1087 };1118 };
1088 return sema.failWithOwnedErrorMsg(block, msg: {1119 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -1138,6 +1169,8 @@ fn resolvePackedUnionLayout(...@@ -1138,6 +1169,8 @@ fn resolvePackedUnionLayout(
1138 assert(!field_ty.comptimeOnly(zcu)); // packable types are not comptime-only1169 assert(!field_ty.comptimeOnly(zcu)); // packable types are not comptime-only
1139 }1170 }
11401171
1172 const backing_int_ty_src = block.src(.container_arg);
1173
1141 const explicit_backing_int_ty: ?Type = if (union_obj.is_reified) ty: {1174 const explicit_backing_int_ty: ?Type = if (union_obj.is_reified) ty: {
1142 switch (union_obj.packed_backing_mode) {1175 switch (union_obj.packed_backing_mode) {
1143 .explicit => break :ty .fromInterned(union_obj.packed_backing_int_type),1176 .explicit => break :ty .fromInterned(union_obj.packed_backing_int_type),
...@@ -1150,20 +1183,21 @@ fn resolvePackedUnionLayout(...@@ -1150,20 +1183,21 @@ fn resolvePackedUnionLayout(
1150 break :ty null; // inferred backing type1183 break :ty null; // inferred backing type
1151 };1184 };
1152 // Explicitly specified, so evaluate the backing int type expression.1185 // 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;
1154 block.comptime_reason = .{ .reason = .{1188 block.comptime_reason = .{ .reason = .{
1155 .src = backing_int_type_src,1189 .src = backing_int_ty_src,
1156 .r = .{ .simple = .packed_union_backing_int_type },1190 .r = .{ .simple = .packed_union_backing_int_type },
1157 } };1191 } };
1158 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);1192 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);
1160 };1194 };
11611195
1162 // Finally, either validate or infer the backing int type.1196 // Finally, either validate or infer the backing int type.
1163 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {1197 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
1164 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(1198 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
1165 block,1199 block,
1166 block.src(.container_arg),1200 backing_int_ty_src,
1167 "expected backing integer type, found '{f}'",1201 "expected backing integer type, found '{f}'",
1168 .{backing_ty.fmt(pt)},1202 .{backing_ty.fmt(pt)},
1169 );1203 );
...@@ -1177,7 +1211,7 @@ fn resolvePackedUnionLayout(...@@ -1177,7 +1211,7 @@ fn resolvePackedUnionLayout(
1177 errdefer msg.destroy(gpa);1211 errdefer msg.destroy(gpa);
1178 try sema.errNote(field_ty_src, msg, "field type '{f}' has bit width '{d}'", .{ field_type.fmt(pt), field_bits });1212 try sema.errNote(field_ty_src, msg, "field type '{f}' has bit width '{d}'", .{ field_type.fmt(pt), field_bits });
1179 try sema.errNote(1213 try sema.errNote(
1180 block.src(.container_arg),1214 backing_int_ty_src,
1181 msg,1215 msg,
1182 "backing integer '{f}' has bit width '{d}'",1216 "backing integer '{f}' has bit width '{d}'",
1183 .{ backing_ty.fmt(pt), backing_int_bits },1217 .{ backing_ty.fmt(pt), backing_int_bits },
...@@ -1256,7 +1290,10 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1256,7 +1290,10 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1256 .instructions = .empty,1290 .instructions = .empty,
1257 .inlining = null,1291 .inlining = null,
1258 .comptime_reason = undefined, // always set before using `block`1292 .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 },
1260 .type_name_ctx = enum_obj.name,1297 .type_name_ctx = enum_obj.name,
1261 .type_fqn_ctx = enum_obj.fqn,1298 .type_fqn_ctx = enum_obj.fqn,
1262 };1299 };
...@@ -1341,6 +1378,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1341,6 +1378,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1341 // Explicitly specified, so evaluate the int tag type expression.1378 // Explicitly specified, so evaluate the int tag type expression.
1342 const tag_type_body = zir_union.arg_type_body.?;1379 const tag_type_body = zir_union.arg_type_body.?;
1343 const tag_type_src = block.src(.container_arg);1380 const tag_type_src = block.src(.container_arg);
1381 block.src_baseline.node = .type_decl_arg;
1382 defer block.src_baseline.node = .main;
1344 block.comptime_reason = .{ .reason = .{1383 block.comptime_reason = .{ .reason = .{
1345 .src = tag_type_src,1384 .src = tag_type_src,
1346 .r = .{ .simple = .enum_int_tag_type },1385 .r = .{ .simple = .enum_int_tag_type },
...@@ -1354,6 +1393,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1354,6 +1393,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1354 };1393 };
1355 // Explicitly specified, so evaluate the int tag type expression.1394 // Explicitly specified, so evaluate the int tag type expression.
1356 const tag_type_src = block.src(.container_arg);1395 const tag_type_src = block.src(.container_arg);
1396 block.src_baseline.node = .type_decl_arg;
1397 defer block.src_baseline.node = .main;
1357 block.comptime_reason = .{ .reason = .{1398 block.comptime_reason = .{ .reason = .{
1358 .src = tag_type_src,1399 .src = tag_type_src,
1359 .r = .{ .simple = .enum_int_tag_type },1400 .r = .{ .simple = .enum_int_tag_type },
...@@ -1425,6 +1466,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1425,6 +1466,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1425 var field_it = zir_union.iterateFields();1466 var field_it = zir_union.iterateFields();
1426 while (field_it.next()) |zir_field| {1467 while (field_it.next()) |zir_field| {
1427 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });1468 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;
1428 block.comptime_reason = .{ .reason = .{1471 block.comptime_reason = .{ .reason = .{
1429 .src = field_val_src,1472 .src = field_val_src,
1430 .r = .{ .simple = .enum_field_values },1473 .r = .{ .simple = .enum_field_values },
...@@ -1447,6 +1490,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {...@@ -1447,6 +1490,8 @@ pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1447 var field_it = zir_enum.iterateFields();1490 var field_it = zir_enum.iterateFields();
1448 while (field_it.next()) |zir_field| {1491 while (field_it.next()) |zir_field| {
1449 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });1492 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;
1450 block.comptime_reason = .{ .reason = .{1495 block.comptime_reason = .{ .reason = .{
1451 .src = field_val_src,1496 .src = field_val_src,
1452 .r = .{ .simple = .enum_field_values },1497 .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 {...@@ -2586,13 +2586,16 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
2586pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {2586pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
2587 const ip = &zcu.intern_pool;2587 const ip = &zcu.intern_pool;
2588 return .{2588 return .{
2589 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {2589 .baseline = .{
2590 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {2590 .inst = switch (ip.indexToKey(ty.toIntern())) {
2591 .declared => |d| d.zir_index,2591 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2592 .reified => |r| r.zir_index,2592 .declared => |d| d.zir_index,
2593 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).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,
2594 },2597 },
2595 else => return null,2598 .node = .main,
2596 },2599 },
2597 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),2600 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),
2598 };2601 };
src/Zcu.zig+109-54
...@@ -209,14 +209,14 @@ dependency_loop_nodes: std.array_hash_map.Auto(AnalUnit, struct {...@@ -209,14 +209,14 @@ dependency_loop_nodes: std.array_hash_map.Auto(AnalUnit, struct {
209/// Keep track of `@compileLog`s per `AnalUnit`.209/// Keep track of `@compileLog`s per `AnalUnit`.
210/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.210/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.
211/// The list is singly linked, but we do track its tail for fast appends (optimizing many logs in one unit).211/// 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 {212compile_logs: std.array_hash_map.Auto(AnalUnit, struct {
213 base_node_inst: InternPool.TrackedInst.Index,213 baseline: LazySrcLoc.Baseline,
214 node_offset: Ast.Node.Offset,214 node_offset: Ast.Node.Offset,
215 first_line: CompileLogLine.Index,215 first_line: CompileLogLine.Index,
216 last_line: CompileLogLine.Index,216 last_line: CompileLogLine.Index,
217 pub fn src(self: @This()) LazySrcLoc {217 pub fn src(self: @This()) LazySrcLoc {
218 return .{218 return .{
219 .base_node_inst = self.base_node_inst,219 .baseline = self.baseline,
220 .offset = LazySrcLoc.Offset.nodeOffset(self.node_offset),220 .offset = LazySrcLoc.Offset.nodeOffset(self.node_offset),
221 };221 };
222 }222 }
...@@ -2341,21 +2341,115 @@ pub const SrcLoc = struct {...@@ -2341,21 +2341,115 @@ pub const SrcLoc = struct {
2341};2341};
23422342
2343pub const LazySrcLoc = struct {2343pub const LazySrcLoc = struct {
2344 /// This instruction provides the source node locations are resolved relative to.2344 /// The baseline is a reference to a single AST node which `offset` is relative to. We use this
2345 /// It is a `declaration`, `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl`.2345 /// offset-based approach because AST node indices change across incremental updates, but we can
2346 /// This must be valid even if `relative` is an absolute value, since it is required to2346 /// track the changes for certain instructions (e.g. declarations). `Baseline` is a stable
2347 /// determine the file which the `LazySrcLoc` refers to.2347 /// reference to a source location in such an instruction. By representing all source locations
2348 base_node_inst: InternPool.TrackedInst.Index,2348 /// as relative to one of these baselines, we make them independent of changes in a file which
2349 /// This field determines the source location relative to `base_node_inst`.2349 /// happen outside of (e.g.) a specific declaration.
2350 baseline: Baseline,
2351 /// This field determines the source location relative to `baseline`.
2350 offset: Offset,2352 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
2352 pub const Offset = union(enum) {2446 pub const Offset = union(enum) {
2353 /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting2447 /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting
2354 /// that all code paths which would need to resolve the source location are2448 /// that all code paths which would need to resolve the source location are
2355 /// unreachable. If you are debugging this tag incorrectly being this value,2449 /// unreachable. If you are debugging this tag incorrectly being this value,
2356 /// look into using reverse-continue with a memory watchpoint to see where the2450 /// look into using reverse-continue with a memory watchpoint to see where the
2357 /// value is being set to this tag.2451 /// value is being set to this tag.
2358 /// `base_node_inst` is unused.2452 /// `baseline` is unused.
2359 unneeded,2453 unneeded,
2360 /// The source location points to a byte offset within a source file,2454 /// The source location points to a byte offset within a source file,
2361 /// offset from 0. The source file is determined contextually.2455 /// offset from 0. The source file is determined contextually.
...@@ -2734,50 +2828,11 @@ pub const LazySrcLoc = struct {...@@ -2734,50 +2828,11 @@ pub const LazySrcLoc = struct {
2734 };2828 };
27352829
2736 pub const unneeded: LazySrcLoc = .{2830 pub const unneeded: LazySrcLoc = .{
2737 .base_node_inst = undefined,2831 .baseline = undefined,
2738 .offset = .unneeded,2832 .offset = .unneeded,
2739 };2833 };
27402834
2741 /// Returns `null` if the ZIR instruction has been lost across incremental updates.2835 /// Resolve the file and AST node of `baseline` to get a resolved `SrcLoc`.
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`.
2781 /// The resulting `SrcLoc` should only be used ephemerally, as it is not correct across incremental updates.2836 /// The resulting `SrcLoc` should only be used ephemerally, as it is not correct across incremental updates.
2782 pub fn upgrade(lazy: LazySrcLoc, zcu: *Zcu) SrcLoc {2837 pub fn upgrade(lazy: LazySrcLoc, zcu: *Zcu) SrcLoc {
2783 return lazy.upgradeOrLost(zcu).?;2838 return lazy.upgradeOrLost(zcu).?;
...@@ -2785,9 +2840,9 @@ pub const LazySrcLoc = struct {...@@ -2785,9 +2840,9 @@ pub const LazySrcLoc = struct {
27852840
2786 /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates.2841 /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates.
2787 pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc {2842 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;
2789 return .{2844 return .{
2790 .file_scope = file,2845 .file_scope = zcu.fileByIndex(file),
2791 .base_node = base_node,2846 .base_node = base_node,
2792 .lazy = lazy.offset,2847 .lazy = lazy.offset,
2793 };2848 };
...@@ -4459,7 +4514,7 @@ pub fn setFileRootType(zcu: *Zcu, file_index: File.Index, root_type: InternPool....@@ -4459,7 +4514,7 @@ pub fn setFileRootType(zcu: *Zcu, file_index: File.Index, root_type: InternPool.
4459pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc {4514pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc {
4460 const ip = &zcu.intern_pool;4515 const ip = &zcu.intern_pool;
4461 return .{4516 return .{
4462 .base_node_inst = ip.getNav(nav_index).srcInst(ip),4517 .baseline = .{ .inst = ip.getNav(nav_index).srcInst(ip), .node = .main },
4463 .offset = LazySrcLoc.Offset.nodeOffset(.zero),4518 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
4464 };4519 };
4465}4520}
src/Zcu/PerThread.zig+18-6
...@@ -1317,12 +1317,15 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu...@@ -1317,12 +1317,15 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
1317 .inlining = null,1317 .inlining = null,
1318 .comptime_reason = .{ .reason = .{1318 .comptime_reason = .{ .reason = .{
1319 .src = .{1319 .src = .{
1320 .base_node_inst = comptime_unit.zir_index,1320 .baseline = .{ .inst = comptime_unit.zir_index, .node = .main },
1321 .offset = .{ .token_offset = .zero },1321 .offset = .{ .token_offset = .zero },
1322 },1322 },
1323 .r = .{ .simple = .comptime_keyword },1323 .r = .{ .simple = .comptime_keyword },
1324 } },1324 } },
1325 .src_base_inst = comptime_unit.zir_index,1325 .src_baseline = .{
1326 .inst = comptime_unit.zir_index,
1327 .node = .main,
1328 },
1326 .type_name_ctx = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.comptime", .{1329 .type_name_ctx = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.comptime", .{
1327 parent_ns.name.fmt(ip),1330 parent_ns.name.fmt(ip),
1328 }, .no_embedded_nulls),1331 }, .no_embedded_nulls),
...@@ -1723,7 +1726,10 @@ fn analyzeNavVal(...@@ -1723,7 +1726,10 @@ fn analyzeNavVal(
1723 .instructions = .empty,1726 .instructions = .empty,
1724 .inlining = null,1727 .inlining = null,
1725 .comptime_reason = undefined, // set below1728 .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 },
1727 .type_name_ctx = old_nav.name,1733 .type_name_ctx = old_nav.name,
1728 .type_fqn_ctx = old_nav.fqn,1734 .type_fqn_ctx = old_nav.fqn,
1729 };1735 };
...@@ -2093,7 +2099,10 @@ fn analyzeNavType(...@@ -2093,7 +2099,10 @@ fn analyzeNavType(
2093 .instructions = .empty,2099 .instructions = .empty,
2094 .inlining = null,2100 .inlining = null,
2095 .comptime_reason = undefined, // set below2101 .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 },
2097 .type_name_ctx = old_nav.name,2106 .type_name_ctx = old_nav.name,
2098 .type_fqn_ctx = old_nav.fqn,2107 .type_fqn_ctx = old_nav.fqn,
2099 };2108 };
...@@ -3373,7 +3382,10 @@ fn analyzeFuncBodyInner(...@@ -3373,7 +3382,10 @@ fn analyzeFuncBodyInner(
3373 .instructions = .empty,3382 .instructions = .empty,
3374 .inlining = null,3383 .inlining = null,
3375 .comptime_reason = null,3384 .comptime_reason = null,
3376 .src_base_inst = decl_analysis.zir_index,3385 .src_baseline = .{
3386 .inst = decl_analysis.zir_index,
3387 .node = .main,
3388 },
3377 .type_name_ctx = func_nav.name,3389 .type_name_ctx = func_nav.name,
3378 .type_fqn_ctx = func_nav.fqn,3390 .type_fqn_ctx = func_nav.fqn,
3379 };3391 };
...@@ -3511,7 +3523,7 @@ fn analyzeFuncBodyInner(...@@ -3511,7 +3523,7 @@ fn analyzeFuncBodyInner(
3511 // can be emitted here.3523 // can be emitted here.
3512 if (sema.fn_ret_ty_ies) |ies| {3524 if (sema.fn_ret_ty_ies) |ies| {
3513 sema.resolveInferredErrorSetPtr(&inner_block, .{3525 sema.resolveInferredErrorSetPtr(&inner_block, .{
3514 .base_node_inst = inner_block.src_base_inst,3526 .baseline = inner_block.src_baseline,
3515 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),3527 .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero),
3516 }, ies) catch |err| switch (err) {3528 }, ies) catch |err| switch (err) {
3517 error.ComptimeReturn => unreachable,3529 error.ComptimeReturn => unreachable,
src/crash_report.zig+5-4
...@@ -150,11 +150,12 @@ fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8...@@ -150,11 +150,12 @@ fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8
150150
151 var fba: std.heap.FixedBufferAllocator = .init(crash_heap);151 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 {153 const file_index, const src_base_node = block.src_baseline.resolve(zcu) orelse {
154 const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));154 const file = zcu.fileByIndex(block.src_baseline.inst.resolveFile(&zcu.intern_pool));
155 try stderr.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(comp)});155 try stderr.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(comp)});
156 return;156 return;
157 };157 };
158 const file = zcu.fileByIndex(file_index);
158159
159 try stderr.print("Analyzing '{f}'\n", .{file.path.fmt(comp)});160 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...@@ -180,9 +181,9 @@ fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8
180 var parent = anal.parent;181 var parent = anal.parent;
181 while (parent) |curr| {182 while (parent) |curr| {
182 fba.reset();183 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));
184 try stderr.print(" in {f}\n", .{cur_block_file.path.fmt(comp)});185 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 {
186 try stderr.writeAll(" > [lost instruction; this should not happen]\n");187 try stderr.writeAll(" > [lost instruction; this should not happen]\n");
187 parent = curr.parent;188 parent = curr.parent;
188 continue;189 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#}