// 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(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() {}