Skip to content

Commit be01b79

Browse files
authored
Unrolled build for rust-lang#123571
Rollup merge of rust-lang#123571 - WaffleLapkin:properly-adjust-never, r=compiler-errors Correctly change type when adding adjustments on top of `NeverToAny` I'm concerned that the check only caught the problem with `fallback = !`, because at least MIR contained `<() as PartialEq>::eq(move _5, move _7)` where `_5: ()`. I rediscovered the issue when looking at rust-lang#123482's crater run. r? compiler-errors Fixes rust-lang#120600
2 parents ce3263e + e5a6d8d commit be01b79

File tree

6 files changed

+102
-34
lines changed

6 files changed

+102
-34
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
279279
}
280280
Entry::Occupied(mut entry) => {
281281
debug!(" - composing on top of {:?}", entry.get());
282-
match (&entry.get()[..], &adj[..]) {
283-
// Applying any adjustment on top of a NeverToAny
284-
// is a valid NeverToAny adjustment, because it can't
285-
// be reached.
286-
(&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
282+
match (&mut entry.get_mut()[..], &adj[..]) {
287283
(
288-
&[
284+
[Adjustment { kind: Adjust::NeverToAny, target }],
285+
&[.., Adjustment { target: new_target, .. }],
286+
) => {
287+
// NeverToAny coercion can target any type, so instead of adding a new
288+
// adjustment on top we can change the target.
289+
//
290+
// This is required for things like `a == a` (where `a: !`) to produce
291+
// valid MIR -- we need borrow adjustment from things like `==` to change
292+
// the type to `&!` (or `&()` depending on the fallback). This might be
293+
// relevant even in unreachable code.
294+
*target = new_target;
295+
}
296+
297+
(
298+
&mut [
289299
Adjustment { kind: Adjust::Deref(_), .. },
290300
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
291301
],
@@ -294,11 +304,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294304
.., // Any following adjustments are allowed.
295305
],
296306
) => {
297-
// A reborrow has no effect before a dereference.
307+
// A reborrow has no effect before a dereference, so we can safely replace adjustments.
308+
*entry.get_mut() = adj;
298309
}
299-
// FIXME: currently we never try to compose autoderefs
300-
// and ReifyFnPointer/UnsafeFnPointer, but we could.
310+
301311
_ => {
312+
// FIXME: currently we never try to compose autoderefs
313+
// and ReifyFnPointer/UnsafeFnPointer, but we could.
302314
self.dcx().span_delayed_bug(
303315
expr.span,
304316
format!(
@@ -308,9 +320,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
308320
adj
309321
),
310322
);
323+
324+
*entry.get_mut() = adj;
311325
}
312326
}
313-
*entry.get_mut() = adj;
314327
}
315328
}
316329

tests/crashes/120600-2.rs

-13
This file was deleted.

tests/crashes/120600.rs

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// MIR for `_f` after built
2+
3+
fn _f(_1: !, _2: !) -> () {
4+
debug a => _1;
5+
debug b => _2;
6+
let mut _0: ();
7+
let mut _3: !;
8+
let _4: bool;
9+
let mut _5: &();
10+
let mut _6: !;
11+
let mut _7: &();
12+
let _8: ();
13+
let mut _9: !;
14+
15+
bb0: {
16+
StorageLive(_4);
17+
StorageLive(_5);
18+
StorageLive(_6);
19+
_6 = _1;
20+
unreachable;
21+
}
22+
23+
bb1: {
24+
StorageDead(_6);
25+
StorageLive(_7);
26+
StorageLive(_8);
27+
StorageLive(_9);
28+
_9 = _2;
29+
unreachable;
30+
}
31+
32+
bb2: {
33+
_7 = &_8;
34+
StorageDead(_9);
35+
_4 = <() as PartialEq>::eq(move _5, move _7) -> [return: bb3, unwind: bb5];
36+
}
37+
38+
bb3: {
39+
StorageDead(_7);
40+
StorageDead(_5);
41+
StorageDead(_8);
42+
StorageDead(_4);
43+
unreachable;
44+
}
45+
46+
bb4: {
47+
return;
48+
}
49+
50+
bb5 (cleanup): {
51+
resume;
52+
}
53+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// skip-filecheck
2+
#![feature(never_type)]
3+
#![allow(unreachable_code)]
4+
5+
// EMIT_MIR eq_never_type._f.built.after.mir
6+
fn _f(a: !, b: !) {
7+
// Both arguments must be references (i.e. == should auto-borrow/coerce-to-ref both arguments)
8+
// (this previously was buggy due to `NeverToAny` coercion incorrectly throwing out other
9+
// coercions)
10+
a == b;
11+
}
12+
13+
fn main() {}

tests/ui/never_type/eq-never-types.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ check-pass
2+
//
3+
// issue: rust-lang/rust#120600
4+
5+
#![allow(internal_features)]
6+
#![feature(never_type, rustc_attrs)]
7+
#![rustc_never_type_options(fallback = "never")]
8+
9+
fn ice(a: !) {
10+
a == a;
11+
}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)