diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-04-21 12:13:33 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-04-21 12:13:33 +0100 |
commit | fe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21 (patch) | |
tree | c4d4611d59da5be0c9476f2d1a62eaeef666b402 /gcc/rust/parse/rust-parse-impl.h | |
parent | c18257c7265470a071f7ed9fe29899ece839fcf4 (diff) | |
download | gcc-fe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21.zip gcc-fe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21.tar.gz gcc-fe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21.tar.bz2 |
Handle parsing match arms with no comma
When parsing a match expression such as:
```
match (f, g) {
(Foo::A, 1) => {}
(Foo::B, 2) => {}
_ => {}
}
```
The first match arm here has an empty block expression of {}. This was
being parsed into a CallExpr of {}(Foo::B, 2) which is wrong. The parsing
of match arms are expression statements so they can be a block but must not
consume the semi-colon as it is valid to have a comma to delimit the match
arm or it can be ignored if this is a ExprWithBlock.
Addresses #1081
Diffstat (limited to 'gcc/rust/parse/rust-parse-impl.h')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 0198bfa3..25979ce 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -8563,7 +8563,11 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs, return nullptr; } - std::unique_ptr<AST::Expr> expr = parse_expr (); + ParseRestrictions restrictions; + restrictions.expr_can_be_stmt = true; + restrictions.consume_semi = false; + + std::unique_ptr<AST::ExprStmt> expr = parse_expr_stmt ({}, restrictions); if (expr == nullptr) { Error error (lexer.peek_token ()->get_locus (), @@ -8573,10 +8577,30 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs, // skip somewhere? return nullptr; } - bool is_expr_without_block = expr->is_expr_without_block (); + bool is_expr_without_block + = expr->get_type () == AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK; // construct match case expr and add to cases - match_arms.push_back (AST::MatchCase (std::move (arm), std::move (expr))); + switch (expr->get_type ()) + { + case AST::ExprStmt::ExprStmtType::WITH_BLOCK: { + AST::ExprStmtWithBlock *cast + = static_cast<AST::ExprStmtWithBlock *> (expr.get ()); + std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr (); + match_arms.push_back ( + AST::MatchCase (std::move (arm), std::move (e))); + } + break; + + case AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK: { + AST::ExprStmtWithoutBlock *cast + = static_cast<AST::ExprStmtWithoutBlock *> (expr.get ()); + std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr (); + match_arms.push_back ( + AST::MatchCase (std::move (arm), std::move (e))); + } + break; + } // handle comma presence if (lexer.peek_token ()->get_id () != COMMA) |