about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2019-05-04 11:03:06 +0100
committerDavid Wood <david@davidtw.co>2019-05-10 17:52:12 +0100
commit8838b9130e2f6551077f432dddd5a8077ae4d2e1 (patch)
treed717430ddb3eb5d195028c28c1868b163af46de3 /src
parent0d034a2e4dd9418fa41aba4ebdd1ebc31a08c9e9 (diff)
downloadrust-8838b9130e2f6551077f432dddd5a8077ae4d2e1.tar.gz
rust-8838b9130e2f6551077f432dddd5a8077ae4d2e1.zip
Fix uninhabitedness of non-exhaustive enums.
This commit ensures that non-exhaustive enums are considered inhabited
when used in extern crates.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs11
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs6
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs55
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr47
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs19
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr11
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs18
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs22
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr11
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs21
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs59
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs71
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr38
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs55
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr63
15 files changed, 398 insertions, 109 deletions
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 2fc07fb20bf..be1d973c2cd 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -113,9 +113,14 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         tcx: TyCtxt<'a, 'gcx, 'tcx>,
         substs: SubstsRef<'tcx>) -> DefIdForest
     {
-        DefIdForest::intersection(tcx, self.variants.iter().map(|v| {
-            v.uninhabited_from(tcx, substs, self.adt_kind())
-        }))
+        // Non-exhaustive ADTs from other crates are always considered inhabited.
+        if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
+            DefIdForest::empty()
+        } else {
+            DefIdForest::intersection(tcx, self.variants.iter().map(|v| {
+                v.uninhabited_from(tcx, substs, self.adt_kind())
+            }))
+        }
     }
 }
 
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 1a7266859ad..8c7155e1df3 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -208,7 +208,11 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
                                     .map(|variant| variant.ident)
                                     .collect();
                             }
-                            def.variants.is_empty()
+
+                            let is_non_exhaustive_and_non_local =
+                                def.is_variant_list_non_exhaustive() && !def.did.is_local();
+
+                            !(is_non_exhaustive_and_non_local) && def.variants.is_empty()
                         },
                         _ => false
                     }
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs
index 97061310d19..80b9dc4c1c3 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.rs
@@ -1,59 +1,38 @@
 // aux-build:uninhabited.rs
-// compile-pass
-#![deny(unreachable_patterns)]
-#![feature(exhaustive_patterns)]
+#![feature(never_type)]
 
 extern crate uninhabited;
 
 use uninhabited::{
-    PartiallyInhabitedVariants,
     UninhabitedEnum,
     UninhabitedStruct,
     UninhabitedTupleStruct,
     UninhabitedVariants,
 };
 
-fn uninhabited_enum() -> Option<UninhabitedEnum> {
-    None
-}
+// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never
+// type can.
 
-fn uninhabited_variant() -> Option<UninhabitedVariants> {
-    None
-}
+struct A;
 
-fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
-    PartiallyInhabitedVariants::Tuple(3)
+fn can_coerce_never_type_to_anything(x: !) -> A {
+    x
 }
 
-fn uninhabited_struct() -> Option<UninhabitedStruct> {
-    None
+fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+    x //~ ERROR mismatched types
 }
 
-fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
-    None
+fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+    x //~ ERROR mismatched types
 }
 
-// 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.
-    }
+fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+    x //~ ERROR mismatched types
+}
 
-    while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error.
-    }
+fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+    x //~ ERROR mismatched types
 }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr
new file mode 100644
index 00000000000..490a6c10117
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited.stderr
@@ -0,0 +1,47 @@
+error[E0308]: mismatched types
+  --> $DIR/uninhabited.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 `uninhabited::UninhabitedEnum`
+   |
+   = note: expected type `A`
+              found type `uninhabited::UninhabitedEnum`
+
+error[E0308]: mismatched types
+  --> $DIR/uninhabited.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 `uninhabited::UninhabitedTupleStruct`
+   |
+   = note: expected type `A`
+              found type `uninhabited::UninhabitedTupleStruct`
+
+error[E0308]: mismatched types
+  --> $DIR/uninhabited.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 `uninhabited::UninhabitedStruct`
+   |
+   = note: expected type `A`
+              found type `uninhabited::UninhabitedStruct`
+
+error[E0308]: mismatched types
+  --> $DIR/uninhabited.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 `uninhabited::UninhabitedVariants`
+   |
+   = note: expected type `A`
+              found type `uninhabited::UninhabitedVariants`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs
new file mode 100644
index 00000000000..0166b2e46cb
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.rs
@@ -0,0 +1,19 @@
+// aux-build:uninhabited.rs
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+    UninhabitedEnum,
+};
+
+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 main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr
new file mode 100644
index 00000000000..3000e1b0930
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match.stderr
@@ -0,0 +1,11 @@
+error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
+  --> $DIR/uninhabited_match.rs:16:11
+   |
+LL |     match x {}
+   |           ^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs
new file mode 100644
index 00000000000..d8b1c3810f3
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_same_crate.rs
@@ -0,0 +1,18 @@
+// compile-pass
+#![feature(never_type)]
+#![feature(non_exhaustive)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+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 main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs
new file mode 100644
index 00000000000..d82010158cc
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.rs
@@ -0,0 +1,22 @@
+// aux-build:uninhabited.rs
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+extern crate uninhabited;
+
+use uninhabited::{
+    UninhabitedEnum,
+};
+
+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 main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..73d9e689b55
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns.stderr
@@ -0,0 +1,11 @@
+error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedEnum` is non-empty
+  --> $DIR/uninhabited_match_with_exhaustive_patterns.rs:19:11
+   |
+LL |     match x {}
+   |           ^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs
new file mode 100644
index 00000000000..da814a70a75
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_match_with_exhaustive_patterns_same_crate.rs
@@ -0,0 +1,21 @@
+// compile-pass
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+#![feature(non_exhaustive)]
+
+#[non_exhaustive]
+pub enum UninhabitedEnum {
+}
+
+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.
+
+fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+    match x {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs
new file mode 100644
index 00000000000..97061310d19
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns.rs
@@ -0,0 +1,59 @@
+// aux-build:uninhabited.rs
+// compile-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/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs
new file mode 100644
index 00000000000..302a35cab5f
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.rs
@@ -0,0 +1,71 @@
+#![deny(unreachable_patterns)]
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+#![feature(non_exhaustive)]
+
+#[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/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr
new file mode 100644
index 00000000000..8e995632b2f
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_patterns_same_crate.stderr
@@ -0,0 +1,38 @@
+error: unreachable pattern
+  --> $DIR/uninhabited_patterns_same_crate.rs:53:9
+   |
+LL |         Some(_x) => (),
+   |         ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/uninhabited_patterns_same_crate.rs:1:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/uninhabited_patterns_same_crate.rs:58:9
+   |
+LL |         Some(_x) => (),
+   |         ^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/uninhabited_patterns_same_crate.rs:62:15
+   |
+LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/uninhabited_patterns_same_crate.rs:66:15
+   |
+LL |     while let Some(_x) = uninhabited_struct() {
+   |               ^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/uninhabited_patterns_same_crate.rs:69:15
+   |
+LL |     while let Some(_x) = uninhabited_tuple_struct() {
+   |               ^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs
index 302a35cab5f..803a542f8aa 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.rs
@@ -1,5 +1,3 @@
-#![deny(unreachable_patterns)]
-#![feature(exhaustive_patterns)]
 #![feature(never_type)]
 #![feature(non_exhaustive)]
 
@@ -20,52 +18,29 @@ pub enum UninhabitedVariants {
     #[non_exhaustive] Struct { x: ! }
 }
 
-pub enum PartiallyInhabitedVariants {
-    Tuple(u8),
-    #[non_exhaustive] Struct { x: ! }
-}
+struct A;
 
-fn uninhabited_enum() -> Option<UninhabitedEnum> {
-    None
-}
+// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce
+// to any type, as the never type can.
 
-fn uninhabited_variant() -> Option<UninhabitedVariants> {
-    None
+fn can_coerce_never_type_to_anything(x: !) -> A {
+    x
 }
 
-fn partially_inhabited_variant() -> PartiallyInhabitedVariants {
-    PartiallyInhabitedVariants::Tuple(3)
+fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A {
+    x //~ ERROR mismatched types
 }
 
-fn uninhabited_struct() -> Option<UninhabitedStruct> {
-    None
+fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A {
+    x //~ ERROR mismatched types
 }
 
-fn uninhabited_tuple_struct() -> Option<UninhabitedTupleStruct> {
-    None
+fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A {
+    x //~ ERROR mismatched types
 }
 
-// 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
-    }
+fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A {
+    x //~ ERROR mismatched types
 }
+
+fn main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr
index 942f004c3cf..ea79e7105d5 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited_same_crate.stderr
@@ -1,38 +1,47 @@
-error: unreachable pattern
-  --> $DIR/uninhabited_same_crate.rs:53:9
+error[E0308]: mismatched types
+  --> $DIR/uninhabited_same_crate.rs:31:5
    |
-LL |         Some(_x) => (),
-   |         ^^^^^^^^
+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`
    |
-note: lint level defined here
-  --> $DIR/uninhabited_same_crate.rs:1:9
-   |
-LL | #![deny(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+   = note: expected type `A`
+              found type `UninhabitedEnum`
 
-error: unreachable pattern
-  --> $DIR/uninhabited_same_crate.rs:58:9
+error[E0308]: mismatched types
+  --> $DIR/uninhabited_same_crate.rs:35:5
    |
-LL |         Some(_x) => (),
-   |         ^^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/uninhabited_same_crate.rs:62:15
+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`
    |
-LL |     while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() {
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected type `A`
+              found type `UninhabitedTupleStruct`
 
-error: unreachable pattern
-  --> $DIR/uninhabited_same_crate.rs:66:15
+error[E0308]: mismatched types
+  --> $DIR/uninhabited_same_crate.rs:39:5
    |
-LL |     while let Some(_x) = uninhabited_struct() {
-   |               ^^^^^^^^
+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`
+   |
+   = note: expected type `A`
+              found type `UninhabitedStruct`
 
-error: unreachable pattern
-  --> $DIR/uninhabited_same_crate.rs:69:15
+error[E0308]: mismatched types
+  --> $DIR/uninhabited_same_crate.rs:43: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`
    |
-LL |     while let Some(_x) = uninhabited_tuple_struct() {
-   |               ^^^^^^^^
+   = note: expected type `A`
+              found type `UninhabitedVariants`
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0308`.