about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-10-21 19:08:28 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-10-23 08:02:58 -0700
commita4ee3ca1e4f1177516139a4704456958c7d08c91 (patch)
treeaebc14c2bd85647d35adf001959a602639f6ae98
parent86df9039b2a49dde3a2453d75c4c58540a568a1a (diff)
downloadrust-a4ee3ca1e4f1177516139a4704456958c7d08c91.tar.gz
rust-a4ee3ca1e4f1177516139a4704456958c7d08c91.zip
Suggest semicolon removal on prior match arm
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs9
-rw-r--r--src/test/ui/suggestions/match-prev-arm-needing-semi.rs32
-rw-r--r--src/test/ui/suggestions/match-prev-arm-needing-semi.stderr53
3 files changed, 93 insertions, 1 deletions
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`.