Commit b2f16d4484

Vexu <git@vexu.eu>
2020-05-15 22:38:40
fix infinite loop with mismatced bracket
1 parent a00fd6e
Changed files (4)
doc/langref.html.in
@@ -10090,7 +10090,7 @@ FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link
 
 VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
 
-ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
+ContainerField &lt;- 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
     &lt;- 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 &lt;- ![a-zA-Z0-9_] skip
 KEYWORD_align       &lt;- 'align'       end_of_word
 KEYWORD_allowzero   &lt;- 'allowzero'   end_of_word
 KEYWORD_and         &lt;- 'and'         end_of_word
+KEYWORD_anyframe    &lt;- 'anyframe'    end_of_word
 KEYWORD_asm         &lt;- 'asm'         end_of_word
 KEYWORD_async       &lt;- 'async'       end_of_word
 KEYWORD_await       &lt;- 'await'       end_of_word
@@ -10521,7 +10522,6 @@ KEYWORD_null        &lt;- 'null'        end_of_word
 KEYWORD_or          &lt;- 'or'          end_of_word
 KEYWORD_orelse      &lt;- 'orelse'      end_of_word
 KEYWORD_packed      &lt;- 'packed'      end_of_word
-KEYWORD_promise     &lt;- 'promise'     end_of_word
 KEYWORD_pub         &lt;- 'pub'         end_of_word
 KEYWORD_resume      &lt;- 'resume'      end_of_word
 KEYWORD_return      &lt;- 'return'      end_of_word
@@ -10548,7 +10548,7 @@ keyword &lt;- 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
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);
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,
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)