AstGen: reset anon_name_strategy for sub expressions

Closes  #12910
This commit is contained in:
Veikka Tuominen 2022-09-24 15:15:20 +03:00
parent 8e4d0ae4f5
commit c4400e8aa5
2 changed files with 57 additions and 0 deletions

View file

@ -577,6 +577,12 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
const node_datas = tree.nodes.items(.data);
const node_tags = tree.nodes.items(.tag);
const prev_anon_name_strategy = gz.anon_name_strategy;
defer gz.anon_name_strategy = prev_anon_name_strategy;
if (!nodeUsesAnonNameStrategy(tree, node)) {
gz.anon_name_strategy = .anon;
}
switch (node_tags[node]) {
.root => unreachable, // Top-level declaration.
.@"usingnamespace" => unreachable, // Top-level declaration.
@ -9344,6 +9350,32 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
}
}
/// Returns `true` if the node uses `gz.anon_name_strategy`.
fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool {
const node_tags = tree.nodes.items(.tag);
switch (node_tags[node]) {
.container_decl,
.container_decl_trailing,
.container_decl_two,
.container_decl_two_trailing,
.container_decl_arg,
.container_decl_arg_trailing,
.tagged_union,
.tagged_union_trailing,
.tagged_union_two,
.tagged_union_two_trailing,
.tagged_union_enum_tag,
.tagged_union_enum_tag_trailing,
=> return true,
.builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => {
const builtin_token = tree.nodes.items(.main_token)[node];
const builtin_name = tree.tokenSlice(builtin_token);
return std.mem.eql(u8, builtin_name, "@Type");
},
else => return false,
}
}
/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
/// result locations must call this function on their result.
/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.

View file

@ -246,3 +246,28 @@ test "comptime parameters not converted to anytype in function type" {
const T = fn (fn (type) void, void) void;
try expectEqualStrings("fn(comptime fn(comptime type) void, void) void", @typeName(T));
}
test "anon name strategy used in sub expression" {
if (builtin.zig_backend == .stage1) {
// stage1 uses line/column for the names but we're moving away from that for
// incremental compilation purposes.
return error.SkipZigTest;
}
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
const S = struct {
fn getTheName() []const u8 {
return struct {
const name = @typeName(@This());
}.name;
}
};
try expectEqualStringsIgnoreDigits(
"behavior.typename.test.anon name strategy used in sub expression.S.getTheName__struct_0",
S.getTheName(),
);
}