summaryrefslogtreecommitdiffstats
path: root/tests/ui/pattern/usefulness/uninhabited.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/pattern/usefulness/uninhabited.rs')
-rw-r--r--tests/ui/pattern/usefulness/uninhabited.rs143
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/ui/pattern/usefulness/uninhabited.rs b/tests/ui/pattern/usefulness/uninhabited.rs
new file mode 100644
index 000000000..5622808d4
--- /dev/null
+++ b/tests/ui/pattern/usefulness/uninhabited.rs
@@ -0,0 +1,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(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() {}