Skip to content

Commit 04dac42

Browse files
authored
Rollup merge of #105455 - lcnr:correct-reveal-in-validate, r=jackh726
use the correct `Reveal` during validation supersedes #105454. Deals with #105009 (comment), not closing #105009 as the ICE may leak into beta The issue was the following: - we optimize the mir, using `Reveal::All` - some optimization relies on the hidden type of an opaque type - we then validate using `Reveal::UserFacing` again which is not able to observe the hidden type r? `@jackh726`
2 parents 6111a73 + e73ef59 commit 04dac42

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use rustc_data_structures::fx::FxHashSet;
44
use rustc_index::bit_set::BitSet;
5+
use rustc_infer::traits::Reveal;
56
use rustc_middle::mir::interpret::Scalar;
67
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
78
use rustc_middle::mir::visit::{PlaceContext, Visitor};
@@ -44,8 +45,11 @@ impl<'tcx> MirPass<'tcx> for Validator {
4445
return;
4546
}
4647
let def_id = body.source.def_id();
47-
let param_env = tcx.param_env(def_id);
4848
let mir_phase = self.mir_phase;
49+
let param_env = match mir_phase.reveal() {
50+
Reveal::UserFacing => tcx.param_env(def_id),
51+
Reveal::All => tcx.param_env_reveal_all_normalized(def_id),
52+
};
4953

5054
let always_live_locals = always_storage_live_locals(body);
5155
let storage_liveness = MaybeStorageLive::new(always_live_locals)

compiler/rustc_middle/src/mir/syntax.rs

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection};
77

88
use crate::mir::coverage::{CodeRegion, CoverageKind};
9+
use crate::traits::Reveal;
910
use crate::ty::adjustment::PointerCast;
1011
use crate::ty::subst::SubstsRef;
1112
use crate::ty::{self, List, Ty};
@@ -100,6 +101,13 @@ impl MirPhase {
100101
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
101102
}
102103
}
104+
105+
pub fn reveal(&self) -> Reveal {
106+
match *self {
107+
MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
108+
MirPhase::Runtime(_) => Reveal::All,
109+
}
110+
}
103111
}
104112

105113
/// See [`MirPhase::Analysis`].
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Regression test for #105009. the issue here was that even after the `RevealAll` pass,
2+
// `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing
3+
// opaque types with their revealed version, resulting in an ICE.
4+
//
5+
// We're using these flags to run the `RevealAll` pass while making it less likely to
6+
// accidentally removing the assignment from `Foo<fn_ptr>` to `Foo<fn_def>`.
7+
8+
// compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir
9+
// run-pass
10+
11+
use std::hint::black_box;
12+
13+
trait Func {
14+
type Ret: Id;
15+
}
16+
17+
trait Id {
18+
type Assoc;
19+
}
20+
impl Id for u32 {
21+
type Assoc = u32;
22+
}
23+
impl Id for i32 {
24+
type Assoc = i32;
25+
}
26+
27+
impl<F: FnOnce() -> R, R: Id> Func for F {
28+
type Ret = R;
29+
}
30+
31+
fn bar() -> impl Copy + Id {
32+
0u32
33+
}
34+
35+
struct Foo<T: Func> {
36+
_func: T,
37+
value: Option<<<T as Func>::Ret as Id>::Assoc>,
38+
}
39+
40+
fn main() {
41+
let mut fn_def = black_box(Foo {
42+
_func: bar,
43+
value: None,
44+
});
45+
let fn_ptr = black_box(Foo {
46+
_func: bar as fn() -> _,
47+
value: None,
48+
});
49+
50+
fn_def.value = fn_ptr.value;
51+
black_box(fn_def);
52+
}

0 commit comments

Comments
 (0)