about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs8
-rw-r--r--tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs20
2 files changed, 26 insertions, 2 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 6599b49baa3..b4715839cf5 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -68,7 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // While we don't allow *arbitrary* coercions here, we *do* allow
         // coercions from ! to `expected`.
-        if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
+        if self.try_structurally_resolve_type(expr.span, ty).is_never()
+            && self.expr_guaranteed_to_constitute_read_for_never(expr)
+        {
             if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
                 let reported = self.dcx().span_delayed_bug(
                     expr.span,
@@ -274,7 +276,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // unless it's a place expression that isn't being read from, in which case
         // diverging would be unsound since we may never actually read the `!`.
         // e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
-        if ty.is_never() && self.expr_guaranteed_to_constitute_read_for_never(expr) {
+        if self.try_structurally_resolve_type(expr.span, ty).is_never()
+            && self.expr_guaranteed_to_constitute_read_for_never(expr)
+        {
             self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
         }
 
diff --git a/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs
new file mode 100644
index 00000000000..6df1fd5d4ba
--- /dev/null
+++ b/tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+//@ compile-flags: -Znext-solver
+
+#![feature(never_type)]
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+fn diverge() -> <! as Mirror>::Assoc { todo!() }
+
+fn main() {
+    let close = || {
+        diverge();
+    };
+    let x: u32 = close();
+}