]> git.ipfire.org Git - people/ms/gcc.git/commitdiff
parser: Fix while let expr parsing
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Wed, 1 Mar 2023 16:45:51 +0000 (17:45 +0100)
committerPhilip Herron <philip.herron@embecosm.com>
Thu, 2 Mar 2023 16:36:57 +0000 (16:36 +0000)
While let expr return unit but are valid construct in rust, they should
therefore be included in the parsing code. Also add a new test to check
parsing of while let expressions.

gcc/rust/ChangeLog:

* parse/rust-parse-impl.h (Parser::parse_while_let_loop_expr):
Prevent hard error on token skip.
(Parser::null_denotation): Fix parser for while let expressions.

gcc/testsuite/ChangeLog:

* rust/compile/while_let_expr.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/parse/rust-parse-impl.h
gcc/testsuite/rust/compile/while_let_expr.rs [new file with mode: 0644]

index b17744fedaad6a0ec24bd4a950ea1428e323e08d..46704111f37602873c7595295299ab60f767630b 100644 (file)
@@ -8372,7 +8372,7 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs,
     locus = lexer.peek_token ()->get_locus ();
   else
     locus = label.get_locus ();
-  skip_token (WHILE);
+  maybe_skip_token (WHILE);
 
   /* check for possible accidental recognition of a while loop as a while let
    * loop */
@@ -13114,9 +13114,16 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
       return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (),
                              tok->get_locus ());
     case WHILE:
-      return parse_while_loop_expr (std::move (outer_attrs),
-                                   AST::LoopLabel::error (),
-                                   tok->get_locus ());
+      if (lexer.peek_token ()->get_id () == LET)
+       {
+         return parse_while_let_loop_expr (std::move (outer_attrs));
+       }
+      else
+       {
+         return parse_while_loop_expr (std::move (outer_attrs),
+                                       AST::LoopLabel::error (),
+                                       tok->get_locus ());
+       }
     case MATCH_TOK:
       // also an expression with block
       return parse_match_expr (std::move (outer_attrs), tok->get_locus ());
diff --git a/gcc/testsuite/rust/compile/while_let_expr.rs b/gcc/testsuite/rust/compile/while_let_expr.rs
new file mode 100644 (file)
index 0000000..113ad74
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-options "-fsyntax-only" }
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+fn main() {
+    let mut x = Option::Some(3);
+    let a = while let Option::Some(1) = x {
+        x = Option::None;
+    };
+}