1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
//@ 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() {}
|