diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 85d04f7d1c41e..e02f88708f879 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 29e93a29aab4b..39438258c2ebb 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 b48f62e9dab86..75adae6160afb 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 // // Regression test for . -//@ 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 61c3f430b9a5d..0000000000000 --- 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 = ::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