Commit 6cddf9d723
Changed files (4)
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);
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 = .{
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
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();
+}