about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2023-12-29 16:30:34 -0800
committerDavid Tolnay <dtolnay@gmail.com>2024-05-11 15:48:59 -0700
commit9e1cf2098d68356bccf7112bbff1d9b565e80a02 (patch)
treef9b2fa5f5790e5421fa215a2ade0c568052306e8
parentcbb8714a3f8a04cce698719df338fb095c40f479 (diff)
downloadrust-9e1cf2098d68356bccf7112bbff1d9b565e80a02.tar.gz
rust-9e1cf2098d68356bccf7112bbff1d9b565e80a02.zip
Macro call with braces does not require semicolon to be statement
This commit by itself is supposed to have no effect on behavior. All of
the call sites are updated to preserve their previous behavior.

The behavior changes are in the commits that follow.
-rw-r--r--compiler/rustc_ast/src/util/classify.rs30
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs5
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/fixup.rs6
-rw-r--r--compiler/rustc_lint/src/unused.rs5
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs16
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs11
6 files changed, 50 insertions, 23 deletions
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index 5ed8d95b12d..86383af1f7c 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -42,19 +42,23 @@ use crate::{ast, token::Delimiter};
 ///     _ => m! {} - 1,  // binary subtraction operator
 /// }
 /// ```
-#[allow(non_snake_case)]
-pub fn expr_requires_semi_to_be_stmt_FIXME(e: &ast::Expr) -> bool {
-    !matches!(
-        e.kind,
-        ast::ExprKind::If(..)
-            | ast::ExprKind::Match(..)
-            | ast::ExprKind::Block(..)
-            | ast::ExprKind::While(..)
-            | ast::ExprKind::Loop(..)
-            | ast::ExprKind::ForLoop { .. }
-            | ast::ExprKind::TryBlock(..)
-            | ast::ExprKind::ConstBlock(..)
-    )
+pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
+    use ast::ExprKind::*;
+
+    match &e.kind {
+        If(..)
+        | Match(..)
+        | Block(..)
+        | While(..)
+        | Loop(..)
+        | ForLoop { .. }
+        | TryBlock(..)
+        | ConstBlock(..) => false,
+
+        MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace,
+
+        _ => true,
+    }
 }
 
 /// If an expression ends with `}`, returns the innermost expression ending in the `}`
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index be98b7d37d4..fe17ff41bc3 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1253,7 +1253,10 @@ impl<'a> State<'a> {
             ast::StmtKind::Expr(expr) => {
                 self.space_if_not_bol();
                 self.print_expr_outer_attr_style(expr, false, FixupContext::new_stmt());
-                if classify::expr_requires_semi_to_be_stmt_FIXME(expr) {
+                if match expr.kind {
+                    ast::ExprKind::MacCall(_) => true,
+                    _ => classify::expr_requires_semi_to_be_stmt(expr),
+                } {
                     self.word(";");
                 }
             }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
index 363243215a3..9934f972f9b 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
@@ -128,7 +128,11 @@ impl FixupContext {
     /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
     /// examples.
     pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
-        self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt_FIXME(expr)
+        self.leftmost_subexpression_in_stmt
+            && match expr.kind {
+                ExprKind::MacCall(_) => false,
+                _ => !classify::expr_requires_semi_to_be_stmt(expr),
+            }
     }
 
     /// Determine whether parentheses are needed around the given `let`
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 7dca7017950..19b71564e2e 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -688,7 +688,10 @@ trait UnusedDelimLint {
                     ExprKind::Index(base, _subscript, _) => base,
                     _ => break,
                 };
-                if !classify::expr_requires_semi_to_be_stmt_FIXME(innermost) {
+                if match innermost.kind {
+                    ExprKind::MacCall(_) => false,
+                    _ => !classify::expr_requires_semi_to_be_stmt(innermost),
+                } {
                     return true;
                 }
             }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 951c3495995..5f7bd0835d3 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -498,7 +498,10 @@ impl<'a> Parser<'a> {
     /// Checks if this expression is a successfully parsed statement.
     fn expr_is_complete(&self, e: &Expr) -> bool {
         self.restrictions.contains(Restrictions::STMT_EXPR)
-            && !classify::expr_requires_semi_to_be_stmt_FIXME(e)
+            && match e.kind {
+                ExprKind::MacCall(_) => false,
+                _ => !classify::expr_requires_semi_to_be_stmt(e),
+            }
     }
 
     /// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
@@ -2694,7 +2697,10 @@ impl<'a> Parser<'a> {
                 // 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`.
                     if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
-                        && classify::expr_requires_semi_to_be_stmt_FIXME(&cond) =>
+                        && match cond.kind {
+                            ExprKind::MacCall(_) => true,
+                            _ => classify::expr_requires_semi_to_be_stmt(&cond),
+                        } =>
                 {
                     self.dcx().emit_err(errors::ExpectedElseBlock {
                         first_tok_span,
@@ -3136,8 +3142,10 @@ impl<'a> Parser<'a> {
                         err
                     })?;
 
-                let require_comma = classify::expr_requires_semi_to_be_stmt_FIXME(&expr)
-                    && this.token != token::CloseDelim(Delimiter::Brace);
+                let require_comma = match expr.kind {
+                    ExprKind::MacCall(_) => true,
+                    _ => classify::expr_requires_semi_to_be_stmt(&expr),
+                } && this.token != token::CloseDelim(Delimiter::Brace);
 
                 if !require_comma {
                     arm_body = Some(expr);
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index f64a480a18c..684799eb6a7 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -648,8 +648,10 @@ impl<'a> Parser<'a> {
         match &mut stmt.kind {
             // Expression without semicolon.
             StmtKind::Expr(expr)
-                if classify::expr_requires_semi_to_be_stmt_FIXME(expr)
-                    && !expr.attrs.is_empty()
+                if match expr.kind {
+                    ExprKind::MacCall(_) => true,
+                    _ => classify::expr_requires_semi_to_be_stmt(expr),
+                } && !expr.attrs.is_empty()
                     && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)]
                         .contains(&self.token.kind) =>
             {
@@ -663,7 +665,10 @@ impl<'a> Parser<'a> {
             // Expression without semicolon.
             StmtKind::Expr(expr)
                 if self.token != token::Eof
-                    && classify::expr_requires_semi_to_be_stmt_FIXME(expr) =>
+                    && match expr.kind {
+                        ExprKind::MacCall(_) => true,
+                        _ => classify::expr_requires_semi_to_be_stmt(expr),
+                    } =>
             {
                 // Just check for errors and recover; do not eat semicolon yet.