authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-06-18 04:41:02+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-06-18 04:48:24+01:00
log0486aa5081eee589edce79b721f35fadf2de1625
tree6d27bacdf27943c6c2e0edbc24243dd7f0cf769b
parentedf14777bae56c3a6a155c59f793dc432656c1de
signaturelock-open Commit is signed but in an unrecognized format.

Zir: provide absolute node for `reify`

Since we track `reify` instructions across incremental updates, it is acceptable to treat it as the baseline for a relative source location. This turns out to be a good idea, since it makes it easy to define the source location for a reified type.

6 files changed, 29 insertions(+), 21 deletions(-)

lib/std/zig/AstGen.zig+3-2
...@@ -9361,9 +9361,10 @@ fn builtinCall(...@@ -9361,9 +9361,10 @@ fn builtinCall(
9361 try gz.instructions.ensureUnusedCapacity(gpa, 1);9361 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9362 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);9362 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
93639363
9364 const payload_index = try gz.astgen.addExtra(Zir.Inst.UnNode{9364 const payload_index = try gz.astgen.addExtra(Zir.Inst.Reify{
9365 .node = gz.nodeIndexToRelative(node),9365 .node = node, // Absolute node index -- see the definition of `Reify`.
9366 .operand = operand,9366 .operand = operand,
9367 .src_line = astgen.source_line,
9367 });9368 });
9368 const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);9369 const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
9369 gz.astgen.instructions.appendAssumeCapacity(.{9370 gz.astgen.instructions.appendAssumeCapacity(.{
lib/std/zig/Zir.zig+3-1
...@@ -2835,7 +2835,9 @@ pub const Inst = struct {...@@ -2835,7 +2835,9 @@ pub const Inst = struct {
2835 };2835 };
28362836
2837 pub const Reify = struct {2837 pub const Reify = struct {
2838 node: i32,2838 /// This node is absolute, because `reify` instructions are tracked across updates, and
2839 /// this simplifies the logic for getting source locations for types.
2840 node: Ast.Node.Index,
2839 operand: Ref,2841 operand: Ref,
2840 src_line: u32,2842 src_line: u32,
2841 };2843 };
src/Module.zig+1
...@@ -2374,6 +2374,7 @@ pub const LazySrcLoc = struct {...@@ -2374,6 +2374,7 @@ pub const LazySrcLoc = struct {
2374 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,2374 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
2375 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,2375 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,
2376 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,2376 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,
2377 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.node,
2377 else => unreachable,2378 else => unreachable,
2378 },2379 },
2379 else => unreachable,2380 else => unreachable,
src/Sema.zig+14-2
...@@ -21210,10 +21210,22 @@ fn zirReify(...@@ -21210,10 +21210,22 @@ fn zirReify(
21210 const ip = &mod.intern_pool;21210 const ip = &mod.intern_pool;
21211 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);21211 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
21212 const extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data;21212 const extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data;
21213 const src = block.nodeOffset(extra.node);21213 const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
21214 const src: LazySrcLoc = .{
21215 .base_node_inst = tracked_inst,
21216 .offset = LazySrcLoc.Offset.nodeOffset(0),
21217 };
21218 const operand_src: LazySrcLoc = .{
21219 .base_node_inst = tracked_inst,
21220 .offset = .{
21221 .node_offset_builtin_call_arg = .{
21222 .builtin_call_node = 0, // `tracked_inst` is precisely the `reify` instruction, so offset is 0
21223 .arg_index = 0,
21224 },
21225 },
21226 };
21214 const type_info_ty = try sema.getBuiltinType("Type");21227 const type_info_ty = try sema.getBuiltinType("Type");
21215 const uncasted_operand = try sema.resolveInst(extra.operand);21228 const uncasted_operand = try sema.resolveInst(extra.operand);
21216 const operand_src = block.builtinCallArgSrc(extra.node, 0);
21217 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21229 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
21218 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{21230 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
21219 .needed_comptime_reason = "operand to @Type must be comptime-known",21231 .needed_comptime_reason = "operand to @Type must be comptime-known",
src/print_zir.zig+4-1
...@@ -586,7 +586,10 @@ const Writer = struct {...@@ -586,7 +586,10 @@ const Writer = struct {
586 try stream.print("{d}, ", .{inst_data.src_line});586 try stream.print("{d}, ", .{inst_data.src_line});
587 try self.writeInstRef(stream, inst_data.operand);587 try self.writeInstRef(stream, inst_data.operand);
588 try stream.writeAll(")) ");588 try stream.writeAll(")) ");
589 try self.writeSrcNode(stream, inst_data.node);589 const prev_parent_decl_node = self.parent_decl_node;
590 self.parent_decl_node = inst_data.node;
591 defer self.parent_decl_node = prev_parent_decl_node;
592 try self.writeSrcNode(stream, 0);
590 },593 },
591594
592 .builtin_extern,595 .builtin_extern,
src/type.zig+4-15
...@@ -3336,22 +3336,11 @@ pub const Type = struct {...@@ -3336,22 +3336,11 @@ pub const Type = struct {
3336 const ip = &zcu.intern_pool;3336 const ip = &zcu.intern_pool;
3337 return .{3337 return .{
3338 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {3338 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {
3339 .struct_type => |info| switch (info) {3339 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
3340 .declared => ip.loadStructType(ty.toIntern()).zir_index.unwrap() orelse return null,3340 .declared => |d| d.zir_index,
3341 else => return null,3341 .reified => |r| r.zir_index,
3342 },
3343 .union_type => |info| switch (info) {
3344 .declared => ip.loadUnionType(ty.toIntern()).zir_index,
3345 else => return null,
3346 },
3347 .opaque_type => |info| switch (info) {
3348 .declared => ip.loadOpaqueType(ty.toIntern()).zir_index,
3349 else => return null,
3350 },
3351 .enum_type => |info| switch (info) {
3352 .declared => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3353 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index, // must be declared since we can't generate tags when reifying3342 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index, // must be declared since we can't generate tags when reifying
3354 else => return null,3343 .empty_struct => return null,
3355 },3344 },
3356 else => return null,3345 else => return null,
3357 },3346 },