From d1ba2d25d483a65f41ca6277c160e2ea6d813e3b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 27 May 2022 21:58:48 -0700 Subject: [PATCH] Improve parsing errors and suggestions for bad if statements --- compiler/rustc_parse/src/parser/expr.rs | 106 +++++++++++------- compiler/rustc_parse/src/parser/stmt.rs | 19 +++- ...-identifier-not-instead-of-negation.stderr | 10 +- src/test/ui/expr/if/if-without-block.rs | 4 +- src/test/ui/expr/if/if-without-block.stderr | 15 +-- src/test/ui/issues/issue-39848.stderr | 12 +- src/test/ui/missing/missing-block-hint.stderr | 17 ++- src/test/ui/parser/bad-if-statements.rs | 38 +++++++ src/test/ui/parser/bad-if-statements.stderr | 86 ++++++++++++++ .../ui/parser/if-block-unreachable-expr.rs | 8 ++ src/test/ui/parser/issue-61858.stderr | 10 +- .../issue-68091-unicode-ident-after-if.rs | 5 +- .../issue-68091-unicode-ident-after-if.stderr | 18 +-- src/test/ui/parser/issue-91421.rs | 5 +- src/test/ui/parser/issue-91421.stderr | 17 +-- src/test/ui/parser/issues/issue-13483.rs | 8 +- src/test/ui/parser/issues/issue-13483.stderr | 29 ++--- src/test/ui/parser/issues/issue-51602.stderr | 10 +- src/test/ui/parser/issues/issue-62554.stderr | 9 +- ...-else-does-not-interact-with-let-chains.rs | 6 +- ...e-does-not-interact-with-let-chains.stderr | 36 ++++-- 21 files changed, 325 insertions(+), 143 deletions(-) create mode 100644 src/test/ui/parser/bad-if-statements.rs create mode 100644 src/test/ui/parser/bad-if-statements.stderr create mode 100644 src/test/ui/parser/if-block-unreachable-expr.rs diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b224fa9596eb8..81bab0e3513c9 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2248,36 +2248,59 @@ impl<'a> Parser<'a> { &mut self, attrs: AttrVec, lo: Span, - cond: P, + mut cond: P, ) -> PResult<'a, P> { - let missing_then_block_binop_span = || { - match cond.kind { - ExprKind::Binary(Spanned { span: binop_span, .. }, _, ref right) - if let ExprKind::Block(..) = right.kind => Some(binop_span), - _ => None + let cond_span = cond.span; + // Tries to interpret `cond` as either a missing expression if it's a block, + // or as an unfinished expression if it's a binop and the RHS is a block. + // We could probably add more recoveries here too... + let mut recover_block_from_condition = |this: &mut Self| { + let block = match &mut cond.kind { + ExprKind::Binary(Spanned { span: binop_span, .. }, _, right) + if let ExprKind::Block(_, None) = right.kind => { + this.error_missing_if_then_block(lo, cond_span.shrink_to_lo().to(*binop_span), true).emit(); + std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi())) + }, + ExprKind::Block(_, None) => { + this.error_missing_if_cond(lo, cond_span).emit(); + std::mem::replace(&mut cond, this.mk_expr_err(cond_span.shrink_to_hi())) + } + _ => { + return None; + } + }; + if let ExprKind::Block(block, _) = &block.kind { + Some(block.clone()) + } else { + unreachable!() } }; - // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then - // verify that the last statement is either an implicit return (no `;`) or an explicit - // return. This won't catch blocks with an explicit `return`, but that would be caught by - // the dead code lint. - let thn = if self.token.is_keyword(kw::Else) || !cond.returns() { - if let Some(binop_span) = missing_then_block_binop_span() { - self.error_missing_if_then_block(lo, None, Some(binop_span)).emit(); - self.mk_block_err(cond.span) + // Parse then block + let thn = if self.token.is_keyword(kw::Else) { + if let Some(block) = recover_block_from_condition(self) { + block } else { - self.error_missing_if_cond(lo, cond.span) + self.error_missing_if_then_block(lo, cond_span, false).emit(); + self.mk_block_err(cond_span.shrink_to_hi()) } } else { let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery. - let not_block = self.token != token::OpenDelim(Delimiter::Brace); - let block = self.parse_block().map_err(|err| { - if not_block { - self.error_missing_if_then_block(lo, Some(err), missing_then_block_binop_span()) + let block = if self.check(&token::OpenDelim(Delimiter::Brace)) { + self.parse_block()? + } else { + if let Some(block) = recover_block_from_condition(self) { + block } else { - err + // Parse block, which will always fail, but we can add a nice note to the error + self.parse_block().map_err(|mut err| { + err.span_note( + cond_span, + "the `if` expression is missing a block after this condition", + ); + err + })? } - })?; + }; self.error_on_if_block_attrs(lo, false, block.span, &attrs); block }; @@ -2288,31 +2311,34 @@ impl<'a> Parser<'a> { fn error_missing_if_then_block( &self, if_span: Span, - err: Option>, - binop_span: Option, + cond_span: Span, + is_unfinished: bool, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let msg = "this `if` expression has a condition, but no block"; - - let mut err = if let Some(mut err) = err { - err.span_label(if_span, msg); - err + let mut err = self.struct_span_err( + if_span, + "this `if` expression is missing a block after the condition", + ); + if is_unfinished { + err.span_help(cond_span, "this binary operation is possibly unfinished"); } else { - self.struct_span_err(if_span, msg) - }; - - if let Some(binop_span) = binop_span { - err.span_help(binop_span, "maybe you forgot the right operand of the condition?"); + err.span_help(cond_span.shrink_to_hi(), "add a block here"); } - err } - fn error_missing_if_cond(&self, lo: Span, span: Span) -> P { - let sp = self.sess.source_map().next_point(lo); - self.struct_span_err(sp, "missing condition for `if` expression") - .span_label(sp, "expected if condition here") - .emit(); - self.mk_block_err(span) + fn error_missing_if_cond( + &self, + lo: Span, + span: Span, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let next_span = self.sess.source_map().next_point(lo); + let mut err = self.struct_span_err(next_span, "missing condition for `if` expression"); + err.span_label(next_span, "expected condition here"); + err.span_label( + self.sess.source_map().start_point(span), + "if this block is the condition of the `if` expression, then it must be followed by another block" + ); + err } /// Parses the condition of a `if` or `while` expression. diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 42355dd93a7a5..51bd9d2d386ad 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -432,10 +432,23 @@ impl<'a> Parser<'a> { // // which is valid in other languages, but not Rust. match self.parse_stmt_without_recovery(false, ForceCollect::No) { - // If the next token is an open brace (e.g., `if a b {`), the place- - // inside-a-block suggestion would be more likely wrong than right. + // If the next token is an open brace, e.g., we have: + // + // if expr other_expr { + // ^ ^ ^- lookahead(1) is a brace + // | |- current token is not "else" + // |- (statement we just parsed) + // + // the place-inside-a-block suggestion would be more likely wrong than right. + // + // FIXME(compiler-errors): this should probably parse an arbitrary expr and not + // just lookahead one token, so we can see if there's a brace after _that_, + // since we want to protect against: + // `if 1 1 + 1 {` being suggested as `if { 1 } 1 + 1 {` + // + + Ok(Some(_)) - if self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)) + if (!self.token.is_keyword(kw::Else) + && self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))) || do_not_suggest_help => {} // Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836). Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {} diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr index 609a5efd46fee..3ccc14bba5422 100644 --- a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr +++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr @@ -25,10 +25,16 @@ LL | println!("Then when?"); error: expected `{`, found `;` --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31 | -LL | if not // lack of braces is [sic] - | -- this `if` expression has a condition, but no block LL | println!("Then when?"); | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:19:8 + | +LL | if not // lack of braces is [sic] + | ________^ +LL | | println!("Then when?"); + | |______________________________^ error: unexpected `2` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24 diff --git a/src/test/ui/expr/if/if-without-block.rs b/src/test/ui/expr/if/if-without-block.rs index 8a4c59f32613d..5add9dfda4b9d 100644 --- a/src/test/ui/expr/if/if-without-block.rs +++ b/src/test/ui/expr/if/if-without-block.rs @@ -1,9 +1,7 @@ fn main() { let n = 1; if 5 == { - //~^ NOTE this `if` expression has a condition, but no block + //~^ ERROR this `if` expression is missing a block after the condition println!("five"); } } -//~^ ERROR expected `{`, found `}` -//~| NOTE expected `{` diff --git a/src/test/ui/expr/if/if-without-block.stderr b/src/test/ui/expr/if/if-without-block.stderr index d3f6ca07617f4..2d1ee04ce09a8 100644 --- a/src/test/ui/expr/if/if-without-block.stderr +++ b/src/test/ui/expr/if/if-without-block.stderr @@ -1,17 +1,14 @@ -error: expected `{`, found `}` - --> $DIR/if-without-block.rs:7:1 +error: this `if` expression is missing a block after the condition + --> $DIR/if-without-block.rs:3:5 | LL | if 5 == { - | -- this `if` expression has a condition, but no block -... -LL | } - | ^ expected `{` + | ^^ | -help: maybe you forgot the right operand of the condition? - --> $DIR/if-without-block.rs:3:10 +help: this binary operation is possibly unfinished + --> $DIR/if-without-block.rs:3:8 | LL | if 5 == { - | ^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-39848.stderr b/src/test/ui/issues/issue-39848.stderr index feabe3814dcf9..387ef0776ff4a 100644 --- a/src/test/ui/issues/issue-39848.stderr +++ b/src/test/ui/issues/issue-39848.stderr @@ -2,13 +2,19 @@ error: expected `{`, found `foo` --> $DIR/issue-39848.rs:3:21 | LL | if $tgt.has_$field() {} - | -- ^^^^^^ expected `{` - | | - | this `if` expression has a condition, but no block + | ^^^^^^ expected `{` ... LL | get_opt!(bar, foo); | ------------------ in this macro invocation | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-39848.rs:3:12 + | +LL | if $tgt.has_$field() {} + | ^^^^^^^^^ +... +LL | get_opt!(bar, foo); + | ------------------ in this macro invocation = note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info) help: try placing this code inside a block | diff --git a/src/test/ui/missing/missing-block-hint.stderr b/src/test/ui/missing/missing-block-hint.stderr index 148e214e58ec1..16954223a4521 100644 --- a/src/test/ui/missing/missing-block-hint.stderr +++ b/src/test/ui/missing/missing-block-hint.stderr @@ -2,18 +2,25 @@ error: expected `{`, found `=>` --> $DIR/missing-block-hint.rs:3:18 | LL | if (foo) => {} - | -- ^^ expected `{` - | | - | this `if` expression has a condition, but no block + | ^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/missing-block-hint.rs:3:12 + | +LL | if (foo) => {} + | ^^^^^ error: expected `{`, found `bar` --> $DIR/missing-block-hint.rs:7:13 | -LL | if (foo) - | -- this `if` expression has a condition, but no block LL | bar; | ^^^ expected `{` | +note: the `if` expression is missing a block after this condition + --> $DIR/missing-block-hint.rs:6:12 + | +LL | if (foo) + | ^^^^^ help: try placing this code inside a block | LL | { bar; } diff --git a/src/test/ui/parser/bad-if-statements.rs b/src/test/ui/parser/bad-if-statements.rs new file mode 100644 index 0000000000000..2c501e3a5b399 --- /dev/null +++ b/src/test/ui/parser/bad-if-statements.rs @@ -0,0 +1,38 @@ +fn a() { + if {} + //~^ ERROR missing condition for `if` expression +} + +fn b() { + if true && {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn c() { + let x = {}; + if true x + //~^ ERROR expected `{`, found `x` +} + +fn a2() { + if {} else {} + //~^ ERROR missing condition for `if` expression +} + +fn b2() { + if true && {} else {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn c2() { + let x = {}; + if true x else {} + //~^ ERROR expected `{`, found `x` +} + +fn d() { + if true else {} + //~^ ERROR this `if` expression is missing a block after the condition +} + +fn main() {} diff --git a/src/test/ui/parser/bad-if-statements.stderr b/src/test/ui/parser/bad-if-statements.stderr new file mode 100644 index 0000000000000..ee839db645509 --- /dev/null +++ b/src/test/ui/parser/bad-if-statements.stderr @@ -0,0 +1,86 @@ +error: missing condition for `if` expression + --> $DIR/bad-if-statements.rs:2:7 + | +LL | if {} + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:7:5 + | +LL | if true && {} + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/bad-if-statements.rs:7:8 + | +LL | if true && {} + | ^^^^^^^ + +error: expected `{`, found `x` + --> $DIR/bad-if-statements.rs:13:13 + | +LL | if true x + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/bad-if-statements.rs:13:8 + | +LL | if true x + | ^^^^ +help: try placing this code inside a block + | +LL | if true { x } + | + + + +error: missing condition for `if` expression + --> $DIR/bad-if-statements.rs:18:7 + | +LL | if {} else {} + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:23:5 + | +LL | if true && {} else {} + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/bad-if-statements.rs:23:8 + | +LL | if true && {} else {} + | ^^^^^^^ + +error: expected `{`, found `x` + --> $DIR/bad-if-statements.rs:29:13 + | +LL | if true x else {} + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/bad-if-statements.rs:29:8 + | +LL | if true x else {} + | ^^^^ +help: try placing this code inside a block + | +LL | if true { x } else {} + | + + + +error: this `if` expression is missing a block after the condition + --> $DIR/bad-if-statements.rs:34:5 + | +LL | if true else {} + | ^^ + | +help: add a block here + --> $DIR/bad-if-statements.rs:34:12 + | +LL | if true else {} + | ^ + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/if-block-unreachable-expr.rs b/src/test/ui/parser/if-block-unreachable-expr.rs new file mode 100644 index 0000000000000..4063a33708402 --- /dev/null +++ b/src/test/ui/parser/if-block-unreachable-expr.rs @@ -0,0 +1,8 @@ +// check-pass + +// This regressed from 1.20 -> 1.21 -- the condition is unreachable, +// but it's still an expression, and should parse fine. + +fn main() { + if { if true { return; } else { return; }; } {} +} diff --git a/src/test/ui/parser/issue-61858.stderr b/src/test/ui/parser/issue-61858.stderr index 8b95d9c6ae48b..03f51c6e3a8f4 100644 --- a/src/test/ui/parser/issue-61858.stderr +++ b/src/test/ui/parser/issue-61858.stderr @@ -2,9 +2,13 @@ error: expected `{`, found `)` --> $DIR/issue-61858.rs:2:15 | LL | (if foobar) - | -- ^ expected `{` - | | - | this `if` expression has a condition, but no block + | ^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-61858.rs:2:9 + | +LL | (if foobar) + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs index 00f90cc73b344..57d36feb37b13 100644 --- a/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs +++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.rs @@ -1,7 +1,8 @@ macro_rules! x { ($($c:tt)*) => { - $($c)ö* {} //~ ERROR missing condition for `if` expression - }; //~| ERROR mismatched types + $($c)ö* {} + //~^ ERROR missing condition for `if` expression + }; } fn main() { diff --git a/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr index cdd4c670500f0..6674b924e9c4b 100644 --- a/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr +++ b/src/test/ui/parser/issue-68091-unicode-ident-after-if.stderr @@ -2,19 +2,9 @@ error: missing condition for `if` expression --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14 | LL | $($c)ö* {} - | ^ expected if condition here + | ^ - if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here -error[E0308]: mismatched types - --> $DIR/issue-68091-unicode-ident-after-if.rs:3:17 - | -LL | $($c)ö* {} - | ^^ expected `bool`, found `()` -... -LL | x!(if); - | ------ in this macro invocation - | - = note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issue-91421.rs b/src/test/ui/parser/issue-91421.rs index 9959df5663837..8bba27f372439 100644 --- a/src/test/ui/parser/issue-91421.rs +++ b/src/test/ui/parser/issue-91421.rs @@ -2,9 +2,8 @@ fn main() { let value = if true && { - //~^ ERROR: this `if` expression has a condition, but no block - //~| HELP: maybe you forgot the right operand of the condition? + //~^ ERROR: this `if` expression is missing a block after the condition + //~| HELP: this binary operation is possibly unfinished 3 - //~^ ERROR: mismatched types [E0308] } else { 4 }; } diff --git a/src/test/ui/parser/issue-91421.stderr b/src/test/ui/parser/issue-91421.stderr index 04284d5e3b2f7..2d9652051dd56 100644 --- a/src/test/ui/parser/issue-91421.stderr +++ b/src/test/ui/parser/issue-91421.stderr @@ -1,21 +1,14 @@ -error: this `if` expression has a condition, but no block +error: this `if` expression is missing a block after the condition --> $DIR/issue-91421.rs:4:17 | LL | let value = if true && { | ^^ | -help: maybe you forgot the right operand of the condition? - --> $DIR/issue-91421.rs:4:25 +help: this binary operation is possibly unfinished + --> $DIR/issue-91421.rs:4:20 | LL | let value = if true && { - | ^^ + | ^^^^^^^ -error[E0308]: mismatched types - --> $DIR/issue-91421.rs:7:9 - | -LL | 3 - | ^ expected `bool`, found integer - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-13483.rs b/src/test/ui/parser/issues/issue-13483.rs index a2fd9264b1530..4e32fcab3f098 100644 --- a/src/test/ui/parser/issues/issue-13483.rs +++ b/src/test/ui/parser/issues/issue-13483.rs @@ -1,15 +1,15 @@ fn main() { if true { - } else if { //~ ERROR missing condition - //~^ ERROR mismatched types + } else if { + //~^ ERROR missing condition for `if` expression } else { } } fn foo() { if true { - } else if { //~ ERROR missing condition - //~^ ERROR mismatched types + } else if { + //~^ ERROR missing condition for `if` expression } bar(); } diff --git a/src/test/ui/parser/issues/issue-13483.stderr b/src/test/ui/parser/issues/issue-13483.stderr index 5fd05b18ce06e..f5534090f18a4 100644 --- a/src/test/ui/parser/issues/issue-13483.stderr +++ b/src/test/ui/parser/issues/issue-13483.stderr @@ -2,32 +2,17 @@ error: missing condition for `if` expression --> $DIR/issue-13483.rs:3:14 | LL | } else if { - | ^ expected if condition here + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here error: missing condition for `if` expression --> $DIR/issue-13483.rs:11:14 | LL | } else if { - | ^ expected if condition here + | ^- if this block is the condition of the `if` expression, then it must be followed by another block + | | + | expected condition here -error[E0308]: mismatched types - --> $DIR/issue-13483.rs:3:15 - | -LL | } else if { - | _______________^ -LL | | -LL | | } else { - | |_____^ expected `bool`, found `()` - -error[E0308]: mismatched types - --> $DIR/issue-13483.rs:11:15 - | -LL | } else if { - | _______________^ -LL | | -LL | | } - | |_____^ expected `bool`, found `()` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/issues/issue-51602.stderr b/src/test/ui/parser/issues/issue-51602.stderr index d800890bca38d..4a5653fdb513e 100644 --- a/src/test/ui/parser/issues/issue-51602.stderr +++ b/src/test/ui/parser/issues/issue-51602.stderr @@ -2,9 +2,13 @@ error: expected `{`, found keyword `in` --> $DIR/issue-51602.rs:2:10 | LL | if i in 1..10 { - | -- ^^ expected `{` - | | - | this `if` expression has a condition, but no block + | ^^ expected `{` + | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-51602.rs:2:8 + | +LL | if i in 1..10 { + | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-62554.stderr b/src/test/ui/parser/issues/issue-62554.stderr index 3589016e1dc83..9e62572e388fd 100644 --- a/src/test/ui/parser/issues/issue-62554.stderr +++ b/src/test/ui/parser/issues/issue-62554.stderr @@ -57,10 +57,13 @@ error: expected `{`, found `macro_rules` --> $DIR/issue-62554.rs:6:23 | LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { - | -- ^^^^^^^^^^^ expected `{` - | | - | this `if` expression has a condition, but no block + | ^^^^^^^^^^^ expected `{` | +note: the `if` expression is missing a block after this condition + --> $DIR/issue-62554.rs:6:20 + | +LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + | ^^ help: try placing this code inside a block | LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { } diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs index e24649ea044f5..e66caa19ec96b 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs @@ -21,15 +21,15 @@ fn main() { }; if let Some(n) = opt else { - //~^ ERROR missing condition for `if` expression + //~^ ERROR this `if` expression is missing a block after the condition return; }; if let Some(n) = opt && n == 1 else { - //~^ ERROR missing condition for `if` expression + //~^ ERROR this `if` expression is missing a block after the condition return; }; if let Some(n) = opt && let another = n else { - //~^ ERROR missing condition for `if` expression + //~^ ERROR this `if` expression is missing a block after the condition return; }; diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index aebfc1a72b7aa..eea8ed0c9633e 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -20,23 +20,41 @@ help: wrap the expression in parentheses LL | let Some(n) = (opt && let another = n) else { | + + -error: missing condition for `if` expression - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:7 +error: this `if` expression is missing a block after the condition + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5 | LL | if let Some(n) = opt else { - | ^ expected if condition here + | ^^ + | +help: add a block here + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25 + | +LL | if let Some(n) = opt else { + | ^ -error: missing condition for `if` expression - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:7 +error: this `if` expression is missing a block after the condition + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5 | LL | if let Some(n) = opt && n == 1 else { - | ^ expected if condition here + | ^^ + | +help: add a block here + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35 + | +LL | if let Some(n) = opt && n == 1 else { + | ^ -error: missing condition for `if` expression - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:7 +error: this `if` expression is missing a block after the condition + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5 + | +LL | if let Some(n) = opt && let another = n else { + | ^^ + | +help: add a block here + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44 | LL | if let Some(n) = opt && let another = n else { - | ^ expected if condition here + | ^ error: expected `{`, found keyword `else` --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33