| author | |
| committer | |
| log | 6cddf9d7238a58b88064c3f3ce6e3948143598d8 |
| tree | 4b0f91b91e49d7bdd005ad8138ef6ff77fc7d470 |
| parent | 8c4784f9c181a13eae36d7a1ac57f278cf5fcd72 |
4 files changed, 42 insertions(+), 2 deletions(-)
lib/std/zig/parse.zig+5-1| ... | ... | @@ -1630,7 +1630,11 @@ fn parseBlockLabel(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?TokenInd |
| 1630 | 1630 | /// FieldInit <- DOT IDENTIFIER EQUAL Expr |
| 1631 | 1631 | fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1632 | 1632 | const period_token = eatToken(it, .Period) orelse return null; |
| 1633 | const name_token = try expectToken(it, tree, .Identifier); | |
| 1633 | const name_token = eatToken(it, .Identifier) orelse { | |
| 1634 | // Because of anon literals `.{` is also valid. | |
| 1635 | putBackToken(it, period_token); | |
| 1636 | return null; | |
| 1637 | }; | |
| 1634 | 1638 | const eq_token = eatToken(it, .Equal) orelse { |
| 1635 | 1639 | // `.Name` may also be an enum literal, which is a later rule. |
| 1636 | 1640 | putBackToken(it, name_token); |
lib/std/zig/parser_test.zig+10| ... | ... | @@ -1,3 +1,13 @@ |
| 1 | test "zig fmt: anon literal in array" { | |
| 2 | try testCanonical( | |
| 3 | \\var arr: [2]Foo = .{ | |
| 4 | \\ .{ .a = 2 }, | |
| 5 | \\ .{ .b = 3 }, | |
| 6 | \\}; | |
| 7 | \\ | |
| 8 | ); | |
| 9 | } | |
| 10 | ||
| 1 | 11 | test "zig fmt: anon struct literal syntax" { |
| 2 | 12 | try testCanonical( |
| 3 | 13 | \\const x = .{ |
src/parser.cpp+6-1| ... | ... | @@ -2025,7 +2025,12 @@ static AstNode *ast_parse_field_init(ParseContext *pc) { |
| 2025 | 2025 | if (first == nullptr) |
| 2026 | 2026 | return nullptr; |
| 2027 | 2027 | |
| 2028 | Token *name = expect_token(pc, TokenIdSymbol); | |
| 2028 | Token *name = eat_token_if(pc, TokenIdSymbol); | |
| 2029 | if (name == nullptr) { | |
| 2030 | // Because of anon literals ".{" is also valid. | |
| 2031 | put_back_token(pc); | |
| 2032 | return nullptr; | |
| 2033 | } | |
| 2029 | 2034 | if (eat_token_if(pc, TokenIdEq) == nullptr) { |
| 2030 | 2035 | // Because ".Name" can also be intepreted as an enum literal, we should put back |
| 2031 | 2036 | // those two tokens again so that the parser can try to parse them as the enum |
test/stage1/behavior/array.zig+21| ... | ... | @@ -312,3 +312,24 @@ test "anonymous list literal syntax" { |
| 312 | 312 | S.doTheTest(); |
| 313 | 313 | comptime S.doTheTest(); |
| 314 | 314 | } |
| 315 | ||
| 316 | test "anonymous literal in array" { | |
| 317 | const S = struct { | |
| 318 | const Foo = struct { | |
| 319 | a: usize = 2, | |
| 320 | b: usize = 4, | |
| 321 | }; | |
| 322 | fn doTheTest() void { | |
| 323 | var array: [2]Foo = .{ | |
| 324 | .{.a = 3}, | |
| 325 | .{.b = 3}, | |
| 326 | }; | |
| 327 | expect(array[0].a == 3); | |
| 328 | expect(array[0].b == 4); | |
| 329 | expect(array[1].a == 2); | |
| 330 | expect(array[1].b == 3); | |
| 331 | } | |
| 332 | }; | |
| 333 | S.doTheTest(); | |
| 334 | comptime S.doTheTest(); | |
| 335 | } |