authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-01 16:01:55+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-06 22:04:51+01:00
log38266c50351fc64fd4f513d684d6f2c1aaad7f9a
treeabd90c75849ef6119d1bd81ebbbe6fb219c5fa38
parent21a0885ae70f1e977b91a63a8b23d705acdac618

AstGen: fix name strategy bugs

Representing this with a `GenZir` field is incredibly bug-prone. Instead, just pass this data directly to the relevant expression in the very few places which actually provide a name strategy. Resolves: #22798

2 files changed, 205 insertions(+), 84 deletions(-)

lib/std/zig/AstGen.zig+119-84
...@@ -177,7 +177,6 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {...@@ -177,7 +177,6 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
177 var gen_scope: GenZir = .{177 var gen_scope: GenZir = .{
178 .is_comptime = true,178 .is_comptime = true,
179 .parent = &top_scope.base,179 .parent = &top_scope.base,
180 .anon_name_strategy = .parent,
181 .decl_node_index = .root,180 .decl_node_index = .root,
182 .decl_line = 0,181 .decl_line = 0,
183 .astgen = &astgen,182 .astgen = &astgen,
...@@ -196,6 +195,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {...@@ -196,6 +195,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir {
196 tree.containerDeclRoot(),195 tree.containerDeclRoot(),
197 .auto,196 .auto,
198 .none,197 .none,
198 .parent,
199 )) |struct_decl_ref| {199 )) |struct_decl_ref| {
200 assert(struct_decl_ref.toIndex().? == .main_struct_inst);200 assert(struct_decl_ref.toIndex().? == .main_struct_inst);
201 break :fatal false;201 break :fatal false;
...@@ -640,12 +640,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -640,12 +640,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
640 const astgen = gz.astgen;640 const astgen = gz.astgen;
641 const tree = astgen.tree;641 const tree = astgen.tree;
642642
643 const prev_anon_name_strategy = gz.anon_name_strategy;
644 defer gz.anon_name_strategy = prev_anon_name_strategy;
645 if (!nodeUsesAnonNameStrategy(tree, node)) {
646 gz.anon_name_strategy = .anon;
647 }
648
649 switch (tree.nodeTag(node)) {643 switch (tree.nodeTag(node)) {
650 .root => unreachable, // Top-level declaration.644 .root => unreachable, // Top-level declaration.
651 .@"usingnamespace" => unreachable, // Top-level declaration.645 .@"usingnamespace" => unreachable, // Top-level declaration.
...@@ -1104,7 +1098,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -1104,7 +1098,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
1104 .tagged_union_two_trailing,1098 .tagged_union_two_trailing,
1105 => {1099 => {
1106 var buf: [2]Ast.Node.Index = undefined;1100 var buf: [2]Ast.Node.Index = undefined;
1107 return containerDecl(gz, scope, ri, node, tree.fullContainerDecl(&buf, node).?);1101 return containerDecl(gz, scope, ri, node, tree.fullContainerDecl(&buf, node).?, .anon);
1108 },1102 },
11091103
1110 .@"break" => return breakExpr(gz, scope, node),1104 .@"break" => return breakExpr(gz, scope, node),
...@@ -1162,6 +1156,53 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -1162,6 +1156,53 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
1162 }1156 }
1163}1157}
11641158
1159/// When a name strategy other than `.anon` is available, for instance when analyzing the init expr
1160/// of a variable declaration, try this function before `expr`/`comptimeExpr`/etc, so that the name
1161/// strategy can be applied if necessary. If `null` is returned, then `node` does not consume a name
1162/// strategy, and a normal evaluation function like `expr` should be used instead. Otherwise, `node`
1163/// does consume a name strategy; the expression has been evaluated like `expr`, but using the given
1164/// name strategy.
1165fn nameStratExpr(
1166 gz: *GenZir,
1167 scope: *Scope,
1168 ri: ResultInfo,
1169 node: Ast.Node.Index,
1170 name_strat: Zir.Inst.NameStrategy,
1171) InnerError!?Zir.Inst.Ref {
1172 const astgen = gz.astgen;
1173 const tree = astgen.tree;
1174 switch (tree.nodeTag(node)) {
1175 .container_decl,
1176 .container_decl_trailing,
1177 .container_decl_two,
1178 .container_decl_two_trailing,
1179 .container_decl_arg,
1180 .container_decl_arg_trailing,
1181 .tagged_union,
1182 .tagged_union_trailing,
1183 .tagged_union_two,
1184 .tagged_union_two_trailing,
1185 .tagged_union_enum_tag,
1186 .tagged_union_enum_tag_trailing,
1187 => {
1188 var buf: [2]Ast.Node.Index = undefined;
1189 return try containerDecl(gz, scope, ri, node, tree.fullContainerDecl(&buf, node).?, name_strat);
1190 },
1191 .builtin_call_two,
1192 .builtin_call_two_comma,
1193 => {
1194 const builtin_token = tree.nodeMainToken(node);
1195 const builtin_name = tree.tokenSlice(builtin_token);
1196 if (!std.mem.eql(u8, builtin_name, "@Type")) return null;
1197 var buf: [2]Ast.Node.Index = undefined;
1198 const params = tree.builtinCallParams(&buf, node).?;
1199 if (params.len != 1) return null; // let `builtinCall` error
1200 return try builtinReify(gz, scope, ri, node, params[0], name_strat);
1201 },
1202 else => return null,
1203 }
1204}
1205
1165fn nosuspendExpr(1206fn nosuspendExpr(
1166 gz: *GenZir,1207 gz: *GenZir,
1167 scope: *Scope,1208 scope: *Scope,
...@@ -3241,10 +3282,8 @@ fn varDecl(...@@ -3241,10 +3282,8 @@ fn varDecl(
3241 .rl = .{ .ty = try typeExpr(gz, scope, type_node) },3282 .rl = .{ .ty = try typeExpr(gz, scope, type_node) },
3242 .ctx = .const_init,3283 .ctx = .const_init,
3243 } else .{ .rl = .none, .ctx = .const_init };3284 } else .{ .rl = .none, .ctx = .const_init };
3244 const prev_anon_name_strategy = gz.anon_name_strategy;3285 const init_inst: Zir.Inst.Ref = try nameStratExpr(gz, scope, result_info, init_node, .dbg_var) orelse
3245 gz.anon_name_strategy = .dbg_var;3286 try reachableExprComptime(gz, scope, result_info, init_node, node, if (force_comptime) .comptime_keyword else null);
3246 const init_inst = try reachableExprComptime(gz, scope, result_info, init_node, node, if (force_comptime) .comptime_keyword else null);
3247 gz.anon_name_strategy = prev_anon_name_strategy;
32483287
3249 _ = try gz.addUnNode(.validate_const, init_inst, init_node);3288 _ = try gz.addUnNode(.validate_const, init_inst, init_node);
3250 try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);3289 try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);
...@@ -3307,10 +3346,8 @@ fn varDecl(...@@ -3307,10 +3346,8 @@ fn varDecl(
3307 };3346 };
3308 const init_result_info: ResultInfo = .{ .rl = init_rl, .ctx = .const_init };3347 const init_result_info: ResultInfo = .{ .rl = init_rl, .ctx = .const_init };
33093348
3310 const prev_anon_name_strategy = gz.anon_name_strategy;3349 const init_inst: Zir.Inst.Ref = try nameStratExpr(gz, scope, init_result_info, init_node, .dbg_var) orelse
3311 gz.anon_name_strategy = .dbg_var;3350 try reachableExprComptime(gz, scope, init_result_info, init_node, node, if (force_comptime) .comptime_keyword else null);
3312 defer gz.anon_name_strategy = prev_anon_name_strategy;
3313 const init_inst = try reachableExprComptime(gz, scope, init_result_info, init_node, node, if (force_comptime) .comptime_keyword else null);
33143351
3315 // The const init expression may have modified the error return trace, so signal3352 // The const init expression may have modified the error return trace, so signal
3316 // to Sema that it should save the new index for restoring later.3353 // to Sema that it should save the new index for restoring later.
...@@ -3380,9 +3417,13 @@ fn varDecl(...@@ -3380,9 +3417,13 @@ fn varDecl(
3380 };3417 };
3381 break :a .{ alloc, true, .{ .rl = .{ .inferred_ptr = alloc } } };3418 break :a .{ alloc, true, .{ .rl = .{ .inferred_ptr = alloc } } };
3382 };3419 };
3383 const prev_anon_name_strategy = gz.anon_name_strategy;3420 _ = try nameStratExpr(
3384 gz.anon_name_strategy = .dbg_var;3421 gz,
3385 _ = try reachableExprComptime(3422 scope,
3423 result_info,
3424 init_node,
3425 .dbg_var,
3426 ) orelse try reachableExprComptime(
3386 gz,3427 gz,
3387 scope,3428 scope,
3388 result_info,3429 result_info,
...@@ -3390,7 +3431,6 @@ fn varDecl(...@@ -3390,7 +3431,6 @@ fn varDecl(
3390 node,3431 node,
3391 if (var_decl.comptime_token != null) .comptime_keyword else null,3432 if (var_decl.comptime_token != null) .comptime_keyword else null,
3392 );3433 );
3393 gz.anon_name_strategy = prev_anon_name_strategy;
3394 const final_ptr: Zir.Inst.Ref = if (resolve_inferred) ptr: {3434 const final_ptr: Zir.Inst.Ref = if (resolve_inferred) ptr: {
3395 break :ptr try gz.addUnNode(.resolve_inferred_alloc, alloc, node);3435 break :ptr try gz.addUnNode(.resolve_inferred_alloc, alloc, node);
3396 } else alloc;3436 } else alloc;
...@@ -4605,11 +4645,12 @@ fn globalVarDecl(...@@ -4605,11 +4645,12 @@ fn globalVarDecl(
4605 defer init_gz.unstack();4645 defer init_gz.unstack();
46064646
4607 if (var_decl.ast.init_node.unwrap()) |init_node| {4647 if (var_decl.ast.init_node.unwrap()) |init_node| {
4608 init_gz.anon_name_strategy = .parent;
4609 const init_ri: ResultInfo = if (var_decl.ast.type_node != .none) .{4648 const init_ri: ResultInfo = if (var_decl.ast.type_node != .none) .{
4610 .rl = .{ .coerced_ty = decl_inst.toRef() },4649 .rl = .{ .coerced_ty = decl_inst.toRef() },
4611 } else .{ .rl = .none };4650 } else .{ .rl = .none };
4612 const init_inst = try expr(&init_gz, &init_gz.base, init_ri, init_node);4651 const init_inst: Zir.Inst.Ref = try nameStratExpr(&init_gz, &init_gz.base, init_ri, init_node, .parent) orelse init: {
4652 break :init try expr(&init_gz, &init_gz.base, init_ri, init_node);
4653 };
4613 _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node);4654 _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node);
4614 }4655 }
46154656
...@@ -4986,6 +5027,7 @@ fn structDeclInner(...@@ -4986,6 +5027,7 @@ fn structDeclInner(
4986 container_decl: Ast.full.ContainerDecl,5027 container_decl: Ast.full.ContainerDecl,
4987 layout: std.builtin.Type.ContainerLayout,5028 layout: std.builtin.Type.ContainerLayout,
4988 backing_int_node: Ast.Node.OptionalIndex,5029 backing_int_node: Ast.Node.OptionalIndex,
5030 name_strat: Zir.Inst.NameStrategy,
4989) InnerError!Zir.Inst.Ref {5031) InnerError!Zir.Inst.Ref {
4990 const astgen = gz.astgen;5032 const astgen = gz.astgen;
4991 const gpa = astgen.gpa;5033 const gpa = astgen.gpa;
...@@ -5020,6 +5062,7 @@ fn structDeclInner(...@@ -5020,6 +5062,7 @@ fn structDeclInner(
5020 .any_default_inits = false,5062 .any_default_inits = false,
5021 .any_aligned_fields = false,5063 .any_aligned_fields = false,
5022 .fields_hash = std.zig.hashSrc(@tagName(layout)),5064 .fields_hash = std.zig.hashSrc(@tagName(layout)),
5065 .name_strat = name_strat,
5023 });5066 });
5024 return decl_inst.toRef();5067 return decl_inst.toRef();
5025 }5068 }
...@@ -5216,6 +5259,7 @@ fn structDeclInner(...@@ -5216,6 +5259,7 @@ fn structDeclInner(
5216 .any_default_inits = any_default_inits,5259 .any_default_inits = any_default_inits,
5217 .any_aligned_fields = any_aligned_fields,5260 .any_aligned_fields = any_aligned_fields,
5218 .fields_hash = fields_hash,5261 .fields_hash = fields_hash,
5262 .name_strat = name_strat,
5219 });5263 });
52205264
5221 wip_members.finishBits(bits_per_field);5265 wip_members.finishBits(bits_per_field);
...@@ -5347,6 +5391,7 @@ fn unionDeclInner(...@@ -5347,6 +5391,7 @@ fn unionDeclInner(
5347 layout: std.builtin.Type.ContainerLayout,5391 layout: std.builtin.Type.ContainerLayout,
5348 opt_arg_node: Ast.Node.OptionalIndex,5392 opt_arg_node: Ast.Node.OptionalIndex,
5349 auto_enum_tok: ?Ast.TokenIndex,5393 auto_enum_tok: ?Ast.TokenIndex,
5394 name_strat: Zir.Inst.NameStrategy,
5350) InnerError!Zir.Inst.Ref {5395) InnerError!Zir.Inst.Ref {
5351 const decl_inst = try gz.reserveInstructionIndex();5396 const decl_inst = try gz.reserveInstructionIndex();
53525397
...@@ -5497,6 +5542,7 @@ fn unionDeclInner(...@@ -5497,6 +5542,7 @@ fn unionDeclInner(
5497 .auto_enum_tag = auto_enum_tok != null,5542 .auto_enum_tag = auto_enum_tok != null,
5498 .any_aligned_fields = any_aligned_fields,5543 .any_aligned_fields = any_aligned_fields,
5499 .fields_hash = fields_hash,5544 .fields_hash = fields_hash,
5545 .name_strat = name_strat,
5500 });5546 });
55015547
5502 wip_members.finishBits(bits_per_field);5548 wip_members.finishBits(bits_per_field);
...@@ -5519,6 +5565,7 @@ fn containerDecl(...@@ -5519,6 +5565,7 @@ fn containerDecl(
5519 ri: ResultInfo,5565 ri: ResultInfo,
5520 node: Ast.Node.Index,5566 node: Ast.Node.Index,
5521 container_decl: Ast.full.ContainerDecl,5567 container_decl: Ast.full.ContainerDecl,
5568 name_strat: Zir.Inst.NameStrategy,
5522) InnerError!Zir.Inst.Ref {5569) InnerError!Zir.Inst.Ref {
5523 const astgen = gz.astgen;5570 const astgen = gz.astgen;
5524 const gpa = astgen.gpa;5571 const gpa = astgen.gpa;
...@@ -5539,7 +5586,7 @@ fn containerDecl(...@@ -5539,7 +5586,7 @@ fn containerDecl(
5539 else => unreachable,5586 else => unreachable,
5540 } else .auto;5587 } else .auto;
55415588
5542 const result = try structDeclInner(gz, scope, node, container_decl, layout, container_decl.ast.arg);5589 const result = try structDeclInner(gz, scope, node, container_decl, layout, container_decl.ast.arg, name_strat);
5543 return rvalue(gz, ri, result, node);5590 return rvalue(gz, ri, result, node);
5544 },5591 },
5545 .keyword_union => {5592 .keyword_union => {
...@@ -5549,7 +5596,7 @@ fn containerDecl(...@@ -5549,7 +5596,7 @@ fn containerDecl(
5549 else => unreachable,5596 else => unreachable,
5550 } else .auto;5597 } else .auto;
55515598
5552 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token);5599 const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token, name_strat);
5553 return rvalue(gz, ri, result, node);5600 return rvalue(gz, ri, result, node);
5554 },5601 },
5555 .keyword_enum => {5602 .keyword_enum => {
...@@ -5758,6 +5805,7 @@ fn containerDecl(...@@ -5758,6 +5805,7 @@ fn containerDecl(
5758 .fields_len = @intCast(counts.total_fields),5805 .fields_len = @intCast(counts.total_fields),
5759 .decls_len = @intCast(counts.decls),5806 .decls_len = @intCast(counts.decls),
5760 .fields_hash = fields_hash,5807 .fields_hash = fields_hash,
5808 .name_strat = name_strat,
5761 });5809 });
57625810
5763 wip_members.finishBits(bits_per_field);5811 wip_members.finishBits(bits_per_field);
...@@ -5819,6 +5867,7 @@ fn containerDecl(...@@ -5819,6 +5867,7 @@ fn containerDecl(
5819 .src_node = node,5867 .src_node = node,
5820 .captures_len = @intCast(namespace.captures.count()),5868 .captures_len = @intCast(namespace.captures.count()),
5821 .decls_len = decl_count,5869 .decls_len = decl_count,
5870 .name_strat = name_strat,
5822 });5871 });
58235872
5824 wip_members.finishBits(0);5873 wip_members.finishBits(0);
...@@ -8207,10 +8256,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -8207,10 +8256,8 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
8207 .rl = .{ .coerced_ty = astgen.fn_ret_ty },8256 .rl = .{ .coerced_ty = astgen.fn_ret_ty },
8208 .ctx = .@"return",8257 .ctx = .@"return",
8209 };8258 };
8210 const prev_anon_name_strategy = gz.anon_name_strategy;8259 const operand: Zir.Inst.Ref = try nameStratExpr(gz, scope, ri, operand_node, .func) orelse
8211 gz.anon_name_strategy = .func;8260 try reachableExpr(gz, scope, ri, operand_node, node);
8212 const operand = try reachableExpr(gz, scope, ri, operand_node, node);
8213 gz.anon_name_strategy = prev_anon_name_strategy;
82148261
8215 switch (nodeMayEvalToError(tree, operand_node)) {8262 switch (nodeMayEvalToError(tree, operand_node)) {
8216 .never => {8263 .never => {
...@@ -9472,31 +9519,7 @@ fn builtinCall(...@@ -9472,31 +9519,7 @@ fn builtinCall(
9472 },9519 },
94739520
9474 .Type => {9521 .Type => {
9475 const type_info_ty = try gz.addBuiltinValue(node, .type_info);9522 return builtinReify(gz, scope, ri, node, params[0], .anon);
9476 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = type_info_ty } }, params[0]);
9477
9478 const gpa = gz.astgen.gpa;
9479
9480 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9481 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
9482
9483 const payload_index = try gz.astgen.addExtra(Zir.Inst.Reify{
9484 .node = node, // Absolute node index -- see the definition of `Reify`.
9485 .operand = operand,
9486 .src_line = astgen.source_line,
9487 });
9488 const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
9489 gz.astgen.instructions.appendAssumeCapacity(.{
9490 .tag = .extended,
9491 .data = .{ .extended = .{
9492 .opcode = .reify,
9493 .small = @intFromEnum(gz.anon_name_strategy),
9494 .operand = payload_index,
9495 } },
9496 });
9497 gz.instructions.appendAssumeCapacity(new_index);
9498 const result = new_index.toRef();
9499 return rvalue(gz, ri, result, node);
9500 },9523 },
9501 .panic => {9524 .panic => {
9502 try emitDbgNode(gz, node);9525 try emitDbgNode(gz, node);
...@@ -9827,6 +9850,41 @@ fn builtinCall(...@@ -9827,6 +9850,41 @@ fn builtinCall(
9827 },9850 },
9828 }9851 }
9829}9852}
9853fn builtinReify(
9854 gz: *GenZir,
9855 scope: *Scope,
9856 ri: ResultInfo,
9857 node: Ast.Node.Index,
9858 arg_node: Ast.Node.Index,
9859 name_strat: Zir.Inst.NameStrategy,
9860) InnerError!Zir.Inst.Ref {
9861 const astgen = gz.astgen;
9862 const gpa = astgen.gpa;
9863
9864 const type_info_ty = try gz.addBuiltinValue(node, .type_info);
9865 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = type_info_ty } }, arg_node);
9866
9867 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9868 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
9869
9870 const payload_index = try astgen.addExtra(Zir.Inst.Reify{
9871 .node = node, // Absolute node index -- see the definition of `Reify`.
9872 .operand = operand,
9873 .src_line = astgen.source_line,
9874 });
9875 const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len);
9876 astgen.instructions.appendAssumeCapacity(.{
9877 .tag = .extended,
9878 .data = .{ .extended = .{
9879 .opcode = .reify,
9880 .small = @intFromEnum(name_strat),
9881 .operand = payload_index,
9882 } },
9883 });
9884 gz.instructions.appendAssumeCapacity(new_index);
9885 const result = new_index.toRef();
9886 return rvalue(gz, ri, result, node);
9887}
98309888
9831fn hasDeclOrField(9889fn hasDeclOrField(
9832 gz: *GenZir,9890 gz: *GenZir,
...@@ -11087,31 +11145,6 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {...@@ -11087,31 +11145,6 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
11087 }11145 }
11088}11146}
1108911147
11090/// Returns `true` if the node uses `gz.anon_name_strategy`.
11091fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool {
11092 switch (tree.nodeTag(node)) {
11093 .container_decl,
11094 .container_decl_trailing,
11095 .container_decl_two,
11096 .container_decl_two_trailing,
11097 .container_decl_arg,
11098 .container_decl_arg_trailing,
11099 .tagged_union,
11100 .tagged_union_trailing,
11101 .tagged_union_two,
11102 .tagged_union_two_trailing,
11103 .tagged_union_enum_tag,
11104 .tagged_union_enum_tag_trailing,
11105 => return true,
11106 .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => {
11107 const builtin_token = tree.nodeMainToken(node);
11108 const builtin_name = tree.tokenSlice(builtin_token);
11109 return std.mem.eql(u8, builtin_name, "@Type");
11110 },
11111 else => return false,
11112 }
11113}
11114
11115/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of11148/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
11116/// result locations must call this function on their result.11149/// result locations must call this function on their result.
11117/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.11150/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.
...@@ -11875,8 +11908,6 @@ const GenZir = struct {...@@ -11875,8 +11908,6 @@ const GenZir = struct {
11875 /// exits from this block should use `break_inline` rather than `break`.11908 /// exits from this block should use `break_inline` rather than `break`.
11876 is_inline: bool = false,11909 is_inline: bool = false,
11877 c_import: bool = false,11910 c_import: bool = false,
11878 /// How decls created in this scope should be named.
11879 anon_name_strategy: Zir.Inst.NameStrategy = .anon,
11880 /// The containing decl AST node.11911 /// The containing decl AST node.
11881 decl_node_index: Ast.Node.Index,11912 decl_node_index: Ast.Node.Index,
11882 /// The containing decl line index, absolute.11913 /// The containing decl line index, absolute.
...@@ -13043,6 +13074,7 @@ const GenZir = struct {...@@ -13043,6 +13074,7 @@ const GenZir = struct {
13043 any_default_inits: bool,13074 any_default_inits: bool,
13044 any_aligned_fields: bool,13075 any_aligned_fields: bool,
13045 fields_hash: std.zig.SrcHash,13076 fields_hash: std.zig.SrcHash,
13077 name_strat: Zir.Inst.NameStrategy,
13046 }) !void {13078 }) !void {
13047 const astgen = gz.astgen;13079 const astgen = gz.astgen;
13048 const gpa = astgen.gpa;13080 const gpa = astgen.gpa;
...@@ -13082,7 +13114,7 @@ const GenZir = struct {...@@ -13082,7 +13114,7 @@ const GenZir = struct {
13082 .has_backing_int = args.has_backing_int,13114 .has_backing_int = args.has_backing_int,
13083 .known_non_opv = args.known_non_opv,13115 .known_non_opv = args.known_non_opv,
13084 .known_comptime_only = args.known_comptime_only,13116 .known_comptime_only = args.known_comptime_only,
13085 .name_strategy = gz.anon_name_strategy,13117 .name_strategy = args.name_strat,
13086 .layout = args.layout,13118 .layout = args.layout,
13087 .any_comptime_fields = args.any_comptime_fields,13119 .any_comptime_fields = args.any_comptime_fields,
13088 .any_default_inits = args.any_default_inits,13120 .any_default_inits = args.any_default_inits,
...@@ -13104,6 +13136,7 @@ const GenZir = struct {...@@ -13104,6 +13136,7 @@ const GenZir = struct {
13104 auto_enum_tag: bool,13136 auto_enum_tag: bool,
13105 any_aligned_fields: bool,13137 any_aligned_fields: bool,
13106 fields_hash: std.zig.SrcHash,13138 fields_hash: std.zig.SrcHash,
13139 name_strat: Zir.Inst.NameStrategy,
13107 }) !void {13140 }) !void {
13108 const astgen = gz.astgen;13141 const astgen = gz.astgen;
13109 const gpa = astgen.gpa;13142 const gpa = astgen.gpa;
...@@ -13147,7 +13180,7 @@ const GenZir = struct {...@@ -13147,7 +13180,7 @@ const GenZir = struct {
13147 .has_body_len = args.body_len != 0,13180 .has_body_len = args.body_len != 0,
13148 .has_fields_len = args.fields_len != 0,13181 .has_fields_len = args.fields_len != 0,
13149 .has_decls_len = args.decls_len != 0,13182 .has_decls_len = args.decls_len != 0,
13150 .name_strategy = gz.anon_name_strategy,13183 .name_strategy = args.name_strat,
13151 .layout = args.layout,13184 .layout = args.layout,
13152 .auto_enum_tag = args.auto_enum_tag,13185 .auto_enum_tag = args.auto_enum_tag,
13153 .any_aligned_fields = args.any_aligned_fields,13186 .any_aligned_fields = args.any_aligned_fields,
...@@ -13166,6 +13199,7 @@ const GenZir = struct {...@@ -13166,6 +13199,7 @@ const GenZir = struct {
13166 decls_len: u32,13199 decls_len: u32,
13167 nonexhaustive: bool,13200 nonexhaustive: bool,
13168 fields_hash: std.zig.SrcHash,13201 fields_hash: std.zig.SrcHash,
13202 name_strat: Zir.Inst.NameStrategy,
13169 }) !void {13203 }) !void {
13170 const astgen = gz.astgen;13204 const astgen = gz.astgen;
13171 const gpa = astgen.gpa;13205 const gpa = astgen.gpa;
...@@ -13209,7 +13243,7 @@ const GenZir = struct {...@@ -13209,7 +13243,7 @@ const GenZir = struct {
13209 .has_body_len = args.body_len != 0,13243 .has_body_len = args.body_len != 0,
13210 .has_fields_len = args.fields_len != 0,13244 .has_fields_len = args.fields_len != 0,
13211 .has_decls_len = args.decls_len != 0,13245 .has_decls_len = args.decls_len != 0,
13212 .name_strategy = gz.anon_name_strategy,13246 .name_strategy = args.name_strat,
13213 .nonexhaustive = args.nonexhaustive,13247 .nonexhaustive = args.nonexhaustive,
13214 }),13248 }),
13215 .operand = payload_index,13249 .operand = payload_index,
...@@ -13221,6 +13255,7 @@ const GenZir = struct {...@@ -13221,6 +13255,7 @@ const GenZir = struct {
13221 src_node: Ast.Node.Index,13255 src_node: Ast.Node.Index,
13222 captures_len: u32,13256 captures_len: u32,
13223 decls_len: u32,13257 decls_len: u32,
13258 name_strat: Zir.Inst.NameStrategy,
13224 }) !void {13259 }) !void {
13225 const astgen = gz.astgen;13260 const astgen = gz.astgen;
13226 const gpa = astgen.gpa;13261 const gpa = astgen.gpa;
...@@ -13246,7 +13281,7 @@ const GenZir = struct {...@@ -13246,7 +13281,7 @@ const GenZir = struct {
13246 .small = @bitCast(Zir.Inst.OpaqueDecl.Small{13281 .small = @bitCast(Zir.Inst.OpaqueDecl.Small{
13247 .has_captures_len = args.captures_len != 0,13282 .has_captures_len = args.captures_len != 0,
13248 .has_decls_len = args.decls_len != 0,13283 .has_decls_len = args.decls_len != 0,
13249 .name_strategy = gz.anon_name_strategy,13284 .name_strategy = args.name_strat,
13250 }),13285 }),
13251 .operand = payload_index,13286 .operand = payload_index,
13252 } },13287 } },
test/cases/type_names.zig created+86
...@@ -0,0 +1,86 @@
1const namespace = struct {
2 const S = struct {};
3 const E = enum {};
4 const U = union {};
5 const O = opaque {};
6};
7export fn declarationValue() void {
8 @compileLog(@typeName(namespace.S));
9 @compileLog(@typeName(namespace.E));
10 @compileLog(@typeName(namespace.U));
11 @compileLog(@typeName(namespace.O));
12}
13
14export fn localVarValue() void {
15 const S = struct {};
16 const E = enum {};
17 const U = union {};
18 const O = opaque {};
19 @compileLog(@typeName(S));
20 @compileLog(@typeName(E));
21 @compileLog(@typeName(U));
22 @compileLog(@typeName(O));
23}
24
25fn MakeS() type {
26 return struct {};
27}
28fn MakeE() type {
29 return enum {};
30}
31fn MakeU() type {
32 return union {};
33}
34fn MakeO() type {
35 return opaque {};
36}
37
38export fn returnValue() void {
39 @compileLog(@typeName(MakeS()));
40 @compileLog(@typeName(MakeE()));
41 @compileLog(@typeName(MakeU()));
42 @compileLog(@typeName(MakeO()));
43}
44
45const StructInStruct = struct { a: struct { b: u8 } };
46const UnionInStruct = struct { a: union { b: u8 } };
47const StructInUnion = union { a: struct { b: u8 } };
48const UnionInUnion = union { a: union { b: u8 } };
49const StructInTuple = struct { struct { b: u8 } };
50const UnionInTuple = struct { union { b: u8 } };
51
52export fn nestedTypes() void {
53 @compileLog(@typeName(StructInStruct));
54 @compileLog(@typeName(UnionInStruct));
55 @compileLog(@typeName(StructInUnion));
56 @compileLog(@typeName(UnionInUnion));
57 @compileLog(@typeName(StructInTuple));
58 @compileLog(@typeName(UnionInTuple));
59}
60
61// error
62//
63// :8:5: error: found compile log statement
64// :19:5: note: also here
65// :39:5: note: also here
66// :53:5: note: also here
67//
68// Compile Log Output:
69// @as(*const [15:0]u8, "tmp.namespace.S")
70// @as(*const [15:0]u8, "tmp.namespace.E")
71// @as(*const [15:0]u8, "tmp.namespace.U")
72// @as(*const [15:0]u8, "tmp.namespace.O")
73// @as(*const [19:0]u8, "tmp.localVarValue.S")
74// @as(*const [19:0]u8, "tmp.localVarValue.E")
75// @as(*const [19:0]u8, "tmp.localVarValue.U")
76// @as(*const [19:0]u8, "tmp.localVarValue.O")
77// @as(*const [11:0]u8, "tmp.MakeS()")
78// @as(*const [11:0]u8, "tmp.MakeE()")
79// @as(*const [11:0]u8, "tmp.MakeU()")
80// @as(*const [11:0]u8, "tmp.MakeO()")
81// @as(*const [18:0]u8, "tmp.StructInStruct")
82// @as(*const [17:0]u8, "tmp.UnionInStruct")
83// @as(*const [17:0]u8, "tmp.StructInUnion")
84// @as(*const [16:0]u8, "tmp.UnionInUnion")
85// @as(*const [40:0]u8, "struct { tmp.StructInTuple__struct_574 }")
86// @as(*const [38:0]u8, "struct { tmp.UnionInTuple__union_581 }")