]> git.lizzy.rs Git - rust.git/commitdiff
normalize substs during inlining
authorBastian Kauschke <bastian_kauschke@hotmail.de>
Sun, 4 Oct 2020 14:40:06 +0000 (16:40 +0200)
committerBastian Kauschke <bastian_kauschke@hotmail.de>
Wed, 7 Oct 2020 08:04:08 +0000 (10:04 +0200)
compiler/rustc_mir/src/transform/inline.rs
compiler/rustc_trait_selection/src/traits/codegen/mod.rs
src/test/ui/mir/mir-inlining/ice-issue-77306.rs [new file with mode: 0644]

index bec1eb790478c10d6ed1f51c446dcc523078064e..e0bd4e8b68bec4f73573863ae72695bebe8796e0 100644 (file)
@@ -201,9 +201,13 @@ fn get_valid_function_call(
         let terminator = bb_data.terminator();
         if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
             if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() {
-                let instance = Instance::resolve(self.tcx, self.param_env, callee_def_id, substs)
-                    .ok()
-                    .flatten()?;
+                // To resolve an instance its substs have to be fully normalized, so
+                // we do this here.
+                let normalized_substs = self.tcx.normalize_erasing_regions(self.param_env, substs);
+                let instance =
+                    Instance::resolve(self.tcx, self.param_env, callee_def_id, normalized_substs)
+                        .ok()
+                        .flatten()?;
 
                 if let InstanceDef::Virtual(..) = instance.def {
                     return None;
index 753d64d6115f65958e48cdf1d0ca44a25bba8489..05e6c4804ff6526ff4d66bbffc2c6fb460718e40 100644 (file)
 /// (necessarily) resolve all nested obligations on the impl. Note
 /// that type check should guarantee to us that all nested
 /// obligations *could be* resolved if we wanted to.
+///
 /// Assumes that this is run after the entire crate has been successfully type-checked.
+/// This also expects that `trait_ref` is fully normalized.
 pub fn codegen_fulfill_obligation<'tcx>(
     tcx: TyCtxt<'tcx>,
     (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
 ) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
-    // Remove any references to regions and normalize; this helps improve caching.
-    let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
-
+    // Remove any references to regions; this helps improve caching.
+    let trait_ref = tcx.erase_regions(&trait_ref);
+    // We expect the input to be fully normalized.
+    debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));
     debug!(
         "codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
         (param_env, trait_ref),
diff --git a/src/test/ui/mir/mir-inlining/ice-issue-77306.rs b/src/test/ui/mir/mir-inlining/ice-issue-77306.rs
new file mode 100644 (file)
index 0000000..4d083bf
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+// compile-flags:-Zmir-opt-level=2
+
+// Previously ICEd because we did not normalize during inlining,
+// see https://github.com/rust-lang/rust/pull/77306 for more discussion.
+
+pub fn write() {
+    create()()
+}
+
+pub fn create() -> impl FnOnce() {
+   || ()
+}
+
+fn main() {
+    write();
+}