From 2e301c89c714c2126f2221664c3f754541f9b77b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 3 Jun 2022 18:44:46 +0200 Subject: [PATCH] Do not ICE when failing to normalize during inlining. --- compiler/rustc_mir_transform/src/inline.rs | 25 +++++++++++-------- .../issue-97695-double-trivial-bound.rs | 24 ++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/traits/issue-97695-double-trivial-bound.rs diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 66fb01bd464..221f4b18a58 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -157,11 +157,13 @@ impl<'tcx> Inliner<'tcx> { 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.param_env, callee_body.clone(), - ); + ) else { + return Err("failed to normalize callee body"); + }; let old_blocks = caller_body.basic_blocks().next_index(); self.inline_call(caller_body, &callsite, callee_body); @@ -252,7 +254,7 @@ impl<'tcx> Inliner<'tcx> { let func_ty = func.ty(caller_body, self.tcx); if let ty::FnDef(def_id, substs) = *func_ty.kind() { // 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 = Instance::resolve(self.tcx, self.param_env, def_id, substs).ok().flatten()?; @@ -407,14 +409,17 @@ impl<'tcx> Inliner<'tcx> { if let ty::FnDef(def_id, substs) = *callsite.callee.subst_mir(self.tcx, &f.literal.ty()).kind() { - let substs = self.tcx.normalize_erasing_regions(self.param_env, substs); - if let Ok(Some(instance)) = - Instance::resolve(self.tcx, self.param_env, def_id, substs) + if let Ok(substs) = + self.tcx.try_normalize_erasing_regions(self.param_env, substs) { - if callsite.callee.def_id() == instance.def_id() { - return Err("self-recursion"); - } else if self.history.contains(&instance) { - return Err("already inlined"); + if let Ok(Some(instance)) = + Instance::resolve(self.tcx, self.param_env, def_id, substs) + { + if callsite.callee.def_id() == instance.def_id() { + return Err("self-recursion"); + } else if self.history.contains(&instance) { + return Err("already inlined"); + } } } // Don't give intrinsics the extra penalty for calls diff --git a/src/test/ui/traits/issue-97695-double-trivial-bound.rs b/src/test/ui/traits/issue-97695-double-trivial-bound.rs new file mode 100644 index 00000000000..213605b5114 --- /dev/null +++ b/src/test/ui/traits/issue-97695-double-trivial-bound.rs @@ -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 { + fn create() -> Self; +} + +pub fn oh_no<'a, T>() +where + Wrap<'a>: Associate, + as Associate>::Associated: Create, +{ + as Associate>::Associated::create(); +} + +pub fn main() {}