rust/tests/ui/pattern/usefulness/uninhabited.rs
Matthias Krüger 26cb6c7287
Rollup merge of #120742 - Nadrieril:use-min_exh_pats, r=compiler-errors
mark `min_exhaustive_patterns` as complete

This is step 1 and 2 of my [proposal](https://github.com/rust-lang/rust/issues/119612#issuecomment-1918097361) to move `min_exhaustive_patterns` forward. The vast majority of in-tree use cases of `exhaustive_patterns` are covered by `min_exhaustive_patterns`. There are a few cases that still require `exhaustive_patterns` in tests and they're all behind references.

r? ``@ghost``
2024-02-23 17:02:03 +01:00

144 lines
3.1 KiB
Rust

//@ check-pass
//@ aux-build:empty.rs
//
// This tests plays with matching and uninhabited types. This also serves as a test for the
// `Ty::is_inhabited_from` function.
#![feature(never_type)]
#![feature(never_type_fallback)]
#![feature(min_exhaustive_patterns)]
#![deny(unreachable_patterns)]
macro_rules! assert_empty {
($ty:ty) => {
const _: () = {
fn assert_empty(x: $ty) {
match x {}
match Some(x) {
None => {}
}
}
};
};
}
macro_rules! assert_non_empty {
($ty:ty) => {
const _: () = {
fn assert_non_empty(x: $ty) {
match x {
_ => {}
}
match Some(x) {
None => {}
Some(_) => {}
}
}
};
};
}
extern crate empty;
assert_empty!(empty::EmptyForeignEnum);
assert_empty!(empty::VisiblyUninhabitedForeignStruct);
assert_non_empty!(empty::SecretlyUninhabitedForeignStruct);
enum Void {}
assert_empty!(Void);
enum Enum2 {
Foo(Void),
Bar(!),
}
assert_empty!(Enum2);
enum Enum3 {
Foo(Void),
Bar {
x: u64,
y: !,
},
}
assert_empty!(Enum3);
enum Enum4 {
Foo(u64),
Bar(!),
}
assert_non_empty!(Enum4);
struct Struct1(empty::EmptyForeignEnum);
assert_empty!(Struct1);
struct Struct2 {
x: u64,
y: !,
}
assert_empty!(Struct2);
union Union {
foo: !,
}
assert_non_empty!(Union);
assert_empty!((!, String));
assert_non_empty!(&'static !);
assert_non_empty!(&'static Struct1);
assert_non_empty!(&'static &'static &'static !);
assert_empty!([!; 1]);
assert_empty!([Void; 2]);
assert_non_empty!([!; 0]);
assert_non_empty!(&'static [!]);
mod visibility {
/// This struct can only be seen to be inhabited in modules `b`, `c` or `d`, because otherwise
/// the uninhabitedness of both `SecretlyUninhabited` structs is hidden.
struct SometimesEmptyStruct {
x: a::b::SecretlyUninhabited,
y: c::AlsoSecretlyUninhabited,
}
/// This enum can only be seen to be inhabited in module `d`.
enum SometimesEmptyEnum {
X(c::AlsoSecretlyUninhabited),
Y(c::d::VerySecretlyUninhabited),
}
mod a {
use super::*;
pub mod b {
use super::*;
pub struct SecretlyUninhabited {
_priv: !,
}
assert_empty!(SometimesEmptyStruct);
}
assert_non_empty!(SometimesEmptyStruct);
assert_non_empty!(SometimesEmptyEnum);
}
mod c {
use super::*;
pub struct AlsoSecretlyUninhabited {
_priv: ::Struct1,
}
assert_empty!(SometimesEmptyStruct);
assert_non_empty!(SometimesEmptyEnum);
pub mod d {
use super::*;
pub struct VerySecretlyUninhabited {
_priv: !,
}
assert_empty!(SometimesEmptyStruct);
assert_empty!(SometimesEmptyEnum);
}
}
assert_non_empty!(SometimesEmptyStruct);
assert_non_empty!(SometimesEmptyEnum);
}
fn main() {}