From c4400e8aa58c9ba5e4cc51836a2cfa6c2e22bfcc Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 24 Sep 2022 15:15:20 +0300 Subject: [PATCH] AstGen: reset anon_name_strategy for sub expressions Closes #12910 --- src/AstGen.zig | 32 ++++++++++++++++++++++++++++++++ test/behavior/typename.zig | 25 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/AstGen.zig b/src/AstGen.zig index 7d567b223d..8e6721d7bc 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -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. diff --git a/test/behavior/typename.zig b/test/behavior/typename.zig index 63e36488e0..9b7a899653 100644 --- a/test/behavior/typename.zig +++ b/test/behavior/typename.zig @@ -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(), + ); +}