Skip to content

Commit 22cc2ae

Browse files
committed
Auto merge of #55119 - varkor:unwarned-match-on-never, r=nikomatsakis
Allow explicit matches on ! without warning It's now possible to explicitly match on `!` without an unreachable code warning. This seems desirable as promoting explicitness. Fixes #55116.
2 parents ca2639e + 2634646 commit 22cc2ae

7 files changed

+64
-54
lines changed

src/librustc_typeck/check/_match.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -608,19 +608,20 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
608608
self.check_expr_has_type_or_error(discrim, discrim_ty);
609609
};
610610

611-
// If the discriminant diverges, the match is pointless (e.g.,
612-
// `match (return) { }`).
613-
self.warn_if_unreachable(expr.id, expr.span, "expression");
614-
615611
// If there are no arms, that is a diverging match; a special case.
616612
if arms.is_empty() {
617613
self.diverges.set(self.diverges.get() | Diverges::Always);
618614
return tcx.types.never;
619615
}
620616

617+
if self.diverges.get().always() {
618+
for arm in arms {
619+
self.warn_if_unreachable(arm.body.id, arm.body.span, "arm");
620+
}
621+
}
622+
621623
// Otherwise, we have to union together the types that the
622624
// arms produce and so forth.
623-
624625
let discrim_diverges = self.diverges.get();
625626
self.diverges.set(Diverges::Maybe);
626627

src/test/ui/match/match-unreachable-warning-with-diverging-discrim.rs

-16
This file was deleted.

src/test/ui/match/match-unreachable-warning-with-diverging-discrim.stderr

-14
This file was deleted.

src/test/ui/reachable/expr_match.rs

-6
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
#![allow(dead_code)]
1414
#![deny(unreachable_code)]
1515

16-
fn a() {
17-
// The match is considered unreachable here, because the `return`
18-
// diverges:
19-
match {return} { } //~ ERROR unreachable
20-
}
21-
2216
fn b() {
2317
match () { () => return }
2418
println!("I am dead");
+6-13
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
1-
error: unreachable expression
2-
--> $DIR/expr_match.rs:19:5
1+
error: unreachable statement
2+
--> $DIR/expr_match.rs:18:5
33
|
4-
LL | match {return} { } //~ ERROR unreachable
5-
| ^^^^^^^^^^^^^^^^^^
4+
LL | println!("I am dead");
5+
| ^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: lint level defined here
88
--> $DIR/expr_match.rs:14:9
99
|
1010
LL | #![deny(unreachable_code)]
1111
| ^^^^^^^^^^^^^^^^
12-
13-
error: unreachable statement
14-
--> $DIR/expr_match.rs:24:5
15-
|
16-
LL | println!("I am dead");
17-
| ^^^^^^^^^^^^^^^^^^^^^^
18-
|
1912
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
2013

2114
error: unreachable statement
22-
--> $DIR/expr_match.rs:35:5
15+
--> $DIR/expr_match.rs:29:5
2316
|
2417
LL | println!("I am dead");
2518
| ^^^^^^^^^^^^^^^^^^^^^^
2619
|
2720
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
2821

29-
error: aborting due to 3 previous errors
22+
error: aborting due to 2 previous errors
3023

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![deny(unreachable_code)]
2+
#![allow(dead_code)]
3+
4+
#![feature(never_type)]
5+
6+
fn foo(x: !) -> bool {
7+
// Explicit matches on the never type are unwarned.
8+
match x {}
9+
// But matches in unreachable code are warned.
10+
match x {} //~ ERROR unreachable expression
11+
}
12+
13+
fn bar() {
14+
match (return) {
15+
() => () //~ ERROR unreachable arm
16+
}
17+
}
18+
19+
fn main() {
20+
return;
21+
match () { //~ ERROR unreachable expression
22+
() => (),
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error: unreachable expression
2+
--> $DIR/unwarned-match-on-never.rs:10:5
3+
|
4+
LL | match x {} //~ ERROR unreachable expression
5+
| ^^^^^^^^^^
6+
|
7+
note: lint level defined here
8+
--> $DIR/unwarned-match-on-never.rs:1:9
9+
|
10+
LL | #![deny(unreachable_code)]
11+
| ^^^^^^^^^^^^^^^^
12+
13+
error: unreachable arm
14+
--> $DIR/unwarned-match-on-never.rs:15:15
15+
|
16+
LL | () => () //~ ERROR unreachable arm
17+
| ^^
18+
19+
error: unreachable expression
20+
--> $DIR/unwarned-match-on-never.rs:21:5
21+
|
22+
LL | / match () { //~ ERROR unreachable expression
23+
LL | | () => (),
24+
LL | | }
25+
| |_____^
26+
27+
error: aborting due to 3 previous errors
28+

0 commit comments

Comments
 (0)