about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-11-14 20:39:25 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-11-16 20:03:31 +0000
commit629a69f3e2728251774f825ff54cb642b38249df (patch)
treed90b3e2ce53111f6ed5d02ee48d932164b54813e
parent04fe8391775683e58d861f28678bf80940c91f44 (diff)
downloadrust-629a69f3e2728251774f825ff54cb642b38249df.tar.gz
rust-629a69f3e2728251774f825ff54cb642b38249df.zip
Better account for `else if` macro conditions mising an `if`
If a macro statement has been parsed after `else`, suggest a missing `if`:

```
error: expected `{`, found `falsy`
  --> $DIR/else-no-if.rs:47:12
   |
LL |     } else falsy! {} {
   |       ---- ^^^^^
   |       |
   |       expected an `if` or a block after this `else`
   |
help: add an `if` if this is the condition of a chained `else if` statement
   |
LL |     } else if falsy! {} {
   |            ++
```
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs11
-rw-r--r--tests/ui/parser/else-no-if.stderr9
2 files changed, 18 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 0ac6133e828..0012db471ef 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2683,6 +2683,13 @@ impl<'a> Parser<'a> {
                 //            ^^
                 //     }
                 //
+                // We account for macro calls that were meant as conditions as well.
+                //
+                //     if ... {
+                //     } else if macro! { foo bar } {
+                //            ^^
+                //     }
+                //
                 // If $cond is "statement-like" such as ExprKind::While then we
                 // want to suggest wrapping in braces.
                 //
@@ -2693,7 +2700,9 @@ impl<'a> Parser<'a> {
                 //     }
                 //     ^
                     if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
-                        && classify::expr_requires_semi_to_be_stmt(&cond) =>
+                        && (classify::expr_requires_semi_to_be_stmt(&cond)
+                            || matches!(cond.kind, ExprKind::MacCall(..)))
+                    =>
                 {
                     self.dcx().emit_err(errors::ExpectedElseBlock {
                         first_tok_span,
diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr
index c86791ec896..9954505e7c8 100644
--- a/tests/ui/parser/else-no-if.stderr
+++ b/tests/ui/parser/else-no-if.stderr
@@ -74,7 +74,14 @@ error: expected `{`, found `falsy`
   --> $DIR/else-no-if.rs:47:12
    |
 LL |     } else falsy! {} {
-   |            ^^^^^ expected `{`
+   |       ---- ^^^^^
+   |       |
+   |       expected an `if` or a block after this `else`
+   |
+help: add an `if` if this is the condition of a chained `else if` statement
+   |
+LL |     } else if falsy! {} {
+   |            ++
 
 error: expected `{`, found `falsy`
   --> $DIR/else-no-if.rs:54:12