From a4ee3ca1e4f1177516139a4704456958c7d08c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 21 Oct 2020 19:08:28 -0700 Subject: [PATCH] Suggest semicolon removal on prior match arm --- compiler/rustc_typeck/src/check/_match.rs | 9 +++- .../match-prev-arm-needing-semi.rs | 32 +++++++++++ .../match-prev-arm-needing-semi.stderr | 53 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/match-prev-arm-needing-semi.rs create mode 100644 src/test/ui/suggestions/match-prev-arm-needing-semi.stderr diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 398e013e62f..94e886be54d 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -188,11 +188,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } else { - let (arm_span, semi_span) = if let hir::ExprKind::Block(blk, _) = &arm.body.kind { + let (arm_span, mut semi_span) = if let hir::ExprKind::Block(blk, _) = &arm.body.kind + { self.find_block_span(blk, prior_arm_ty) } else { (arm.body.span, None) }; + if semi_span.is_none() && i > 0 { + if let hir::ExprKind::Block(blk, _) = &arms[i - 1].body.kind { + let (_, semi_span_prev) = self.find_block_span(blk, Some(arm_ty)); + semi_span = semi_span_prev; + } + } let (span, code) = match i { // The reason for the first arm to fail is not that the match arms diverge, // but rather that there's a prior obligation that doesn't hold. diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs new file mode 100644 index 00000000000..d8d6de4bf55 --- /dev/null +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs @@ -0,0 +1,32 @@ +// edition:2018 + +fn dummy() -> i32 { 42 } + +fn extra_semicolon() { + let _ = match true { //~ NOTE `match` arms have incompatible types + true => { + dummy(); //~ NOTE this is found to be + //~^ HELP consider removing this semicolon + } + false => dummy(), //~ ERROR `match` arms have incompatible types + //~^ NOTE expected `()`, found `i32` + }; +} + +async fn async_dummy() {} //~ NOTE the `Output` of this `async fn`'s found opaque type + +async fn async_extra_semicolon_same() { + let _ = match true { //~ NOTE `match` arms have incompatible types + true => { + async_dummy(); //~ NOTE this is found to be + //~^ HELP consider removing this semicolon + } + false => async_dummy(), //~ ERROR `match` arms have incompatible types + //~^ NOTE expected `()`, found opaque type + //~| NOTE expected type `()` + //~| HELP consider `await`ing on the `Future` + }; +} + +fn main() {} + diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr new file mode 100644 index 00000000000..e242a018843 --- /dev/null +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -0,0 +1,53 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/match-prev-arm-needing-semi.rs:24:18 + | +LL | async fn async_dummy() {} + | - the `Output` of this `async fn`'s found opaque type +... +LL | let _ = match true { + | _____________- +LL | | true => { +LL | | async_dummy(); + | | -------------- this is found to be of type `()` +LL | | +LL | | } +LL | | false => async_dummy(), + | | ^^^^^^^^^^^^^ expected `()`, found opaque type +... | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected type `()` + found opaque type `impl Future` +help: consider removing this semicolon + | +LL | async_dummy() + | -- +help: consider `await`ing on the `Future` + | +LL | false => async_dummy().await, + | ^^^^^^ + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-prev-arm-needing-semi.rs:11:18 + | +LL | let _ = match true { + | _____________- +LL | | true => { +LL | | dummy(); + | | -------- + | | | | + | | | help: consider removing this semicolon + | | this is found to be of type `()` +LL | | +LL | | } +LL | | false => dummy(), + | | ^^^^^^^ expected `()`, found `i32` +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.