Auto merge of #56110 - varkor:inhabitedness-union-enum, r=cramertj
Consider references and unions potentially inhabited during privacy-respecting inhabitedness checks It isn't settled exactly how references to uninhabited types and unions of uninhabited types should act, but we should be more conservative here, as it's likely it will be permitted to soundly have values of such types. This will also be more important in light of the changes at https://github.com/rust-lang/rust/pull/54125. cc @RalfJung
This commit is contained in:
commit
b817d0b651
9 changed files with 105 additions and 61 deletions
32
src/test/ui/always-inhabited-union-ref.rs
Normal file
32
src/test/ui/always-inhabited-union-ref.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// The precise semantics of inhabitedness with respect to unions and references is currently
|
||||
// undecided. This test file currently checks a conservative choice.
|
||||
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
pub union Foo {
|
||||
foo: !,
|
||||
}
|
||||
|
||||
fn uninhab_ref() -> &'static ! {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn uninhab_union() -> Foo {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn match_on_uninhab() {
|
||||
match uninhab_ref() {
|
||||
//~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
|
||||
}
|
||||
|
||||
match uninhab_union() {
|
||||
//~^ ERROR non-exhaustive patterns: type `Foo` is non-empty
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
27
src/test/ui/always-inhabited-union-ref.stderr
Normal file
27
src/test/ui/always-inhabited-union-ref.stderr
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
|
||||
--> $DIR/always-inhabited-union-ref.rs:23:11
|
||||
|
|
||||
LL | match uninhab_ref() {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
--> $DIR/always-inhabited-union-ref.rs:23:11
|
||||
|
|
||||
LL | match uninhab_ref() {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
|
||||
--> $DIR/always-inhabited-union-ref.rs:27:11
|
||||
|
|
||||
LL | match uninhab_union() {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
--> $DIR/always-inhabited-union-ref.rs:27:11
|
||||
|
|
||||
LL | match uninhab_union() {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0004`.
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2012-2014 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.
|
||||
|
||||
// error-pattern:reached recursion limit
|
||||
|
||||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
||||
struct Foo<'a, T: 'a> {
|
||||
ph: std::marker::PhantomData<T>,
|
||||
foo: &'a Foo<'a, (T, T)>,
|
||||
}
|
||||
|
||||
fn wub(f: Foo<!>) {
|
||||
match f {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -33,7 +33,10 @@ fn test_a() {
|
|||
|
||||
fn test_b() {
|
||||
let x: Option<Bar> = None;
|
||||
match x { None => () }
|
||||
match x {
|
||||
Some(_) => (),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -8,14 +8,26 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-fail
|
||||
|
||||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
fn main() {
|
||||
let x: &[!] = &[];
|
||||
enum Void {}
|
||||
|
||||
for _ in x {}
|
||||
impl Iterator for Void {
|
||||
type Item = Void;
|
||||
|
||||
fn next(&mut self) -> Option<Void> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for _ in unimplemented!() as Void {}
|
||||
//~^ ERROR unreachable pattern
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/unreachable-loop-patterns.rs:18:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:30:9
|
||||
|
|
||||
LL | for _ in x {}
|
||||
LL | for _ in unimplemented!() as Void {}
|
||||
| ^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/unreachable-loop-patterns.rs:13:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:17:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue