diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 6d5d4b5f2d..3ad82824ce 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1630,7 +1630,11 @@ fn parseBlockLabel(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?TokenInd /// FieldInit <- DOT IDENTIFIER EQUAL Expr fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { const period_token = eatToken(it, .Period) orelse return null; - const name_token = try expectToken(it, tree, .Identifier); + const name_token = eatToken(it, .Identifier) orelse { + // Because of anon literals `.{` is also valid. + putBackToken(it, period_token); + return null; + }; const eq_token = eatToken(it, .Equal) orelse { // `.Name` may also be an enum literal, which is a later rule. putBackToken(it, name_token); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index cabbe823f6..6e5ef878d5 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,3 +1,13 @@ +test "zig fmt: anon literal in array" { + try testCanonical( + \\var arr: [2]Foo = .{ + \\ .{ .a = 2 }, + \\ .{ .b = 3 }, + \\}; + \\ + ); +} + test "zig fmt: anon struct literal syntax" { try testCanonical( \\const x = .{ diff --git a/src/parser.cpp b/src/parser.cpp index 484e145cfa..65894bb833 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2025,7 +2025,12 @@ static AstNode *ast_parse_field_init(ParseContext *pc) { if (first == nullptr) return nullptr; - Token *name = expect_token(pc, TokenIdSymbol); + Token *name = eat_token_if(pc, TokenIdSymbol); + if (name == nullptr) { + // Because of anon literals ".{" is also valid. + put_back_token(pc); + return nullptr; + } if (eat_token_if(pc, TokenIdEq) == nullptr) { // Because ".Name" can also be intepreted as an enum literal, we should put back // those two tokens again so that the parser can try to parse them as the enum diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 0558a47fa4..3a9c9a7655 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -312,3 +312,24 @@ test "anonymous list literal syntax" { S.doTheTest(); comptime S.doTheTest(); } + +test "anonymous literal in array" { + const S = struct { + const Foo = struct { + a: usize = 2, + b: usize = 4, + }; + fn doTheTest() void { + var array: [2]Foo = .{ + .{.a = 3}, + .{.b = 3}, + }; + expect(array[0].a == 3); + expect(array[0].b == 4); + expect(array[1].a == 2); + expect(array[1].b == 3); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +}