about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-10-18 16:34:04 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-10-18 16:59:23 +0000
commitc1c5a1d69ace8bdfd34f449bdb00797f1fc723cc (patch)
treebfcea38043e376d9db24e8462c337ad00a20347e
parente1de04ad4e32afc6c82080a0b46408fee31dce88 (diff)
downloadrust-c1c5a1d69ace8bdfd34f449bdb00797f1fc723cc.tar.gz
rust-c1c5a1d69ace8bdfd34f449bdb00797f1fc723cc.zip
Only check in a single place if a pass is enabled.
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs33
-rw-r--r--tests/mir-opt/inline/unit_test.rs19
3 files changed, 41 insertions, 13 deletions
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 01136974730..d579420ecb8 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -383,7 +383,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     let is_fn_like = tcx.def_kind(def).is_fn_like();
     if is_fn_like {
         // Do not compute the mir call graph without said call graph actually being used.
-        if inline::Inline.is_enabled(&tcx.sess) {
+        if pm::should_run_pass(tcx, &inline::Inline) {
             tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
         }
     }
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 5abb2f3d041..a8aba29adcd 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -83,6 +83,25 @@ pub fn run_passes<'tcx>(
     run_passes_inner(tcx, body, passes, phase_change, true);
 }
 
+pub fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
+where
+    P: MirPass<'tcx> + ?Sized,
+{
+    let name = pass.name();
+
+    let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
+    let overridden =
+        overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(|(_name, polarity)| {
+            trace!(
+                pass = %name,
+                "{} as requested by flag",
+                if *polarity { "Running" } else { "Not running" },
+            );
+            *polarity
+        });
+    overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess))
+}
+
 fn run_passes_inner<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
@@ -100,19 +119,9 @@ fn run_passes_inner<'tcx>(
         for pass in passes {
             let name = pass.name();
 
-            let overridden = overridden_passes.iter().rev().find(|(s, _)| s == &*name).map(
-                |(_name, polarity)| {
-                    trace!(
-                        pass = %name,
-                        "{} as requested by flag",
-                        if *polarity { "Running" } else { "Not running" },
-                    );
-                    *polarity
-                },
-            );
-            if !overridden.unwrap_or_else(|| pass.is_enabled(&tcx.sess)) {
+            if !should_run_pass(tcx, *pass) {
                 continue;
-            }
+            };
 
             let dump_enabled = pass.is_mir_dump_enabled();
 
diff --git a/tests/mir-opt/inline/unit_test.rs b/tests/mir-opt/inline/unit_test.rs
new file mode 100644
index 00000000000..0d877bb10b4
--- /dev/null
+++ b/tests/mir-opt/inline/unit_test.rs
@@ -0,0 +1,19 @@
+// Check that `-Zmir-enable-passes=+Inline` does not ICE because of stolen MIR.
+// unit-test: Inline
+// skip-filecheck
+#![crate_type = "lib"]
+
+// Randomize `def_path_hash` by defining them under a module with different names
+macro_rules! emit {
+    ($($m:ident)*) => {$(
+        pub mod $m {
+            pub fn main() {
+                let func = || 123u8;
+                func();
+            }
+        }
+    )*};
+}
+
+// Increase the chance of triggering the bug
+emit!(m00 m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19);