about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen/issues/str-to-string-128690.rs36
-rw-r--r--tests/run-make/remap-path-prefix-dwarf/Makefile112
-rw-r--r--tests/run-make/remap-path-prefix-dwarf/rmake.rs202
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-args.stderr3
-rw-r--r--tests/ui/coercion/coerce-expect-unsized-ascribed.stderr4
-rw-r--r--tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr44
-rw-r--r--tests/ui/pattern/usefulness/empty-types.never_pats.stderr86
-rw-r--r--tests/ui/pattern/usefulness/empty-types.normal.stderr86
-rw-r--r--tests/ui/pattern/usefulness/empty-types.rs11
9 files changed, 377 insertions, 207 deletions
diff --git a/tests/codegen/issues/str-to-string-128690.rs b/tests/codegen/issues/str-to-string-128690.rs
new file mode 100644
index 00000000000..8b416306ba6
--- /dev/null
+++ b/tests/codegen/issues/str-to-string-128690.rs
@@ -0,0 +1,36 @@
+//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
+#![crate_type = "lib"]
+
+//! Make sure str::to_string is specialized not to use fmt machinery.
+
+// CHECK-LABEL: define {{(dso_local )?}}void @one_ref
+#[no_mangle]
+pub fn one_ref(input: &str) -> String {
+    // CHECK-NOT: {{(call|invoke).*}}fmt
+    input.to_string()
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @two_ref
+#[no_mangle]
+pub fn two_ref(input: &&str) -> String {
+    // CHECK-NOT: {{(call|invoke).*}}fmt
+    input.to_string()
+}
+
+// CHECK-LABEL: define {{(dso_local )?}}void @thirteen_ref
+#[no_mangle]
+pub fn thirteen_ref(input: &&&&&&&&&&&&&str) -> String {
+    // CHECK-NOT: {{(call|invoke).*}}fmt
+    input.to_string()
+}
+
+// This is a known performance cliff because of the macro-generated
+// specialized impl. If this test suddenly starts failing,
+// consider removing the `to_string_str!` macro in `alloc/str/string.rs`.
+//
+// CHECK-LABEL: define {{(dso_local )?}}void @fourteen_ref
+#[no_mangle]
+pub fn fourteen_ref(input: &&&&&&&&&&&&&&str) -> String {
+    // CHECK: {{(call|invoke).*}}fmt
+    input.to_string()
+}
diff --git a/tests/run-make/remap-path-prefix-dwarf/Makefile b/tests/run-make/remap-path-prefix-dwarf/Makefile
deleted file mode 100644
index 8905a00ea28..00000000000
--- a/tests/run-make/remap-path-prefix-dwarf/Makefile
+++ /dev/null
@@ -1,112 +0,0 @@
-# This test makes sure that --remap-path-prefix has the expected effects on paths in debuginfo.
-# It tests several cases, each of them has a detailed description attached to it.
-
-# ignore-windows
-
-include ../tools.mk
-
-SRC_DIR := $(abspath .)
-SRC_DIR_PARENT := $(abspath ..)
-
-ifeq ($(UNAME),Darwin)
-  DEBUGINFOOPTS := -Csplit-debuginfo=off
-else
-  DEBUGINFOOPTS :=
-endif
-
-all: \
-  abs_input_outside_working_dir \
-  rel_input_remap_working_dir \
-  rel_input_remap_working_dir_scope \
-  rel_input_remap_working_dir_parent \
-  rel_input_remap_working_dir_child \
-  rel_input_remap_working_dir_diagnostics \
-  abs_input_inside_working_dir \
-  abs_input_inside_working_dir_scope \
-  abs_input_outside_working_dir
-
-# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
-# the working directory of the compiler. We are remapping the path that contains `src`.
-abs_input_inside_working_dir:
-	# We explicitly switch to a directory that *is* a prefix of the directory our
-	# source code is contained in.
-	cd $(SRC_DIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_inside_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED
-	# We expect the path to the main source file to be remapped.
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir.rlib | $(CGREP) "REMAPPED/src/quux.rs"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
-# the working directory of the compiler. We are remapping the path that contains `src`.
-abs_input_inside_working_dir_scope:
-	# We explicitly switch to a directory that *is* a prefix of the directory our
-	# source code is contained in.
-	cd $(SRC_DIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_inside_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED -Zremap-path-scope=object $(DEBUGINFOOPTS)
-	# We expect the path to the main source file to be remapped.
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir_scope.rlib | $(CGREP) "REMAPPED/src/quux.rs"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_inside_working_dir_scope.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path is *not* within
-# the working directory of the compiler. We are remapping both the path that contains `src` and
-# the working directory to the same thing. This setup corresponds to a workaround that is needed
-# when trying to remap everything to something that looks like a local path.
-# Relative paths are interpreted as relative to the compiler's working directory (e.g. in
-# debuginfo). If we also remap the working directory, the compiler strip it from other paths so
-# that the final outcome is the desired one again.
-abs_input_outside_working_dir:
-	# We explicitly switch to a directory that is *not* a prefix of the directory our
-	# source code is contained in.
-	cd $(TMPDIR) && $(RUSTC) $(SRC_DIR)/src/quux.rs -o "$(TMPDIR)/abs_input_outside_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix $(SRC_DIR)=REMAPPED --remap-path-prefix $(TMPDIR)=REMAPPED
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_outside_working_dir.rlib | $(CGREP) "REMAPPED/src/quux.rs"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump $(TMPDIR)/abs_input_outside_working_dir.rlib | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with a *RELATIVE PATH* as input. We are remapping the working directory of
-# the compiler, which naturally is an implicit prefix of our relative input path. Debuginfo will
-# expand the relative path to an absolute path and we expect the working directory to be remapped
-# in that expansion.
-rel_input_remap_working_dir:
-	cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir.rlib" | $(CGREP) "REMAPPED/src/quux.rs"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with a *RELATIVE PATH* as input. We are remapping the working directory of
-# the compiler, which naturally is an implicit prefix of our relative input path. Debuginfo will
-# expand the relative path to an absolute path and we expect the working directory to be remapped
-# in that expansion.
-rel_input_remap_working_dir_scope:
-	cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED" -Zremap-path-scope=object $(DEBUGINFOOPTS)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) "REMAPPED/src/quux.rs"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
-
-rel_input_remap_working_dir_diagnostics:
-	cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)=REMAPPED" -Zremap-path-scope=diagnostics $(DEBUGINFOOPTS)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/src/quux.rs"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_scope.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with a *RELATIVE PATH* as input. We are remapping a *SUB-DIRECTORY* of the
-# compiler's working directory. This test makes sure that that directory is remapped even though it
-# won't actually show up in this form in the compiler's SourceMap and instead is only constructed
-# on demand during debuginfo generation.
-rel_input_remap_working_dir_child:
-	cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR)/src=REMAPPED"
-	# We expect `src/quux.rs` to have been remapped to `REMAPPED/quux.rs`.
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) "REMAPPED/quux.rs"
-	# We don't want to find the path that we just remapped anywhere in the DWARF
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) -v "$(SRC_DIR)/src"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_child.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
-
-# The compiler is called with a *RELATIVE PATH* as input. We are remapping a *PARENT DIRECTORY* of
-# the compiler's working directory.
-rel_input_remap_working_dir_parent:
-	cd $(SRC_DIR) && $(RUSTC) src/quux.rs -o "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" -Cdebuginfo=2 --remap-path-prefix "$(SRC_DIR_PARENT)=REMAPPED"
-	# We expect `src/quux.rs` to have been remapped to `REMAPPED/remap-path-prefix-dwarf/src/quux.rs`.
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) "REMAPPED/remap-path-prefix-dwarf/src/quux.rs"
-	# We don't want to find the path that we just remapped anywhere in the DWARF
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) -v "$(SRC_DIR_PARENT)"
-	# No weird duplication of remapped components (see #78479)
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump "$(TMPDIR)/rel_input_remap_working_dir_parent.rlib" | $(CGREP) -v "REMAPPED/REMAPPED"
diff --git a/tests/run-make/remap-path-prefix-dwarf/rmake.rs b/tests/run-make/remap-path-prefix-dwarf/rmake.rs
new file mode 100644
index 00000000000..ede1d615742
--- /dev/null
+++ b/tests/run-make/remap-path-prefix-dwarf/rmake.rs
@@ -0,0 +1,202 @@
+// This test makes sure that --remap-path-prefix has the expected effects on paths in debuginfo.
+// We explicitly switch to a directory that *is* a prefix of the directory our
+// source code is contained in.
+// It tests several cases, each of them has a detailed description attached to it.
+// See https://github.com/rust-lang/rust/pull/96867
+
+//@ ignore-windows
+// Reason: the remap path prefix is not printed in the dwarf dump.
+
+use run_make_support::{cwd, is_darwin, llvm_dwarfdump, rust_lib_name, rustc};
+
+fn main() {
+    // The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path *is* within
+    // the working directory of the compiler. We are remapping the path that contains `src`.
+    check_dwarf(DwarfTest {
+        lib_name: "abs_input_inside_working_dir",
+        input_path: PathType::Absolute,
+        scope: None,
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
+        dwarf_test: DwarfDump::ContainsSrcPath,
+    });
+    check_dwarf(DwarfTest {
+        lib_name: "abs_input_inside_working_dir_scope",
+        input_path: PathType::Absolute,
+        scope: Some(ScopeType::Object),
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
+        dwarf_test: DwarfDump::ContainsSrcPath,
+    });
+    // The compiler is called with an *ABSOLUTE PATH* as input, and that absolute path is *not*
+    // within the working directory of the compiler. We are remapping both the path that contains
+    // `src` and the working directory to the same thing. This setup corresponds to a workaround
+    // that is needed when trying to remap everything to something that looks like a local
+    // path. Relative paths are interpreted as relative to the compiler's working directory (e.g.
+    // in debuginfo). If we also remap the working directory, the compiler strip it from other
+    // paths so that the final outcome is the desired one again.
+    check_dwarf(DwarfTest {
+        lib_name: "abs_input_outside_working_dir",
+        input_path: PathType::Absolute,
+        scope: None,
+        remap_path_prefix: PrefixType::Dual((
+            format!("{}=REMAPPED", cwd().display()),
+            "rmake_out=REMAPPED".to_owned(),
+        )),
+        dwarf_test: DwarfDump::ContainsSrcPath,
+    });
+    // The compiler is called with a *RELATIVE PATH* as input. We are remapping the working
+    // directory of the compiler, which naturally is an implicit prefix of our relative input path.
+    // Debuginfo will expand the relative path to an absolute path and we expect the working
+    // directory to be remapped in that expansion.
+    check_dwarf(DwarfTest {
+        lib_name: "rel_input_remap_working_dir",
+        input_path: PathType::Relative,
+        scope: None,
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
+        dwarf_test: DwarfDump::ContainsSrcPath,
+    });
+    check_dwarf(DwarfTest {
+        lib_name: "rel_input_remap_working_dir_scope",
+        input_path: PathType::Relative,
+        scope: Some(ScopeType::Object),
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
+        dwarf_test: DwarfDump::ContainsSrcPath,
+    });
+    check_dwarf(DwarfTest {
+        lib_name: "rel_input_remap_working_dir_scope",
+        input_path: PathType::Relative,
+        scope: Some(ScopeType::Diagnostics),
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().display())),
+        dwarf_test: DwarfDump::AvoidSrcPath,
+    });
+    // The compiler is called with a *RELATIVE PATH* as input. We are remapping a *SUB-DIRECTORY*
+    // of the compiler's working directory. This test makes sure that that directory is remapped
+    // even though it won't actually show up in this form in the compiler's SourceMap and instead
+    // is only constructed on demand during debuginfo generation.
+    check_dwarf(DwarfTest {
+        lib_name: "rel_input_remap_working_dir_child",
+        input_path: PathType::Relative,
+        scope: None,
+        remap_path_prefix: PrefixType::Regular(format!("{}=REMAPPED", cwd().join("src").display())),
+        dwarf_test: DwarfDump::ChildTest,
+    });
+    // The compiler is called with a *RELATIVE PATH* as input. We are remapping a
+    // *PARENT DIRECTORY* of the compiler's working directory.
+    check_dwarf(DwarfTest {
+        lib_name: "rel_input_remap_working_dir_parent",
+        input_path: PathType::Relative,
+        scope: None,
+        remap_path_prefix: PrefixType::Regular(format!(
+            "{}=REMAPPED",
+            cwd().parent().unwrap().display()
+        )),
+        dwarf_test: DwarfDump::ParentTest,
+    });
+}
+
+#[track_caller]
+fn check_dwarf(test: DwarfTest) {
+    let mut rustc = rustc();
+    match test.input_path {
+        PathType::Absolute => rustc.input(cwd().join("src/quux.rs")),
+        PathType::Relative => rustc.input("src/quux.rs"),
+    };
+    rustc.output(rust_lib_name(test.lib_name));
+    rustc.arg("-Cdebuginfo=2");
+    if let Some(scope) = test.scope {
+        match scope {
+            ScopeType::Object => rustc.arg("-Zremap-path-scope=object"),
+            ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"),
+        };
+        if is_darwin() {
+            rustc.arg("-Csplit-debuginfo=off");
+        }
+    }
+    match test.remap_path_prefix {
+        PrefixType::Regular(prefix) => {
+            // We explicitly switch to a directory that *is* a prefix of the directory our
+            // source code is contained in.
+            rustc.arg("--remap-path-prefix");
+            rustc.arg(prefix);
+        }
+        PrefixType::Dual((prefix1, prefix2)) => {
+            // We explicitly switch to a directory that is *not* a prefix of the directory our
+            // source code is contained in.
+            rustc.arg("--remap-path-prefix");
+            rustc.arg(prefix1);
+            rustc.arg("--remap-path-prefix");
+            rustc.arg(prefix2);
+        }
+    }
+    rustc.run();
+    match test.dwarf_test {
+        DwarfDump::ContainsSrcPath => {
+            llvm_dwarfdump()
+                .input(rust_lib_name(test.lib_name))
+                .run()
+                // We expect the path to the main source file to be remapped.
+                .assert_stdout_contains("REMAPPED/src/quux.rs")
+                // No weird duplication of remapped components (see #78479)
+                .assert_stdout_not_contains("REMAPPED/REMAPPED");
+        }
+        DwarfDump::AvoidSrcPath => {
+            llvm_dwarfdump()
+                .input(rust_lib_name(test.lib_name))
+                .run()
+                .assert_stdout_not_contains("REMAPPED/src/quux.rs")
+                .assert_stdout_not_contains("REMAPPED/REMAPPED");
+        }
+        DwarfDump::ChildTest => {
+            llvm_dwarfdump()
+                .input(rust_lib_name(test.lib_name))
+                .run()
+                // We expect `src/quux.rs` to have been remapped to `REMAPPED/quux.rs`.
+                .assert_stdout_contains("REMAPPED/quux.rs")
+                // We don't want to find the path that we just remapped anywhere in the DWARF
+                .assert_stdout_not_contains(cwd().join("src").to_str().unwrap())
+                // No weird duplication of remapped components (see #78479)
+                .assert_stdout_not_contains("REMAPPED/REMAPPED");
+        }
+        DwarfDump::ParentTest => {
+            llvm_dwarfdump()
+                .input(rust_lib_name(test.lib_name))
+                .run()
+                // We expect `src/quux.rs` to have been remapped to
+                // `REMAPPED/remap-path-prefix-dwarf/src/quux.rs`.
+                .assert_stdout_contains("REMAPPED/rmake_out/src/quux.rs")
+                // We don't want to find the path that we just remapped anywhere in the DWARF
+                .assert_stdout_not_contains(cwd().parent().unwrap().to_str().unwrap())
+                // No weird duplication of remapped components (see #78479)
+                .assert_stdout_not_contains("REMAPPED/REMAPPED");
+        }
+    };
+}
+
+struct DwarfTest {
+    lib_name: &'static str,
+    input_path: PathType,
+    scope: Option<ScopeType>,
+    remap_path_prefix: PrefixType,
+    dwarf_test: DwarfDump,
+}
+
+enum PathType {
+    Absolute,
+    Relative,
+}
+
+enum ScopeType {
+    Object,
+    Diagnostics,
+}
+
+enum DwarfDump {
+    ContainsSrcPath,
+    AvoidSrcPath,
+    ChildTest,
+    ParentTest,
+}
+
+enum PrefixType {
+    Regular(String),
+    Dual((String, String)),
+}
diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr
index b04289ae747..8e60ca42f0a 100644
--- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr
+++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr
@@ -14,6 +14,7 @@ LL |     let y: *const dyn Trait<Y> = x as _;
    |
    = note: expected trait object `dyn Trait<X>`
               found trait object `dyn Trait<Y>`
+   = help: `dyn Trait<Y>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/ptr-to-trait-obj-different-args.rs:27:34
@@ -25,6 +26,7 @@ LL |     let _: *const dyn Trait<T> = x as _;
    |
    = note: expected trait object `dyn Trait<X>`
               found trait object `dyn Trait<T>`
+   = help: `dyn Trait<T>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/ptr-to-trait-obj-different-args.rs:28:34
@@ -37,6 +39,7 @@ LL |     let _: *const dyn Trait<X> = t as _;
    |
    = note: expected trait object `dyn Trait<T>`
               found trait object `dyn Trait<X>`
+   = help: `dyn Trait<X>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/ptr-to-trait-obj-different-args.rs:36:5
diff --git a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
index 646044ae41a..0c220a13876 100644
--- a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
+++ b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
@@ -42,6 +42,7 @@ LL |     let _ = type_ascribe!(Box::new( if true { false } else { true }), Box<d
    |
    = note: expected struct `Box<dyn Debug>`
               found struct `Box<bool>`
+   = help: `bool` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:16:27
@@ -51,6 +52,7 @@ LL |     let _ = type_ascribe!(Box::new( match true { true => 'a', false => 'b'
    |
    = note: expected struct `Box<dyn Debug>`
               found struct `Box<char>`
+   = help: `char` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:18:27
@@ -96,6 +98,7 @@ LL |     let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug);
    |
    = note: expected reference `&dyn Debug`
               found reference `&bool`
+   = help: `bool` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:24:27
@@ -105,6 +108,7 @@ LL |     let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn D
    |
    = note: expected reference `&dyn Debug`
               found reference `&char`
+   = help: `char` implements `Debug` so you could box the found value and coerce it to the trait object `Box<dyn Debug>`, you will have to change the expected type as well
 
 error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:26:27
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
index 17cb6fbd94b..f6f341d6f2f 100644
--- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -254,7 +254,7 @@ LL |             _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:279:9
+  --> $DIR/empty-types.rs:281:9
    |
 LL |         _ => {}
    |         ^
@@ -262,7 +262,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:282:9
+  --> $DIR/empty-types.rs:284:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
@@ -270,7 +270,7 @@ LL |         (_, _) => {}
    = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:285:9
+  --> $DIR/empty-types.rs:287:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
@@ -278,7 +278,7 @@ LL |         Ok(_) => {}
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:286:9
+  --> $DIR/empty-types.rs:288:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
@@ -286,7 +286,7 @@ LL |         Err(_) => {}
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
-  --> $DIR/empty-types.rs:318:11
+  --> $DIR/empty-types.rs:327:11
    |
 LL |     match slice_never {}
    |           ^^^^^^^^^^^
@@ -300,7 +300,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/empty-types.rs:329:11
+  --> $DIR/empty-types.rs:338:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[]` not covered
@@ -313,7 +313,7 @@ LL +         &[] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/empty-types.rs:343:11
+  --> $DIR/empty-types.rs:352:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[]` not covered
@@ -327,7 +327,7 @@ LL +         &[] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
-  --> $DIR/empty-types.rs:350:11
+  --> $DIR/empty-types.rs:359:11
    |
 LL |     match *slice_never {}
    |           ^^^^^^^^^^^^
@@ -341,7 +341,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:359:9
+  --> $DIR/empty-types.rs:368:9
    |
 LL |         _ => {}
    |         ^
@@ -349,7 +349,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:362:9
+  --> $DIR/empty-types.rs:371:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
@@ -357,7 +357,7 @@ LL |         [_, _, _] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:365:9
+  --> $DIR/empty-types.rs:374:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
@@ -365,7 +365,7 @@ LL |         [_, ..] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
-  --> $DIR/empty-types.rs:379:11
+  --> $DIR/empty-types.rs:388:11
    |
 LL |     match array_0_never {}
    |           ^^^^^^^^^^^^^
@@ -379,7 +379,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:386:9
+  --> $DIR/empty-types.rs:395:9
    |
 LL |         [] => {}
    |         -- matches all the values already
@@ -387,7 +387,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/empty-types.rs:388:11
+  --> $DIR/empty-types.rs:397:11
    |
 LL |     match array_0_never {
    |           ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -401,7 +401,7 @@ LL +         [] => todo!()
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:407:9
+  --> $DIR/empty-types.rs:416:9
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
@@ -409,7 +409,7 @@ LL |         Some(_) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:412:9
+  --> $DIR/empty-types.rs:421:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
@@ -417,7 +417,7 @@ LL |         Some(_a) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:417:9
+  --> $DIR/empty-types.rs:426:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -426,7 +426,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:422:9
+  --> $DIR/empty-types.rs:431:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -435,7 +435,7 @@ LL |         _a => {}
    |         ^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:594:9
+  --> $DIR/empty-types.rs:603:9
    |
 LL |         _ => {}
    |         ^
@@ -443,7 +443,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:597:9
+  --> $DIR/empty-types.rs:606:9
    |
 LL |         _x => {}
    |         ^^
@@ -451,7 +451,7 @@ LL |         _x => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:600:9
+  --> $DIR/empty-types.rs:609:9
    |
 LL |         _ if false => {}
    |         ^
@@ -459,7 +459,7 @@ LL |         _ if false => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:603:9
+  --> $DIR/empty-types.rs:612:9
    |
 LL |         _x if false => {}
    |         ^^
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 1ecb15f2cae..55a138c2d1c 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -296,7 +296,7 @@ LL |             _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:279:9
+  --> $DIR/empty-types.rs:281:9
    |
 LL |         _ => {}
    |         ^
@@ -304,7 +304,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:282:9
+  --> $DIR/empty-types.rs:284:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
@@ -312,7 +312,7 @@ LL |         (_, _) => {}
    = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:285:9
+  --> $DIR/empty-types.rs:287:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
@@ -320,15 +320,29 @@ LL |         Ok(_) => {}
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:286:9
+  --> $DIR/empty-types.rs:288:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
    |
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
+error[E0005]: refutable pattern in local binding
+  --> $DIR/empty-types.rs:297:13
+   |
+LL |         let Ok(_) = *ptr_result_never_err;
+   |             ^^^^^ pattern `Err(!)` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `Result<u8, !>`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |         if let Ok(_) = *ptr_result_never_err { todo!() };
+   |         ++                                   +++++++++++
+
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:307:11
+  --> $DIR/empty-types.rs:316:11
    |
 LL |     match *x {}
    |           ^^
@@ -342,7 +356,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
-  --> $DIR/empty-types.rs:309:11
+  --> $DIR/empty-types.rs:318:11
    |
 LL |     match *x {}
    |           ^^
@@ -356,7 +370,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(!)` and `Err(!)` not covered
-  --> $DIR/empty-types.rs:311:11
+  --> $DIR/empty-types.rs:320:11
    |
 LL |     match *x {}
    |           ^^ patterns `Ok(!)` and `Err(!)` not covered
@@ -378,7 +392,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
-  --> $DIR/empty-types.rs:313:11
+  --> $DIR/empty-types.rs:322:11
    |
 LL |     match *x {}
    |           ^^
@@ -392,7 +406,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
-  --> $DIR/empty-types.rs:318:11
+  --> $DIR/empty-types.rs:327:11
    |
 LL |     match slice_never {}
    |           ^^^^^^^^^^^
@@ -406,7 +420,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered
-  --> $DIR/empty-types.rs:320:11
+  --> $DIR/empty-types.rs:329:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[!, ..]` not covered
@@ -420,7 +434,7 @@ LL +         &[!, ..]
    |
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[!]` and `&[!, !]` not covered
-  --> $DIR/empty-types.rs:329:11
+  --> $DIR/empty-types.rs:338:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]`, `&[!]` and `&[!, !]` not covered
@@ -433,7 +447,7 @@ LL +         &[] | &[!] | &[!, !] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[!, ..]` not covered
-  --> $DIR/empty-types.rs:343:11
+  --> $DIR/empty-types.rs:352:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]` and `&[!, ..]` not covered
@@ -447,7 +461,7 @@ LL +         &[] | &[!, ..] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
-  --> $DIR/empty-types.rs:350:11
+  --> $DIR/empty-types.rs:359:11
    |
 LL |     match *slice_never {}
    |           ^^^^^^^^^^^^
@@ -461,7 +475,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:359:9
+  --> $DIR/empty-types.rs:368:9
    |
 LL |         _ => {}
    |         ^
@@ -469,7 +483,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:362:9
+  --> $DIR/empty-types.rs:371:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
@@ -477,7 +491,7 @@ LL |         [_, _, _] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:365:9
+  --> $DIR/empty-types.rs:374:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
@@ -485,7 +499,7 @@ LL |         [_, ..] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
-  --> $DIR/empty-types.rs:379:11
+  --> $DIR/empty-types.rs:388:11
    |
 LL |     match array_0_never {}
    |           ^^^^^^^^^^^^^
@@ -499,7 +513,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:386:9
+  --> $DIR/empty-types.rs:395:9
    |
 LL |         [] => {}
    |         -- matches all the values already
@@ -507,7 +521,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/empty-types.rs:388:11
+  --> $DIR/empty-types.rs:397:11
    |
 LL |     match array_0_never {
    |           ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -521,7 +535,7 @@ LL +         [] => todo!()
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:407:9
+  --> $DIR/empty-types.rs:416:9
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
@@ -529,7 +543,7 @@ LL |         Some(_) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:412:9
+  --> $DIR/empty-types.rs:421:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
@@ -537,7 +551,7 @@ LL |         Some(_a) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:417:9
+  --> $DIR/empty-types.rs:426:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -546,7 +560,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:422:9
+  --> $DIR/empty-types.rs:431:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -555,7 +569,7 @@ LL |         _a => {}
    |         ^^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `&Some(!)` not covered
-  --> $DIR/empty-types.rs:442:11
+  --> $DIR/empty-types.rs:451:11
    |
 LL |     match ref_opt_never {
    |           ^^^^^^^^^^^^^ pattern `&Some(!)` not covered
@@ -574,7 +588,7 @@ LL +         &Some(!)
    |
 
 error[E0004]: non-exhaustive patterns: `Some(!)` not covered
-  --> $DIR/empty-types.rs:483:11
+  --> $DIR/empty-types.rs:492:11
    |
 LL |     match *ref_opt_never {
    |           ^^^^^^^^^^^^^^ pattern `Some(!)` not covered
@@ -593,7 +607,7 @@ LL +         Some(!)
    |
 
 error[E0004]: non-exhaustive patterns: `Err(!)` not covered
-  --> $DIR/empty-types.rs:531:11
+  --> $DIR/empty-types.rs:540:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
@@ -612,7 +626,7 @@ LL +         Err(!)
    |
 
 error[E0004]: non-exhaustive patterns: `Err(!)` not covered
-  --> $DIR/empty-types.rs:542:11
+  --> $DIR/empty-types.rs:551:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
@@ -631,7 +645,7 @@ LL +         Err(!)
    |
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:561:11
+  --> $DIR/empty-types.rs:570:11
    |
 LL |     match *ref_tuple_half_never {}
    |           ^^^^^^^^^^^^^^^^^^^^^
@@ -645,7 +659,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:594:9
+  --> $DIR/empty-types.rs:603:9
    |
 LL |         _ => {}
    |         ^
@@ -653,7 +667,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:597:9
+  --> $DIR/empty-types.rs:606:9
    |
 LL |         _x => {}
    |         ^^
@@ -661,7 +675,7 @@ LL |         _x => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:600:9
+  --> $DIR/empty-types.rs:609:9
    |
 LL |         _ if false => {}
    |         ^
@@ -669,7 +683,7 @@ LL |         _ if false => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:603:9
+  --> $DIR/empty-types.rs:612:9
    |
 LL |         _x if false => {}
    |         ^^
@@ -677,7 +691,7 @@ LL |         _x if false => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `&!` not covered
-  --> $DIR/empty-types.rs:628:11
+  --> $DIR/empty-types.rs:637:11
    |
 LL |     match ref_never {
    |           ^^^^^^^^^ pattern `&!` not covered
@@ -693,7 +707,7 @@ LL +         &!
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(!)` not covered
-  --> $DIR/empty-types.rs:644:11
+  --> $DIR/empty-types.rs:653:11
    |
 LL |     match *ref_result_never {
    |           ^^^^^^^^^^^^^^^^^ pattern `Ok(!)` not covered
@@ -712,7 +726,7 @@ LL +         Ok(!)
    |
 
 error[E0004]: non-exhaustive patterns: `Some(!)` not covered
-  --> $DIR/empty-types.rs:664:11
+  --> $DIR/empty-types.rs:673:11
    |
 LL |     match *x {
    |           ^^ pattern `Some(!)` not covered
@@ -730,7 +744,7 @@ LL ~         None => {},
 LL +         Some(!)
    |
 
-error: aborting due to 64 previous errors; 1 warning emitted
+error: aborting due to 65 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0004, E0005.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index c3421cd592e..83b3989ffde 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -287,7 +287,7 @@ LL |             _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:279:9
+  --> $DIR/empty-types.rs:281:9
    |
 LL |         _ => {}
    |         ^
@@ -295,7 +295,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:282:9
+  --> $DIR/empty-types.rs:284:9
    |
 LL |         (_, _) => {}
    |         ^^^^^^
@@ -303,7 +303,7 @@ LL |         (_, _) => {}
    = note: this pattern matches no values because `(!, !)` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:285:9
+  --> $DIR/empty-types.rs:287:9
    |
 LL |         Ok(_) => {}
    |         ^^^^^
@@ -311,15 +311,29 @@ LL |         Ok(_) => {}
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:286:9
+  --> $DIR/empty-types.rs:288:9
    |
 LL |         Err(_) => {}
    |         ^^^^^^
    |
    = note: this pattern matches no values because `Result<!, !>` is uninhabited
 
+error[E0005]: refutable pattern in local binding
+  --> $DIR/empty-types.rs:297:13
+   |
+LL |         let Ok(_) = *ptr_result_never_err;
+   |             ^^^^^ pattern `Err(_)` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `Result<u8, !>`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |         if let Ok(_) = *ptr_result_never_err { todo!() };
+   |         ++                                   +++++++++++
+
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:307:11
+  --> $DIR/empty-types.rs:316:11
    |
 LL |     match *x {}
    |           ^^
@@ -333,7 +347,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
-  --> $DIR/empty-types.rs:309:11
+  --> $DIR/empty-types.rs:318:11
    |
 LL |     match *x {}
    |           ^^
@@ -347,7 +361,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
-  --> $DIR/empty-types.rs:311:11
+  --> $DIR/empty-types.rs:320:11
    |
 LL |     match *x {}
    |           ^^ patterns `Ok(_)` and `Err(_)` not covered
@@ -369,7 +383,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
-  --> $DIR/empty-types.rs:313:11
+  --> $DIR/empty-types.rs:322:11
    |
 LL |     match *x {}
    |           ^^
@@ -383,7 +397,7 @@ LL ~     }
    |
 
 error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
-  --> $DIR/empty-types.rs:318:11
+  --> $DIR/empty-types.rs:327:11
    |
 LL |     match slice_never {}
    |           ^^^^^^^^^^^
@@ -397,7 +411,7 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
-  --> $DIR/empty-types.rs:320:11
+  --> $DIR/empty-types.rs:329:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ pattern `&[_, ..]` not covered
@@ -411,7 +425,7 @@ LL +         &[_, ..] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
-  --> $DIR/empty-types.rs:329:11
+  --> $DIR/empty-types.rs:338:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
@@ -424,7 +438,7 @@ LL +         &[] | &[_] | &[_, _] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
-  --> $DIR/empty-types.rs:343:11
+  --> $DIR/empty-types.rs:352:11
    |
 LL |     match slice_never {
    |           ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
@@ -438,7 +452,7 @@ LL +         &[] | &[_, ..] => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
-  --> $DIR/empty-types.rs:350:11
+  --> $DIR/empty-types.rs:359:11
    |
 LL |     match *slice_never {}
    |           ^^^^^^^^^^^^
@@ -452,7 +466,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:359:9
+  --> $DIR/empty-types.rs:368:9
    |
 LL |         _ => {}
    |         ^
@@ -460,7 +474,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:362:9
+  --> $DIR/empty-types.rs:371:9
    |
 LL |         [_, _, _] => {}
    |         ^^^^^^^^^
@@ -468,7 +482,7 @@ LL |         [_, _, _] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:365:9
+  --> $DIR/empty-types.rs:374:9
    |
 LL |         [_, ..] => {}
    |         ^^^^^^^
@@ -476,7 +490,7 @@ LL |         [_, ..] => {}
    = note: this pattern matches no values because `[!; 3]` is uninhabited
 
 error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
-  --> $DIR/empty-types.rs:379:11
+  --> $DIR/empty-types.rs:388:11
    |
 LL |     match array_0_never {}
    |           ^^^^^^^^^^^^^
@@ -490,7 +504,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:386:9
+  --> $DIR/empty-types.rs:395:9
    |
 LL |         [] => {}
    |         -- matches all the values already
@@ -498,7 +512,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/empty-types.rs:388:11
+  --> $DIR/empty-types.rs:397:11
    |
 LL |     match array_0_never {
    |           ^^^^^^^^^^^^^ pattern `[]` not covered
@@ -512,7 +526,7 @@ LL +         [] => todo!()
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:407:9
+  --> $DIR/empty-types.rs:416:9
    |
 LL |         Some(_) => {}
    |         ^^^^^^^
@@ -520,7 +534,7 @@ LL |         Some(_) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:412:9
+  --> $DIR/empty-types.rs:421:9
    |
 LL |         Some(_a) => {}
    |         ^^^^^^^^
@@ -528,7 +542,7 @@ LL |         Some(_a) => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:417:9
+  --> $DIR/empty-types.rs:426:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -537,7 +551,7 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:422:9
+  --> $DIR/empty-types.rs:431:9
    |
 LL |         None => {}
    |         ---- matches all the values already
@@ -546,7 +560,7 @@ LL |         _a => {}
    |         ^^ unreachable pattern
 
 error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
-  --> $DIR/empty-types.rs:442:11
+  --> $DIR/empty-types.rs:451:11
    |
 LL |     match ref_opt_never {
    |           ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
@@ -565,7 +579,7 @@ LL +         &Some(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:483:11
+  --> $DIR/empty-types.rs:492:11
    |
 LL |     match *ref_opt_never {
    |           ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
@@ -584,7 +598,7 @@ LL +         Some(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:531:11
+  --> $DIR/empty-types.rs:540:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -603,7 +617,7 @@ LL +         Err(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/empty-types.rs:542:11
+  --> $DIR/empty-types.rs:551:11
    |
 LL |     match *ref_res_never {
    |           ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
@@ -622,7 +636,7 @@ LL +         Err(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
-  --> $DIR/empty-types.rs:561:11
+  --> $DIR/empty-types.rs:570:11
    |
 LL |     match *ref_tuple_half_never {}
    |           ^^^^^^^^^^^^^^^^^^^^^
@@ -636,7 +650,7 @@ LL +     }
    |
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:594:9
+  --> $DIR/empty-types.rs:603:9
    |
 LL |         _ => {}
    |         ^
@@ -644,7 +658,7 @@ LL |         _ => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:597:9
+  --> $DIR/empty-types.rs:606:9
    |
 LL |         _x => {}
    |         ^^
@@ -652,7 +666,7 @@ LL |         _x => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:600:9
+  --> $DIR/empty-types.rs:609:9
    |
 LL |         _ if false => {}
    |         ^
@@ -660,7 +674,7 @@ LL |         _ if false => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error: unreachable pattern
-  --> $DIR/empty-types.rs:603:9
+  --> $DIR/empty-types.rs:612:9
    |
 LL |         _x if false => {}
    |         ^^
@@ -668,7 +682,7 @@ LL |         _x if false => {}
    = note: this pattern matches no values because `!` is uninhabited
 
 error[E0004]: non-exhaustive patterns: `&_` not covered
-  --> $DIR/empty-types.rs:628:11
+  --> $DIR/empty-types.rs:637:11
    |
 LL |     match ref_never {
    |           ^^^^^^^^^ pattern `&_` not covered
@@ -684,7 +698,7 @@ LL +         &_ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
-  --> $DIR/empty-types.rs:644:11
+  --> $DIR/empty-types.rs:653:11
    |
 LL |     match *ref_result_never {
    |           ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered
@@ -703,7 +717,7 @@ LL +         Ok(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/empty-types.rs:664:11
+  --> $DIR/empty-types.rs:673:11
    |
 LL |     match *x {
    |           ^^ pattern `Some(_)` not covered
@@ -721,7 +735,7 @@ LL ~         None => {},
 LL +         Some(_) => todo!()
    |
 
-error: aborting due to 64 previous errors
+error: aborting due to 65 previous errors
 
 Some errors have detailed explanations: E0004, E0005.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-types.rs b/tests/ui/pattern/usefulness/empty-types.rs
index 639c48cea12..d561a0e9c12 100644
--- a/tests/ui/pattern/usefulness/empty-types.rs
+++ b/tests/ui/pattern/usefulness/empty-types.rs
@@ -17,7 +17,7 @@
 #[derive(Copy, Clone)]
 enum Void {}
 
-/// A bunch of never situations that can't be normally constructed.
+/// A bunch of never situations that can't be normally constructed so we take them as argument.
 #[derive(Copy, Clone)]
 struct NeverBundle {
     never: !,
@@ -272,6 +272,8 @@ fn nested_validity_tracking(bundle: NeverBundle) {
     let ref_never: &! = &never;
     let tuple_never: (!, !) = bundle.tuple_never;
     let result_never: Result<!, !> = bundle.result_never;
+    let result_never_err: Result<u8, !> = Ok(0);
+    let ptr_result_never_err: *const Result<u8, !> = &result_never_err as *const _;
     let union_never = Uninit::<!>::new();
 
     // These should be considered known_valid and warn unreachable.
@@ -287,6 +289,13 @@ fn nested_validity_tracking(bundle: NeverBundle) {
     }
 
     // These should be considered !known_valid and not warn unreachable.
+    unsafe {
+        match *ptr_result_never_err {
+            Ok(_) => {}
+            Err(_) => {}
+        }
+        let Ok(_) = *ptr_result_never_err; //[normal,never_pats]~ ERROR refutable pattern
+    }
     match ref_never {
         &_ => {}
     }