Mark expr_requires_semi_to_be_stmt call sites

For each of these, we need to decide whether they need to be using
`expr_requires_semi_to_be_stmt`, or `expr_requires_comma_to_be_match_arm`,
which are supposed to be 2 different behaviors. Previously they were
conflated into one, causing either too much or too little
parenthesization.
This commit is contained in:
David Tolnay 2023-12-29 16:28:47 -08:00
parent b431eec6f2
commit cbb8714a3f
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
6 changed files with 11 additions and 9 deletions

View File

@ -42,7 +42,8 @@ use crate::{ast, token::Delimiter};
/// _ => m! {} - 1, // binary subtraction operator /// _ => m! {} - 1, // binary subtraction operator
/// } /// }
/// ``` /// ```
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { #[allow(non_snake_case)]
pub fn expr_requires_semi_to_be_stmt_FIXME(e: &ast::Expr) -> bool {
!matches!( !matches!(
e.kind, e.kind,
ast::ExprKind::If(..) ast::ExprKind::If(..)

View File

@ -1253,7 +1253,7 @@ impl<'a> State<'a> {
ast::StmtKind::Expr(expr) => { ast::StmtKind::Expr(expr) => {
self.space_if_not_bol(); self.space_if_not_bol();
self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt()); self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
if classify::expr_requires_semi_to_be_stmt(expr) { if classify::expr_requires_semi_to_be_stmt_FIXME(expr) {
self.word(";"); self.word(";");
} }
} }

View File

@ -128,7 +128,7 @@ impl FixupContext {
/// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
/// examples. /// examples.
pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr) self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt_FIXME(expr)
} }
/// Determine whether parentheses are needed around the given `let` /// Determine whether parentheses are needed around the given `let`

View File

@ -688,7 +688,7 @@ trait UnusedDelimLint {
ExprKind::Index(base, _subscript, _) => base, ExprKind::Index(base, _subscript, _) => base,
_ => break, _ => break,
}; };
if !classify::expr_requires_semi_to_be_stmt(innermost) { if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) {
return true; return true;
} }
} }

View File

@ -498,7 +498,7 @@ impl<'a> Parser<'a> {
/// Checks if this expression is a successfully parsed statement. /// Checks if this expression is a successfully parsed statement.
fn expr_is_complete(&self, e: &Expr) -> bool { fn expr_is_complete(&self, e: &Expr) -> bool {
self.restrictions.contains(Restrictions::STMT_EXPR) self.restrictions.contains(Restrictions::STMT_EXPR)
&& !classify::expr_requires_semi_to_be_stmt(e) && !classify::expr_requires_semi_to_be_stmt_FIXME(e)
} }
/// Parses `x..y`, `x..=y`, and `x..`/`x..=`. /// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
@ -2694,7 +2694,7 @@ impl<'a> Parser<'a> {
// If it's not a free-standing expression, and is followed by a block, // If it's not a free-standing expression, and is followed by a block,
// then it's very likely the condition to an `else if`. // then it's very likely the condition to an `else if`.
if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
&& classify::expr_requires_semi_to_be_stmt(&cond) => && classify::expr_requires_semi_to_be_stmt_FIXME(&cond) =>
{ {
self.dcx().emit_err(errors::ExpectedElseBlock { self.dcx().emit_err(errors::ExpectedElseBlock {
first_tok_span, first_tok_span,
@ -3136,7 +3136,7 @@ impl<'a> Parser<'a> {
err err
})?; })?;
let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr)
&& this.token != token::CloseDelim(Delimiter::Brace); && this.token != token::CloseDelim(Delimiter::Brace);
if !require_comma { if !require_comma {

View File

@ -648,7 +648,7 @@ impl<'a> Parser<'a> {
match &mut stmt.kind { match &mut stmt.kind {
// Expression without semicolon. // Expression without semicolon.
StmtKind::Expr(expr) StmtKind::Expr(expr)
if classify::expr_requires_semi_to_be_stmt(expr) if classify::expr_requires_semi_to_be_stmt_FIXME(expr)
&& !expr.attrs.is_empty() && !expr.attrs.is_empty()
&& ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)] && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)]
.contains(&self.token.kind) => .contains(&self.token.kind) =>
@ -662,7 +662,8 @@ impl<'a> Parser<'a> {
// Expression without semicolon. // Expression without semicolon.
StmtKind::Expr(expr) StmtKind::Expr(expr)
if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) => if self.token != token::Eof
&& classify::expr_requires_semi_to_be_stmt_FIXME(expr) =>
{ {
// Just check for errors and recover; do not eat semicolon yet. // Just check for errors and recover; do not eat semicolon yet.