Add classify::expr_is_complete
This commit is contained in:
parent
53521faf06
commit
10227eaee7
2 changed files with 60 additions and 98 deletions
|
@ -496,51 +496,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Checks if this expression is a successfully parsed statement.
|
||||
///
|
||||
/// This determines whether to continue parsing more of an expression in a
|
||||
/// match arm (false) vs continue to the next arm (true).
|
||||
///
|
||||
/// ```ignore (illustrative)
|
||||
/// match ... {
|
||||
/// // Is this calling $e as a function, or is it the start of a new arm
|
||||
/// // with a tuple pattern?
|
||||
/// _ => $e (
|
||||
/// ^ )
|
||||
///
|
||||
/// // Is this an Index operation, or new arm with a slice pattern?
|
||||
/// _ => $e [
|
||||
/// ^ ]
|
||||
///
|
||||
/// // Is this a binary operator, or leading vert in a new arm? Same for
|
||||
/// // other punctuation which can either be a binary operator in
|
||||
/// // expression or unary operator in pattern, such as `&` and `-`.
|
||||
/// _ => $e |
|
||||
/// ^
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If $e is something like `path::to` or `(…)`, continue parsing the same
|
||||
/// arm.
|
||||
///
|
||||
/// If $e is something like `{}` or `if … {}`, then terminate the current
|
||||
/// arm and parse a new arm.
|
||||
fn expr_is_complete(&self, e: &Expr) -> bool {
|
||||
self.restrictions.contains(Restrictions::STMT_EXPR)
|
||||
&& match e.kind {
|
||||
// Surprising special case: even though braced macro calls like
|
||||
// `m! {}` normally introduce a statement boundary when found at
|
||||
// the head of a statement, in match arms they do not terminate
|
||||
// the arm.
|
||||
//
|
||||
// let _ = { m! {} () }; // macro call followed by unit
|
||||
//
|
||||
// match ... {
|
||||
// _ => m! {} (), // macro that expands to a function, which is then called
|
||||
// }
|
||||
//
|
||||
ExprKind::MacCall(_) => false,
|
||||
_ => !classify::expr_requires_semi_to_be_stmt(e),
|
||||
}
|
||||
self.restrictions.contains(Restrictions::STMT_EXPR) && classify::expr_is_complete(e)
|
||||
}
|
||||
|
||||
/// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
|
||||
|
@ -3203,21 +3160,8 @@ impl<'a> Parser<'a> {
|
|||
err
|
||||
})?;
|
||||
|
||||
let require_comma = match expr.kind {
|
||||
// Special case: braced macro calls require comma in a match
|
||||
// arm, even though they do not require semicolon in a
|
||||
// statement.
|
||||
//
|
||||
// m! {} // okay without semicolon
|
||||
//
|
||||
// match ... {
|
||||
// _ => m! {}, // requires comma
|
||||
// _ => ...
|
||||
// }
|
||||
//
|
||||
ExprKind::MacCall(_) => true,
|
||||
_ => classify::expr_requires_semi_to_be_stmt(&expr),
|
||||
} && this.token != token::CloseDelim(Delimiter::Brace);
|
||||
let require_comma = !classify::expr_is_complete(&expr)
|
||||
&& this.token != token::CloseDelim(Delimiter::Brace);
|
||||
|
||||
if !require_comma {
|
||||
arm_body = Some(expr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue