diff --git a/doc/langref.html.in b/doc/langref.html.in index 0733540478..455c2e8ec1 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -10090,7 +10090,7 @@ FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON -ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)? +ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)? # *** Block Level *** Statement @@ -10204,7 +10204,7 @@ PrimaryTypeExpr / KEYWORD_error DOT IDENTIFIER / KEYWORD_false / KEYWORD_null - / KEYWORD_promise + / KEYWORD_anyframe / KEYWORD_true / KEYWORD_undefined / KEYWORD_unreachable @@ -10348,7 +10348,7 @@ PrefixOp PrefixTypeOp <- QUESTIONMARK - / KEYWORD_promise MINUSRARROW + / KEYWORD_anyframe MINUSRARROW / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* @@ -10495,6 +10495,7 @@ end_of_word <- ![a-zA-Z0-9_] skip KEYWORD_align <- 'align' end_of_word KEYWORD_allowzero <- 'allowzero' end_of_word KEYWORD_and <- 'and' end_of_word +KEYWORD_anyframe <- 'anyframe' end_of_word KEYWORD_asm <- 'asm' end_of_word KEYWORD_async <- 'async' end_of_word KEYWORD_await <- 'await' end_of_word @@ -10521,7 +10522,6 @@ KEYWORD_null <- 'null' end_of_word KEYWORD_or <- 'or' end_of_word KEYWORD_orelse <- 'orelse' end_of_word KEYWORD_packed <- 'packed' end_of_word -KEYWORD_promise <- 'promise' end_of_word KEYWORD_pub <- 'pub' end_of_word KEYWORD_resume <- 'resume' end_of_word KEYWORD_return <- 'return' end_of_word @@ -10548,7 +10548,7 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline / KEYWORD_noalias / KEYWORD_null / KEYWORD_or - / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub + / KEYWORD_orelse / KEYWORD_packed / KEYWORD_anyframe / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 6e41771ecc..c3714415f3 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -69,8 +69,8 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error /// <- TestDecl ContainerMembers /// / TopLevelComptime ContainerMembers /// / KEYWORD_pub? TopLevelDecl ContainerMembers -/// / KEYWORD_pub? ContainerField COMMA ContainerMembers -/// / KEYWORD_pub? ContainerField +/// / ContainerField COMMA ContainerMembers +/// / ContainerField /// / fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree, top_level: bool) !Node.Root.DeclList { var list = Node.Root.DeclList.init(arena); @@ -284,7 +284,10 @@ fn findNextContainerMember(it: *TokenIterator) void { } }, .LParen, .LBracket, .LBrace => level += 1, - .RParen, .RBracket, .RBrace => { + .RParen, .RBracket => { + if (level != 0) level -= 1; + }, + .RBrace => { if (level == 0) { // end of container, exit putBackToken(it, tok.index); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 616c1a5ea4..3dab9ac8cb 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -162,6 +162,16 @@ test "recovery: extra '}' at top level" { }); } +test "recovery: mismatched bracket at top level" { + try testError( + \\const S = struct { + \\ arr: 128]?G + \\}; + , &[_]Error{ + .ExpectedToken, + }); +} + test "zig fmt: top-level fields" { try testCanonical( \\a: did_you_know, diff --git a/src/parser.cpp b/src/parser.cpp index fc9814f393..c6c5823672 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -538,8 +538,8 @@ enum ContainerFieldState { // <- TestDecl ContainerMembers // / TopLevelComptime ContainerMembers // / KEYWORD_pub? TopLevelDecl ContainerMembers -// / KEYWORD_comptime? ContainerField COMMA ContainerMembers -// / KEYWORD_comptime? ContainerField +// / ContainerField COMMA ContainerMembers +// / ContainerField // / static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { AstNodeContainerDecl res = {}; @@ -862,7 +862,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) { return res; } -// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? +// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? static AstNode *ast_parse_container_field(ParseContext *pc) { Token *identifier = eat_token_if(pc, TokenIdSymbol); if (identifier == nullptr)