Skip to content

Commit a4ee3ca

Browse files
committed
Suggest semicolon removal on prior match arm
1 parent 86df903 commit a4ee3ca

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

Diff for: compiler/rustc_typeck/src/check/_match.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
188188
}
189189
}
190190
} else {
191-
let (arm_span, semi_span) = if let hir::ExprKind::Block(blk, _) = &arm.body.kind {
191+
let (arm_span, mut semi_span) = if let hir::ExprKind::Block(blk, _) = &arm.body.kind
192+
{
192193
self.find_block_span(blk, prior_arm_ty)
193194
} else {
194195
(arm.body.span, None)
195196
};
197+
if semi_span.is_none() && i > 0 {
198+
if let hir::ExprKind::Block(blk, _) = &arms[i - 1].body.kind {
199+
let (_, semi_span_prev) = self.find_block_span(blk, Some(arm_ty));
200+
semi_span = semi_span_prev;
201+
}
202+
}
196203
let (span, code) = match i {
197204
// The reason for the first arm to fail is not that the match arms diverge,
198205
// but rather that there's a prior obligation that doesn't hold.
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// edition:2018
2+
3+
fn dummy() -> i32 { 42 }
4+
5+
fn extra_semicolon() {
6+
let _ = match true { //~ NOTE `match` arms have incompatible types
7+
true => {
8+
dummy(); //~ NOTE this is found to be
9+
//~^ HELP consider removing this semicolon
10+
}
11+
false => dummy(), //~ ERROR `match` arms have incompatible types
12+
//~^ NOTE expected `()`, found `i32`
13+
};
14+
}
15+
16+
async fn async_dummy() {} //~ NOTE the `Output` of this `async fn`'s found opaque type
17+
18+
async fn async_extra_semicolon_same() {
19+
let _ = match true { //~ NOTE `match` arms have incompatible types
20+
true => {
21+
async_dummy(); //~ NOTE this is found to be
22+
//~^ HELP consider removing this semicolon
23+
}
24+
false => async_dummy(), //~ ERROR `match` arms have incompatible types
25+
//~^ NOTE expected `()`, found opaque type
26+
//~| NOTE expected type `()`
27+
//~| HELP consider `await`ing on the `Future`
28+
};
29+
}
30+
31+
fn main() {}
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0308]: `match` arms have incompatible types
2+
--> $DIR/match-prev-arm-needing-semi.rs:24:18
3+
|
4+
LL | async fn async_dummy() {}
5+
| - the `Output` of this `async fn`'s found opaque type
6+
...
7+
LL | let _ = match true {
8+
| _____________-
9+
LL | | true => {
10+
LL | | async_dummy();
11+
| | -------------- this is found to be of type `()`
12+
LL | |
13+
LL | | }
14+
LL | | false => async_dummy(),
15+
| | ^^^^^^^^^^^^^ expected `()`, found opaque type
16+
... |
17+
LL | |
18+
LL | | };
19+
| |_____- `match` arms have incompatible types
20+
|
21+
= note: expected type `()`
22+
found opaque type `impl Future`
23+
help: consider removing this semicolon
24+
|
25+
LL | async_dummy()
26+
| --
27+
help: consider `await`ing on the `Future`
28+
|
29+
LL | false => async_dummy().await,
30+
| ^^^^^^
31+
32+
error[E0308]: `match` arms have incompatible types
33+
--> $DIR/match-prev-arm-needing-semi.rs:11:18
34+
|
35+
LL | let _ = match true {
36+
| _____________-
37+
LL | | true => {
38+
LL | | dummy();
39+
| | --------
40+
| | | |
41+
| | | help: consider removing this semicolon
42+
| | this is found to be of type `()`
43+
LL | |
44+
LL | | }
45+
LL | | false => dummy(),
46+
| | ^^^^^^^ expected `()`, found `i32`
47+
LL | |
48+
LL | | };
49+
| |_____- `match` arms have incompatible types
50+
51+
error: aborting due to 2 previous errors
52+
53+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)