summaryrefslogtreecommitdiffstats
path: root/tests/ui/rfc-2008-non-exhaustive/uninhabited
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/rfc-2008-non-exhaustive/uninhabited')
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs32
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs38
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr35
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs45
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr35
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs36
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr79
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs51
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr79
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs40
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr79
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs57
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs21
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr14
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match.rs34
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr83
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs41
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr64
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs37
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr83
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs47
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs59
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs70
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr38
24 files changed, 1197 insertions, 0 deletions
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs
new file mode 100644
index 000000000..a2735d4cb
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs
@@ -0,0 +1,32 @@
+#![crate_type = "rlib"]
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+pub enum PartiallyInhabitedVariants {
+ Tuple(u8),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+
+pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+
+pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+
+pub struct IndirectUninhabitedVariants(UninhabitedVariants);
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs
new file mode 100644
index 000000000..80b9dc4c1
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs
@@ -0,0 +1,38 @@
+// aux-build:uninhabited.rs
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ UninhabitedEnum,
+ UninhabitedStruct,
+ UninhabitedTupleStruct,
+ UninhabitedVariants,
+};
+
+// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never
+// type can.
+
+struct A;
+
+fn can_coerce_never_type_to_anything(x: !) -> A {
+ x
+}
+
+fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr
new file mode 100644
index 000000000..f8ed156b5
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions.stderr
@@ -0,0 +1,35 @@
+error[E0308]: mismatched types
+ --> $DIR/coercions.rs:23:5
+ |
+LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found enum `UninhabitedEnum`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions.rs:27:5
+ |
+LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found struct `UninhabitedTupleStruct`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions.rs:31:5
+ |
+LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found struct `UninhabitedStruct`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions.rs:35:5
+ |
+LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found enum `UninhabitedVariants`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs
new file mode 100644
index 000000000..6b911dd98
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs
@@ -0,0 +1,45 @@
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+struct A;
+
+// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce
+// to any type, as the never type can.
+
+fn can_coerce_never_type_to_anything(x: !) -> A {
+ x
+}
+
+fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+ x //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr
new file mode 100644
index 000000000..fd2c56974
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr
@@ -0,0 +1,35 @@
+error[E0308]: mismatched types
+ --> $DIR/coercions_same_crate.rs:30:5
+ |
+LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found enum `UninhabitedEnum`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions_same_crate.rs:34:5
+ |
+LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found struct `UninhabitedTupleStruct`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions_same_crate.rs:38:5
+ |
+LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found struct `UninhabitedStruct`
+
+error[E0308]: mismatched types
+ --> $DIR/coercions_same_crate.rs:42:5
+ |
+LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+ | - expected `A` because of return type
+LL | x
+ | ^ expected struct `A`, found enum `UninhabitedVariants`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs
new file mode 100644
index 000000000..98a7fdbc5
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs
@@ -0,0 +1,36 @@
+// aux-build:uninhabited.rs
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ IndirectUninhabitedEnum,
+ IndirectUninhabitedStruct,
+ IndirectUninhabitedTupleStruct,
+ IndirectUninhabitedVariants,
+};
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
+// indirection from an extern crate will not compile.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
+ x: IndirectUninhabitedVariants,
+) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
new file mode 100644
index 000000000..66e93291c
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.stderr
@@ -0,0 +1,79 @@
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty
+ --> $DIR/indirect_match.rs:19:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedEnum` defined here
+ --> $DIR/auxiliary/uninhabited.rs:26:1
+ |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
+ --> $DIR/indirect_match.rs:23:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:28:1
+ |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
+ --> $DIR/indirect_match.rs:27:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedTupleStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:30:1
+ |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
+ --> $DIR/indirect_match.rs:33:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedVariants` defined here
+ --> $DIR/auxiliary/uninhabited.rs:32:1
+ |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs
new file mode 100644
index 000000000..8f090fe88
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs
@@ -0,0 +1,51 @@
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+
+pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+
+pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+
+pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
+// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
+ x: IndirectUninhabitedVariants,
+) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr
new file mode 100644
index 000000000..c12190541
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.stderr
@@ -0,0 +1,79 @@
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty
+ --> $DIR/indirect_match_same_crate.rs:34:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedEnum` defined here
+ --> $DIR/indirect_match_same_crate.rs:20:12
+ |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
+ --> $DIR/indirect_match_same_crate.rs:38:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedStruct` defined here
+ --> $DIR/indirect_match_same_crate.rs:22:12
+ |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
+ --> $DIR/indirect_match_same_crate.rs:42:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedTupleStruct` defined here
+ --> $DIR/indirect_match_same_crate.rs:24:12
+ |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
+ --> $DIR/indirect_match_same_crate.rs:48:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedVariants` defined here
+ --> $DIR/indirect_match_same_crate.rs:26:12
+ |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs
new file mode 100644
index 000000000..be86519ec
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs
@@ -0,0 +1,40 @@
+// aux-build:uninhabited.rs
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ IndirectUninhabitedEnum,
+ IndirectUninhabitedStruct,
+ IndirectUninhabitedTupleStruct,
+ IndirectUninhabitedVariants,
+};
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type through a level of
+// indirection from an extern crate will not compile. In particular, this enables the
+// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine
+// this.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
+ x: IndirectUninhabitedVariants,
+) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
new file mode 100644
index 000000000..ef97c1fa1
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.stderr
@@ -0,0 +1,79 @@
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty
+ --> $DIR/indirect_match_with_exhaustive_patterns.rs:23:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedEnum` defined here
+ --> $DIR/auxiliary/uninhabited.rs:26:1
+ |
+LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedEnum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
+ --> $DIR/indirect_match_with_exhaustive_patterns.rs:27:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:28:1
+ |
+LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
+ --> $DIR/indirect_match_with_exhaustive_patterns.rs:31:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedTupleStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:30:1
+ |
+LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
+ --> $DIR/indirect_match_with_exhaustive_patterns.rs:37:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `IndirectUninhabitedVariants` defined here
+ --> $DIR/auxiliary/uninhabited.rs:32:1
+ |
+LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `IndirectUninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs
new file mode 100644
index 000000000..60289aa78
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs
@@ -0,0 +1,57 @@
+// check-pass
+
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+pub struct IndirectUninhabitedEnum(UninhabitedEnum);
+
+pub struct IndirectUninhabitedStruct(UninhabitedStruct);
+
+pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
+
+pub struct IndirectUninhabitedVariants(UninhabitedVariants);
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
+// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
+// change the branch used in the compiler to determine this.
+// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(
+ x: IndirectUninhabitedVariants,
+) -> A {
+ match x {}
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
new file mode 100644
index 000000000..230ac7529
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs
@@ -0,0 +1,21 @@
+// aux-build:uninhabited.rs
+#![deny(unreachable_patterns)]
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::PartiallyInhabitedVariants;
+
+// This test checks a redundant/useless pattern of a non-exhaustive enum/variant is still
+// warned against.
+
+pub fn foo(x: PartiallyInhabitedVariants) {
+ match x {
+ PartiallyInhabitedVariants::Struct { .. } => {},
+ PartiallyInhabitedVariants::Struct { .. } => {},
+ //~^ ERROR unreachable pattern
+ _ => {},
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
new file mode 100644
index 000000000..f39e6ee29
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+ --> $DIR/issue-65157-repeated-match-arm.rs:15:9
+ |
+LL | PartiallyInhabitedVariants::Struct { .. } => {},
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-65157-repeated-match-arm.rs:2:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.rs
new file mode 100644
index 000000000..e54098d4d
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.rs
@@ -0,0 +1,34 @@
+// aux-build:uninhabited.rs
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ UninhabitedEnum,
+ UninhabitedStruct,
+ UninhabitedTupleStruct,
+ UninhabitedVariants,
+};
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
+// will not compile.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
new file mode 100644
index 000000000..a9c54af04
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -0,0 +1,83 @@
+error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
+ --> $DIR/match.rs:19:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedEnum` defined here
+ --> $DIR/auxiliary/uninhabited.rs:5:1
+ |
+LL | pub enum UninhabitedEnum {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
+ --> $DIR/match.rs:23:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:9:1
+ |
+LL | pub struct UninhabitedStruct {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
+ --> $DIR/match.rs:27:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedTupleStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:14:1
+ |
+LL | pub struct UninhabitedTupleStruct(!);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ --> $DIR/match.rs:31:11
+ |
+LL | match x {}
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ |
+note: `UninhabitedVariants` defined here
+ --> $DIR/auxiliary/uninhabited.rs:17:23
+ |
+LL | pub enum UninhabitedVariants {
+ | ----------------------------
+LL | #[non_exhaustive] Tuple(!),
+ | ^^^^^ not covered
+LL | #[non_exhaustive] Struct { x: ! }
+ | ^^^^^^ not covered
+ = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ match x {
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs
new file mode 100644
index 000000000..ebbdfba15
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs
@@ -0,0 +1,41 @@
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
+// will compile.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
new file mode 100644
index 000000000..ec2a2f6f0
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.stderr
@@ -0,0 +1,64 @@
+error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
+ --> $DIR/match_same_crate.rs:30:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedStruct` defined here
+ --> $DIR/match_same_crate.rs:8:12
+ |
+LL | pub struct UninhabitedStruct {
+ | ^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
+ --> $DIR/match_same_crate.rs:34:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedTupleStruct` defined here
+ --> $DIR/match_same_crate.rs:13:12
+ |
+LL | pub struct UninhabitedTupleStruct(!);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ --> $DIR/match_same_crate.rs:38:11
+ |
+LL | match x {}
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ |
+note: `UninhabitedVariants` defined here
+ --> $DIR/match_same_crate.rs:16:23
+ |
+LL | pub enum UninhabitedVariants {
+ | -------------------
+LL | #[non_exhaustive] Tuple(!),
+ | ^^^^^ not covered
+LL | #[non_exhaustive] Struct { x: ! }
+ | ^^^^^^ not covered
+ = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ match x {
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs
new file mode 100644
index 000000000..900dfff65
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs
@@ -0,0 +1,37 @@
+// aux-build:uninhabited.rs
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ UninhabitedEnum,
+ UninhabitedStruct,
+ UninhabitedTupleStruct,
+ UninhabitedVariants,
+};
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate
+// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can
+// change the branch used in the compiler to determine this.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
+ match x {} //~ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
new file mode 100644
index 000000000..b6b777ec5
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -0,0 +1,83 @@
+error[E0004]: non-exhaustive patterns: type `UninhabitedEnum` is non-empty
+ --> $DIR/match_with_exhaustive_patterns.rs:22:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedEnum` defined here
+ --> $DIR/auxiliary/uninhabited.rs:5:1
+ |
+LL | pub enum UninhabitedEnum {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
+ --> $DIR/match_with_exhaustive_patterns.rs:26:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:9:1
+ |
+LL | pub struct UninhabitedStruct {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
+ --> $DIR/match_with_exhaustive_patterns.rs:30:11
+ |
+LL | match x {}
+ | ^
+ |
+note: `UninhabitedTupleStruct` defined here
+ --> $DIR/auxiliary/uninhabited.rs:14:1
+ |
+LL | pub struct UninhabitedTupleStruct(!);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: the matched value is of type `UninhabitedTupleStruct`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match x {
+LL + _ => todo!(),
+LL ~ }
+ |
+
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ --> $DIR/match_with_exhaustive_patterns.rs:34:11
+ |
+LL | match x {}
+ | ^ patterns `UninhabitedVariants::Tuple(_)` and `UninhabitedVariants::Struct { .. }` not covered
+ |
+note: `UninhabitedVariants` defined here
+ --> $DIR/auxiliary/uninhabited.rs:17:23
+ |
+LL | pub enum UninhabitedVariants {
+ | ----------------------------
+LL | #[non_exhaustive] Tuple(!),
+ | ^^^^^ not covered
+LL | #[non_exhaustive] Struct { x: ! }
+ | ^^^^^^ not covered
+ = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ match x {
+LL + UninhabitedVariants::Tuple(_) | UninhabitedVariants::Struct { .. } => todo!(),
+LL ~ }
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs
new file mode 100644
index 000000000..de5530485
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs
@@ -0,0 +1,47 @@
+// check-pass
+
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+struct A;
+
+// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate
+// will compile. In particular, this enables the `exhaustive_patterns` feature as this can
+// change the branch used in the compiler to determine this.
+// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+ match x {}
+}
+
+fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
+ match x {}
+}
+
+fn main() {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs
new file mode 100644
index 000000000..221b5cf6b
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs
@@ -0,0 +1,59 @@
+// aux-build:uninhabited.rs
+// build-pass (FIXME(62277): could be check-pass?)
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+ PartiallyInhabitedVariants,
+ UninhabitedEnum,
+ UninhabitedStruct,
+ UninhabitedTupleStruct,
+ UninhabitedVariants,
+};
+
+fn uninhabited_enum() -> Option<UninhabitedEnum> {
+ None
+}
+
+fn uninhabited_variant() -> Option<UninhabitedVariants> {
+ None
+}
+
+fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
+ PartiallyInhabitedVariants::Tuple(3)
+}
+
+fn uninhabited_struct() -> Option<UninhabitedStruct> {
+ None
+}
+
+fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
+ None
+}
+
+// This test checks that non-exhaustive types that would normally be considered uninhabited within
+// the defining crate are not considered uninhabited from extern crates.
+
+fn main() {
+ match uninhabited_enum() {
+ Some(_x) => (), // This line would normally error.
+ None => (),
+ }
+
+ match uninhabited_variant() {
+ Some(_x) => (), // This line would normally error.
+ None => (),
+ }
+
+ // This line would normally error.
+ while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {
+ }
+
+ while let Some(_x) = uninhabited_struct() { // This line would normally error.
+ }
+
+ while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
+ }
+}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
new file mode 100644
index 000000000..ffc496a97
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs
@@ -0,0 +1,70 @@
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+#[non_exhaustive]
+pub struct UninhabitedTupleStruct(!);
+
+#[non_exhaustive]
+pub struct UninhabitedStruct {
+ _priv: !,
+}
+
+pub enum UninhabitedVariants {
+ #[non_exhaustive] Tuple(!),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+pub enum PartiallyInhabitedVariants {
+ Tuple(u8),
+ #[non_exhaustive] Struct { x: ! }
+}
+
+fn uninhabited_enum() -> Option<UninhabitedEnum> {
+ None
+}
+
+fn uninhabited_variant() -> Option<UninhabitedVariants> {
+ None
+}
+
+fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
+ PartiallyInhabitedVariants::Tuple(3)
+}
+
+fn uninhabited_struct() -> Option<UninhabitedStruct> {
+ None
+}
+
+fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
+ None
+}
+
+// This test checks that non-exhaustive types that would normally be considered uninhabited within
+// the defining crate are still considered uninhabited.
+
+fn main() {
+ match uninhabited_enum() {
+ Some(_x) => (), //~ ERROR unreachable pattern
+ None => (),
+ }
+
+ match uninhabited_variant() {
+ Some(_x) => (), //~ ERROR unreachable pattern
+ None => (),
+ }
+
+ while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
+ //~^ ERROR unreachable pattern
+ }
+
+ while let Some(_x) = uninhabited_struct() { //~ ERROR unreachable pattern
+ }
+
+ while let Some(_x) = uninhabited_tuple_struct() { //~ ERROR unreachable pattern
+ }
+}
diff --git a/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
new file mode 100644
index 000000000..8bfd6e91f
--- /dev/null
+++ b/tests/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr
@@ -0,0 +1,38 @@
+error: unreachable pattern
+ --> $DIR/patterns_same_crate.rs:52:9
+ |
+LL | Some(_x) => (),
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/patterns_same_crate.rs:1:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/patterns_same_crate.rs:57:9
+ |
+LL | Some(_x) => (),
+ | ^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/patterns_same_crate.rs:61:15
+ |
+LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/patterns_same_crate.rs:65:15
+ |
+LL | while let Some(_x) = uninhabited_struct() {
+ | ^^^^^^^^
+
+error: unreachable pattern
+ --> $DIR/patterns_same_crate.rs:68:15
+ |
+LL | while let Some(_x) = uninhabited_tuple_struct() {
+ | ^^^^^^^^
+
+error: aborting due to 5 previous errors
+