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 https://github.com/rust-lang/rust/issues/55116.
This commit is contained in:
commit
22cc2ae805
7 changed files with 65 additions and 55 deletions
|
@ -608,19 +608,20 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
|||
self.check_expr_has_type_or_error(discrim, discrim_ty);
|
||||
};
|
||||
|
||||
// If the discriminant diverges, the match is pointless (e.g.,
|
||||
// `match (return) { }`).
|
||||
self.warn_if_unreachable(expr.id, expr.span, "expression");
|
||||
|
||||
// If there are no arms, that is a diverging match; a special case.
|
||||
if arms.is_empty() {
|
||||
self.diverges.set(self.diverges.get() | Diverges::Always);
|
||||
return tcx.types.never;
|
||||
}
|
||||
|
||||
if self.diverges.get().always() {
|
||||
for arm in arms {
|
||||
self.warn_if_unreachable(arm.body.id, arm.body.span, "arm");
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we have to union together the types that the
|
||||
// arms produce and so forth.
|
||||
|
||||
let discrim_diverges = self.diverges.get();
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(unused_parens)]
|
||||
#![deny(unreachable_code)]
|
||||
|
||||
fn main() {
|
||||
match (return) { } //~ ERROR unreachable expression
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
error: unreachable expression
|
||||
--> $DIR/match-unreachable-warning-with-diverging-discrim.rs:15:5
|
||||
|
|
||||
LL | match (return) { } //~ ERROR unreachable expression
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/match-unreachable-warning-with-diverging-discrim.rs:12:9
|
||||
|
|
||||
LL | #![deny(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -13,12 +13,6 @@
|
|||
#![allow(dead_code)]
|
||||
#![deny(unreachable_code)]
|
||||
|
||||
fn a() {
|
||||
// The match is considered unreachable here, because the `return`
|
||||
// diverges:
|
||||
match {return} { } //~ ERROR unreachable
|
||||
}
|
||||
|
||||
fn b() {
|
||||
match () { () => return }
|
||||
println!("I am dead");
|
||||
|
|
|
@ -1,30 +1,23 @@
|
|||
error: unreachable expression
|
||||
--> $DIR/expr_match.rs:19:5
|
||||
error: unreachable statement
|
||||
--> $DIR/expr_match.rs:18:5
|
||||
|
|
||||
LL | match {return} { } //~ ERROR unreachable
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
LL | println!("I am dead");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/expr_match.rs:14:9
|
||||
|
|
||||
LL | #![deny(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: unreachable statement
|
||||
--> $DIR/expr_match.rs:24:5
|
||||
--> $DIR/expr_match.rs:29:5
|
||||
|
|
||||
LL | println!("I am dead");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: unreachable statement
|
||||
--> $DIR/expr_match.rs:35:5
|
||||
|
|
||||
LL | println!("I am dead");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
24
src/test/ui/unreachable/unwarned-match-on-never.rs
Normal file
24
src/test/ui/unreachable/unwarned-match-on-never.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
#![deny(unreachable_code)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
fn foo(x: !) -> bool {
|
||||
// Explicit matches on the never type are unwarned.
|
||||
match x {}
|
||||
// But matches in unreachable code are warned.
|
||||
match x {} //~ ERROR unreachable expression
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
match (return) {
|
||||
() => () //~ ERROR unreachable arm
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
return;
|
||||
match () { //~ ERROR unreachable expression
|
||||
() => (),
|
||||
}
|
||||
}
|
28
src/test/ui/unreachable/unwarned-match-on-never.stderr
Normal file
28
src/test/ui/unreachable/unwarned-match-on-never.stderr
Normal file
|
@ -0,0 +1,28 @@
|
|||
error: unreachable expression
|
||||
--> $DIR/unwarned-match-on-never.rs:10:5
|
||||
|
|
||||
LL | match x {} //~ ERROR unreachable expression
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/unwarned-match-on-never.rs:1:9
|
||||
|
|
||||
LL | #![deny(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable arm
|
||||
--> $DIR/unwarned-match-on-never.rs:15:15
|
||||
|
|
||||
LL | () => () //~ ERROR unreachable arm
|
||||
| ^^
|
||||
|
||||
error: unreachable expression
|
||||
--> $DIR/unwarned-match-on-never.rs:21:5
|
||||
|
|
||||
LL | / match () { //~ ERROR unreachable expression
|
||||
LL | | () => (),
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
Add table
Reference in a new issue