aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse/rust-parse-impl.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-04-21 12:13:33 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-04-21 12:13:33 +0100
commitfe10ca37aba8f3cb9bfaa9dd01bdb1329317cf21 (patch)
treec4d4611d59da5be0c9476f2d1a62eaeef666b402 /gcc/rust/parse/rust-parse-impl.h
parentc18257c7265470a071f7ed9fe29899ece839fcf4 (diff)
downloadgcc-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.h30
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)