Rollup merge of #97696 - cjgillot:normalize-inline, r=compiler-errors

Do not ICE when failing to normalize during inlining.

Fixes https://github.com/rust-lang/rust/issues/97695
This commit is contained in:
Matthias Krüger 2022-06-04 00:42:51 +02:00 committed by GitHub
commit 74f0bcc9c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 10 deletions

View file

@ -158,11 +158,13 @@ impl<'tcx> Inliner<'tcx> {
return Err("optimization fuel exhausted"); return Err("optimization fuel exhausted");
} }
let callee_body = callsite.callee.subst_mir_and_normalize_erasing_regions( let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
self.tcx, self.tcx,
self.param_env, self.param_env,
callee_body.clone(), callee_body.clone(),
); ) else {
return Err("failed to normalize callee body");
};
let old_blocks = caller_body.basic_blocks().next_index(); let old_blocks = caller_body.basic_blocks().next_index();
self.inline_call(caller_body, &callsite, callee_body); self.inline_call(caller_body, &callsite, callee_body);
@ -253,7 +255,7 @@ impl<'tcx> Inliner<'tcx> {
let func_ty = func.ty(caller_body, self.tcx); let func_ty = func.ty(caller_body, self.tcx);
if let ty::FnDef(def_id, substs) = *func_ty.kind() { if let ty::FnDef(def_id, substs) = *func_ty.kind() {
// To resolve an instance its substs have to be fully normalized. // To resolve an instance its substs have to be fully normalized.
let substs = self.tcx.normalize_erasing_regions(self.param_env, substs); let substs = self.tcx.try_normalize_erasing_regions(self.param_env, substs).ok()?;
let callee = let callee =
Instance::resolve(self.tcx, self.param_env, def_id, substs).ok().flatten()?; Instance::resolve(self.tcx, self.param_env, def_id, substs).ok().flatten()?;
@ -408,7 +410,9 @@ impl<'tcx> Inliner<'tcx> {
if let ty::FnDef(def_id, substs) = if let ty::FnDef(def_id, substs) =
*callsite.callee.subst_mir(self.tcx, &f.literal.ty()).kind() *callsite.callee.subst_mir(self.tcx, &f.literal.ty()).kind()
{ {
let substs = self.tcx.normalize_erasing_regions(self.param_env, substs); if let Ok(substs) =
self.tcx.try_normalize_erasing_regions(self.param_env, substs)
{
if let Ok(Some(instance)) = if let Ok(Some(instance)) =
Instance::resolve(self.tcx, self.param_env, def_id, substs) Instance::resolve(self.tcx, self.param_env, def_id, substs)
{ {
@ -418,6 +422,7 @@ impl<'tcx> Inliner<'tcx> {
return Err("already inlined"); return Err("already inlined");
} }
} }
}
// Don't give intrinsics the extra penalty for calls // Don't give intrinsics the extra penalty for calls
if tcx.is_intrinsic(def_id) { if tcx.is_intrinsic(def_id) {
cost += INSTR_COST; cost += INSTR_COST;

View file

@ -0,0 +1,24 @@
// compile-flags: -Zinline-mir --emit=mir
// build-pass
pub trait Associate {
type Associated;
}
pub struct Wrap<'a> {
pub field: &'a i32,
}
pub trait Create<T> {
fn create() -> Self;
}
pub fn oh_no<'a, T>()
where
Wrap<'a>: Associate,
<Wrap<'a> as Associate>::Associated: Create<T>,
{
<Wrap<'a> as Associate>::Associated::create();
}
pub fn main() {}