Skip to content

Commit f0487ce

Browse files
committed
normalize substs during inlining
1 parent 9c302f5 commit f0487ce

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

compiler/rustc_mir/src/transform/inline.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,13 @@ impl Inliner<'tcx> {
201201
let terminator = bb_data.terminator();
202202
if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
203203
if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() {
204-
let instance = Instance::resolve(self.tcx, self.param_env, callee_def_id, substs)
205-
.ok()
206-
.flatten()?;
204+
// To resolve an instance its substs have to be fully normalized, so
205+
// we do this here.
206+
let normalized_substs = self.tcx.normalize_erasing_regions(self.param_env, substs);
207+
let instance =
208+
Instance::resolve(self.tcx, self.param_env, callee_def_id, normalized_substs)
209+
.ok()
210+
.flatten()?;
207211

208212
if let InstanceDef::Virtual(..) = instance.def {
209213
return None;

compiler/rustc_trait_selection/src/traits/codegen/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ use rustc_middle::ty::{self, TyCtxt};
1717
/// (necessarily) resolve all nested obligations on the impl. Note
1818
/// that type check should guarantee to us that all nested
1919
/// obligations *could be* resolved if we wanted to.
20+
///
2021
/// Assumes that this is run after the entire crate has been successfully type-checked.
22+
/// This also expects that `trait_ref` is fully normalized.
2123
pub fn codegen_fulfill_obligation<'tcx>(
2224
tcx: TyCtxt<'tcx>,
2325
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
2426
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
25-
// Remove any references to regions and normalize; this helps improve caching.
26-
let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
27-
27+
// Remove any references to regions; this helps improve caching.
28+
let trait_ref = tcx.erase_regions(&trait_ref);
29+
// We expect the input to be fully normalized.
30+
debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));
2831
debug!(
2932
"codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
3033
(param_env, trait_ref),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
// compile-flags:-Zmir-opt-level=2
3+
4+
// Previously ICEd because we did not normalize during inlining,
5+
// see https://github.com/rust-lang/rust/pull/77306 for more discussion.
6+
7+
pub fn write() {
8+
create()()
9+
}
10+
11+
pub fn create() -> impl FnOnce() {
12+
|| ()
13+
}
14+
15+
fn main() {
16+
write();
17+
}

0 commit comments

Comments
 (0)