Skip to content

Commit 02e95c9

Browse files
committed
Never pattern in let statement diverges
1 parent 6ff1daf commit 02e95c9

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14731473
/// Type check a `let` statement.
14741474
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
14751475
self.check_decl(local.into());
1476+
if local.pat.is_never_pattern() {
1477+
self.diverges.set(Diverges::Always {
1478+
span: local.pat.span,
1479+
custom_note: Some("any code following a never pattern is unreachable"),
1480+
});
1481+
}
14761482
}
14771483

14781484
pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {

tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ fn ref_never_arg(&!: &Void) -> u32 {
1717
//~^ ERROR unreachable statement
1818
}
1919

20-
//fn never_let() -> u32 {
21-
// let ptr: *const Void = std::ptr::null();
22-
// unsafe {
23-
// let ! = *ptr;
24-
// }
25-
// println!();
26-
//}
20+
fn never_let() -> u32 {
21+
let ptr: *const Void = std::ptr::null();
22+
unsafe {
23+
let ! = *ptr;
24+
}
25+
println!();
26+
//~^ ERROR unreachable statement
27+
}
2728

2829
fn never_match() -> u32 {
2930
let ptr: *const Void = std::ptr::null();

tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,18 @@ LL | println!();
2424
= note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
2525

2626
error: unreachable statement
27-
--> $DIR/diverge-causes-unreachable-code.rs:33:5
27+
--> $DIR/diverge-causes-unreachable-code.rs:25:5
28+
|
29+
LL | let ! = *ptr;
30+
| - any code following a never pattern is unreachable
31+
LL | }
32+
LL | println!();
33+
| ^^^^^^^^^^ unreachable statement
34+
|
35+
= note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
36+
37+
error: unreachable statement
38+
--> $DIR/diverge-causes-unreachable-code.rs:34:5
2839
|
2940
LL | match *ptr { ! };
3041
| ---------------- any code following this `match` expression is unreachable, as all arms diverge
@@ -34,5 +45,5 @@ LL | println!();
3445
|
3546
= note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
3647

37-
error: aborting due to 3 previous errors
48+
error: aborting due to 4 previous errors
3849

tests/ui/rfcs/rfc-0000-never_patterns/diverges.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ fn never_arg(!: Void) -> u32 {}
1313

1414
fn ref_never_arg(&!: &Void) -> u32 {}
1515

16-
// fn never_let() -> u32 {
17-
// let ptr: *const Void = std::ptr::null();
18-
// unsafe {
19-
// let ! = *ptr;
20-
// }
21-
// }
16+
fn never_let() -> u32 {
17+
let ptr: *const Void = std::ptr::null();
18+
unsafe {
19+
let ! = *ptr;
20+
}
21+
}
2222

2323
fn never_match() -> u32 {
2424
let ptr: *const Void = std::ptr::null();

0 commit comments

Comments
 (0)