From 9946ff227d3b1ec7ee5de9ef9b2f81ee4547df34 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sun, 11 Jul 2021 17:04:11 +0200 Subject: [PATCH] Do not suggest adding a semicolon after `?` --- compiler/rustc_typeck/src/check/coercion.rs | 10 ++++-- .../try-operator-dont-suggest-semicolon.rs | 27 +++++++++++++++ ...try-operator-dont-suggest-semicolon.stderr | 33 +++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs create mode 100644 src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index afa4d0f1c4de9..9e89804b74713 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1456,11 +1456,15 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expected.is_unit(), pointing_at_return_type, ) { - // If the block is from an external macro, then do not suggest - // adding a semicolon, because there's nowhere to put it. - // See issue #81943. + // If the block is from an external macro or try (`?`) desugaring, then + // do not suggest adding a semicolon, because there's nowhere to put it. + // See issues #81943 and #87051. if cond_expr.span.desugaring_kind().is_none() && !in_external_macro(fcx.tcx.sess, cond_expr.span) + && !matches!( + cond_expr.kind, + hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) + ) { err.span_label(cond_expr.span, "expected this to be `()`"); if expr.can_have_side_effects() { diff --git a/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs new file mode 100644 index 0000000000000..f882a159f9834 --- /dev/null +++ b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs @@ -0,0 +1,27 @@ +// Regression test for #87051, where a double semicolon was erroneously +// suggested after a `?` operator. + +fn main() -> Result<(), ()> { + a(|| { + b() + //~^ ERROR: mismatched types [E0308] + //~| NOTE: expected `()`, found `i32` + //~| HELP: consider using a semicolon here + })?; + + // Here, we do want to suggest a semicolon: + let x = Ok(42); + if true { + //~^ NOTE: expected this to be `()` + x? + //~^ ERROR: mismatched types [E0308] + //~| NOTE: expected `()`, found integer + //~| HELP: consider using a semicolon here + } + //~^ HELP: consider using a semicolon here + + Ok(()) +} + +fn a(f: F) -> Result<(), ()> where F: FnMut() { Ok(()) } +fn b() -> i32 { 42 } diff --git a/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr new file mode 100644 index 0000000000000..4f7e18742e22e --- /dev/null +++ b/src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/try-operator-dont-suggest-semicolon.rs:6:9 + | +LL | b() + | ^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/try-operator-dont-suggest-semicolon.rs:16:9 + | +LL | / if true { +LL | | +LL | | x? + | | ^^ expected `()`, found integer +LL | | +LL | | +LL | | +LL | | } + | |_____- expected this to be `()` + | +help: consider using a semicolon here + | +LL | x?; + | ^ +help: consider using a semicolon here + | +LL | }; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.