about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-21 09:14:55 +0000
committerbors <bors@rust-lang.org>2023-07-21 09:14:55 +0000
commit6b290367eca79457870fd57faa08d461d29b674e (patch)
tree47ead33529b2e1c938af67c2e7199701d81fd9fc
parent5419aa3a66fe0832269e021050b8275a2189c09f (diff)
parent45ffe41d144e3e5bc8993abcbcdd54d870a2ff53 (diff)
downloadrust-6b290367eca79457870fd57faa08d461d29b674e.tar.gz
rust-6b290367eca79457870fd57faa08d461d29b674e.zip
Auto merge of #113802 - cjgillot:check-debuginfo, r=compiler-errors
Substitute types before checking inlining compatibility.

Addresses https://github.com/rust-lang/rust/issues/112332 and https://github.com/rust-lang/rust/issues/113781

I don't have a minimal test, but I this seems to remove the ICE locally.

This whole pre-inlining validation mirrors the "real" MIR validation pass to verify that inlined MIR will still pass validation.
The debuginfo loop is added because MIR validation check projections in debuginfo.
Likewise, MIR validation only checks `is_subtype`, so there is no reason for a stronger check.

The types were not being substituted in `check_equal`, so we were not bailing out of inlining if the substituted MIR callee body would not pass validation.
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 7860cf76247..e08edfe143a 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -440,6 +440,10 @@ impl<'tcx> Inliner<'tcx> {
             validation: Ok(()),
         };
 
+        for var_debug_info in callee_body.var_debug_info.iter() {
+            checker.visit_var_debug_info(var_debug_info);
+        }
+
         // Traverse the MIR manually so we can account for the effects of inlining on the CFG.
         let mut work_list = vec![START_BLOCK];
         let mut visited = BitSet::new_empty(callee_body.basic_blocks.len());
@@ -847,7 +851,16 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
         if let ProjectionElem::Field(f, ty) = elem {
             let parent_ty = place_ref.ty(&self.callee_body.local_decls, self.tcx);
             let check_equal = |this: &mut Self, f_ty| {
-                if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
+                // Fast path if there is nothing to substitute.
+                if ty == f_ty {
+                    return;
+                }
+                let ty = this.instance.subst_mir(this.tcx, ty::EarlyBinder::bind(&ty));
+                let f_ty = this.instance.subst_mir(this.tcx, ty::EarlyBinder::bind(&f_ty));
+                if ty == f_ty {
+                    return;
+                }
+                if !util::is_subtype(this.tcx, this.param_env, ty, f_ty) {
                     trace!(?ty, ?f_ty);
                     this.validation = Err("failed to normalize projection type");
                     return;