Remove MacCall special case from recovery after missing 'if' after 'else'

The change to the test is a little goofy because the compiler was
guessing "correctly" before that `falsy! {}` is the condition as opposed
to the else body. But I believe this change is fundamentally correct.
Braced macro invocations in statement position are most often item-like
(`thread_local! {...}`) as opposed to parenthesized macro invocations
which are condition-like (`cfg!(...)`).
This commit is contained in:
David Tolnay 2023-12-29 17:37:32 -08:00
parent 0f6a51d495
commit aedc1b6ad4
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 32 additions and 12 deletions

View File

@ -2733,13 +2733,35 @@ fn parse_expr_else(&mut self) -> PResult<'a, P<Expr>> {
let first_tok_span = self.token.span;
match self.parse_expr() {
Ok(cond)
// 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`.
// Try to guess the difference between a "condition-like" vs
// "statement-like" expression.
//
// We are seeing the following code, in which $cond is neither
// ExprKind::Block nor ExprKind::If (the 2 cases wherein this
// would be valid syntax).
//
// if ... {
// } else $cond
//
// If $cond is "condition-like" such as ExprKind::Binary, we
// want to suggest inserting `if`.
//
// if ... {
// } else if a == b {
// ^^
// }
//
// If $cond is "statement-like" such as ExprKind::While then we
// want to suggest wrapping in braces.
//
// if ... {
// } else {
// ^
// while true {}
// }
// ^
if self.check(&TokenKind::OpenDelim(Delimiter::Brace))
&& match cond.kind {
ExprKind::MacCall(_) => true,
_ => classify::expr_requires_semi_to_be_stmt(&cond),
} =>
&& classify::expr_requires_semi_to_be_stmt(&cond) =>
{
self.dcx().emit_err(errors::ExpectedElseBlock {
first_tok_span,

View File

@ -74,14 +74,12 @@ error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:47:12
|
LL | } else falsy! {} {
| ---- ^^^^^
| |
| expected an `if` or a block after this `else`
| ^^^^^ expected `{`
|
help: add an `if` if this is the condition of a chained `else if` statement
help: try placing this code inside a block
|
LL | } else if falsy! {} {
| ++
LL | } else { falsy! {} } {
| + +
error: expected `{`, found `falsy`
--> $DIR/else-no-if.rs:54:12