properly parse anon literal in array

This commit is contained in:
Vexu 2019-11-17 17:07:48 +02:00 committed by Andrew Kelley
parent 8c4784f9c1
commit 6cddf9d723
4 changed files with 42 additions and 2 deletions

View File

@ -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);

View File

@ -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 = .{

View File

@ -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

View File

@ -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();
}