about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2024-04-06 20:52:32 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2024-04-19 11:05:02 +0000
commit0bbe362901b799c1a8df1e503190c647d8374777 (patch)
treee722cec750090350604eae8a0f81db941478d36b
parent4d749cad25859c92975e7331bd242c2b510096ac (diff)
downloadrust-0bbe362901b799c1a8df1e503190c647d8374777.tar.gz
rust-0bbe362901b799c1a8df1e503190c647d8374777.zip
Correctly change type when adding adjustments on top of `NeverToAny`
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs33
-rw-r--r--tests/mir-opt/building/eq_never_type._f.built.after.mir2
-rw-r--r--tests/ui/never_type/eq-never-types.rs11
-rw-r--r--tests/ui/never_type/eq-never-types.stderr20
4 files changed, 25 insertions, 41 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 786754ed12f..bd2454f6368 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -279,13 +279,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Entry::Occupied(mut entry) => {
                 debug!(" - composing on top of {:?}", entry.get());
-                match (&entry.get()[..], &adj[..]) {
-                    // Applying any adjustment on top of a NeverToAny
-                    // is a valid NeverToAny adjustment, because it can't
-                    // be reached.
-                    (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
+                match (&mut entry.get_mut()[..], &adj[..]) {
                     (
-                        &[
+                        [Adjustment { kind: Adjust::NeverToAny, target }],
+                        &[.., Adjustment { target: new_target, .. }],
+                    ) => {
+                        // NeverToAny coercion can target any type, so instead of adding a new
+                        // adjustment on top we can change the target.
+                        //
+                        // This is required for things like `a == a` (where `a: !`) to produce
+                        // valid MIR -- we need borrow adjustment from things like `==` to change
+                        // the type to `&!` (or `&()` depending on the fallback). This might be
+                        // relevant even in unreachable code.
+                        *target = new_target;
+                    }
+
+                    (
+                        &mut [
                             Adjustment { kind: Adjust::Deref(_), .. },
                             Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
                         ],
@@ -294,11 +304,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             .., // Any following adjustments are allowed.
                         ],
                     ) => {
-                        // A reborrow has no effect before a dereference.
+                        // A reborrow has no effect before a dereference, so we can safely replace adjustments.
+                        *entry.get_mut() = adj;
                     }
-                    // FIXME: currently we never try to compose autoderefs
-                    // and ReifyFnPointer/UnsafeFnPointer, but we could.
+
                     _ => {
+                        // FIXME: currently we never try to compose autoderefs
+                        // and ReifyFnPointer/UnsafeFnPointer, but we could.
                         self.dcx().span_delayed_bug(
                             expr.span,
                             format!(
@@ -308,9 +320,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 adj
                             ),
                         );
+
+                        *entry.get_mut() = adj;
                     }
                 }
-                *entry.get_mut() = adj;
             }
         }
 
diff --git a/tests/mir-opt/building/eq_never_type._f.built.after.mir b/tests/mir-opt/building/eq_never_type._f.built.after.mir
index 29e93a29aab..39438258c2e 100644
--- a/tests/mir-opt/building/eq_never_type._f.built.after.mir
+++ b/tests/mir-opt/building/eq_never_type._f.built.after.mir
@@ -6,7 +6,7 @@ fn _f(_1: !, _2: !) -> () {
     let mut _0: ();
     let mut _3: !;
     let _4: bool;
-    let mut _5: ();
+    let mut _5: &();
     let mut _6: !;
     let mut _7: &();
     let _8: ();
diff --git a/tests/ui/never_type/eq-never-types.rs b/tests/ui/never_type/eq-never-types.rs
index 00e55c100bd..19717fcf443 100644
--- a/tests/ui/never_type/eq-never-types.rs
+++ b/tests/ui/never_type/eq-never-types.rs
@@ -1,16 +1,7 @@
-//@ known-bug: #120600
+//@ check-pass
 //
 // issue: rust-lang/rust#120600
 
-//@ failure-status: 101
-//@ normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
-//@ normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> ""
-//@ normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> ""
-//@ normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> ""
-//@ normalize-stderr-test: "(?m)note: delayed at.*$" -> ""
-//@ normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
-//@ normalize-stderr-test: "(?m)^ *at .*\n" -> ""
-
 #![allow(internal_features)]
 #![feature(never_type, rustc_attrs)]
 #![rustc_never_type_options(fallback = "never")]
diff --git a/tests/ui/never_type/eq-never-types.stderr b/tests/ui/never_type/eq-never-types.stderr
deleted file mode 100644
index 61c3f430b9a..00000000000
--- a/tests/ui/never_type/eq-never-types.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-note: no errors encountered even though delayed bugs were created
-
-note: those delayed bugs will now be shown as internal compiler errors
-
-error: internal compiler error: broken MIR in DefId(ice) (Terminator { source_info: SourceInfo { span: $DIR/eq-never-types.rs:19:5: 19:11 (#0), scope: scope[0] }, kind: _3 = <! as PartialEq>::eq(move _4, move _5) -> [return: bb1, unwind: bb2] }): bad arg #0 (&'?4 ! <- !): NoSolution
-  --> $DIR/eq-never-types.rs:19:10
-   |
-LL |     a == a;
-   |          ^
-   |
-
-  --> $DIR/eq-never-types.rs:19:10
-   |
-LL |     a == a;
-   |          ^
-
-note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly
-
-query stack during panic:
-end of query stack