From e8857d045a62802d30becfc8f4cb50030c9a87cc Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Tue, 17 Oct 2023 08:05:23 +0000
Subject: [PATCH 1/4] Avoid having `rustc_smir` depend on `rustc_interface` or
 `rustc_driver`

---
 Cargo.lock                                    |   2 -
 compiler/rustc_smir/Cargo.toml                |   2 -
 compiler/rustc_smir/src/rustc_internal/mod.rs | 130 ++++++++++--------
 .../stable-mir/compilation-result.rs          |  18 +--
 tests/ui-fulldeps/stable-mir/crate-info.rs    |   5 +-
 tests/ui-fulldeps/stable-mir/instance.rs      |   5 +-
 6 files changed, 89 insertions(+), 73 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index c8e7665337fb5..78cb40a8f67d1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4482,9 +4482,7 @@ name = "rustc_smir"
 version = "0.0.0"
 dependencies = [
  "rustc_data_structures",
- "rustc_driver",
  "rustc_hir",
- "rustc_interface",
  "rustc_middle",
  "rustc_span",
  "rustc_target",
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 2b77044d6bfc7..41c7d3a859437 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -5,9 +5,7 @@ edition = "2021"
 
 [dependencies]
 rustc_data_structures = { path = "../rustc_data_structures" }
-rustc_driver = { path = "../rustc_driver" }
 rustc_hir = { path = "../rustc_hir" }
-rustc_interface = { path = "../rustc_interface" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 5ea805e5739b5..5ae4e127608e6 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,22 +3,18 @@
 //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
 //! until stable MIR is complete.
 
-use crate::rustc_internal;
 use crate::rustc_smir::Tables;
 use rustc_data_structures::fx;
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_driver::{Callbacks, Compilation, RunCompiler};
-use rustc_interface::{interface, Queries};
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::ty;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::Span;
 use stable_mir::ty::IndexedVal;
-use stable_mir::CompilerError;
 use std::fmt::Debug;
 use std::hash::Hash;
-use std::ops::{ControlFlow, Index};
+use std::ops::Index;
 
 impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
     type Output = DefId;
@@ -141,63 +137,81 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
     );
 }
 
-pub struct StableMir<B = (), C = ()>
-where
-    B: Send,
-    C: Send,
-{
-    args: Vec<String>,
-    callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
-    result: Option<ControlFlow<B, C>>,
-}
+#[macro_export]
+macro_rules! run {
+    ($args:expr, $callback:expr) => {
+        run!($args, tcx, $callback)
+    };
+    ($args:expr, $tcx:ident, $callback:expr) => {{
+        use rustc_driver::{Callbacks, Compilation, RunCompiler};
+        use rustc_interface::{interface, Queries};
+        use stable_mir::CompilerError;
+        use std::ops::ControlFlow;
+
+        pub struct StableMir<B = (), C = ()>
+        where
+            B: Send,
+            C: Send,
+        {
+            args: Vec<String>,
+            callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
+            result: Option<ControlFlow<B, C>>,
+        }
 
-impl<B, C> StableMir<B, C>
-where
-    B: Send,
-    C: Send,
-{
-    /// Creates a new `StableMir` instance, with given test_function and arguments.
-    pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
-        StableMir { args, callback, result: None }
-    }
-
-    /// Runs the compiler against given target and tests it with `test_function`
-    pub fn run(&mut self) -> Result<C, CompilerError<B>> {
-        let compiler_result =
-            rustc_driver::catch_fatal_errors(|| RunCompiler::new(&self.args.clone(), self).run());
-        match (compiler_result, self.result.take()) {
-            (Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
-            (Ok(Ok(())), Some(ControlFlow::Break(value))) => Err(CompilerError::Interrupted(value)),
-            (Ok(Ok(_)), None) => Err(CompilerError::Skipped),
-            (Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
-            (Err(_), _) => Err(CompilerError::ICE),
+        impl<B, C> StableMir<B, C>
+        where
+            B: Send,
+            C: Send,
+        {
+            /// Creates a new `StableMir` instance, with given test_function and arguments.
+            pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
+                StableMir { args, callback, result: None }
+            }
+
+            /// Runs the compiler against given target and tests it with `test_function`
+            pub fn run(&mut self) -> Result<C, CompilerError<B>> {
+                let compiler_result = rustc_driver::catch_fatal_errors(|| {
+                    RunCompiler::new(&self.args.clone(), self).run()
+                });
+                match (compiler_result, self.result.take()) {
+                    (Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
+                    (Ok(Ok(())), Some(ControlFlow::Break(value))) => {
+                        Err(CompilerError::Interrupted(value))
+                    }
+                    (Ok(Ok(_)), None) => Err(CompilerError::Skipped),
+                    (Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
+                    (Err(_), _) => Err(CompilerError::ICE),
+                }
+            }
         }
-    }
-}
 
-impl<B, C> Callbacks for StableMir<B, C>
-where
-    B: Send,
-    C: Send,
-{
-    /// Called after analysis. Return value instructs the compiler whether to
-    /// continue the compilation afterwards (defaults to `Compilation::Continue`)
-    fn after_analysis<'tcx>(
-        &mut self,
-        _compiler: &interface::Compiler,
-        queries: &'tcx Queries<'tcx>,
-    ) -> Compilation {
-        queries.global_ctxt().unwrap().enter(|tcx| {
-            rustc_internal::run(tcx, || {
-                self.result = Some((self.callback)(tcx));
-            });
-            if self.result.as_ref().is_some_and(|val| val.is_continue()) {
-                Compilation::Continue
-            } else {
-                Compilation::Stop
+        impl<B, C> Callbacks for StableMir<B, C>
+        where
+            B: Send,
+            C: Send,
+        {
+            /// Called after analysis. Return value instructs the compiler whether to
+            /// continue the compilation afterwards (defaults to `Compilation::Continue`)
+            fn after_analysis<'tcx>(
+                &mut self,
+                _compiler: &interface::Compiler,
+                queries: &'tcx Queries<'tcx>,
+            ) -> Compilation {
+                queries.global_ctxt().unwrap().enter(|tcx| {
+                    rustc_internal::run(tcx, || {
+                        self.result = Some((self.callback)(tcx));
+                    });
+                    if self.result.as_ref().is_some_and(|val| val.is_continue()) {
+                        Compilation::Continue
+                    } else {
+                        Compilation::Stop
+                    }
+                })
             }
-        })
-    }
+        }
+
+        StableMir::new($args, |$tcx| $callback).run()
+    }};
 }
 
 /// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index 3ec1519fb13c4..ae6dc68523247 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -10,13 +10,15 @@
 #![feature(assert_matches)]
 
 extern crate rustc_middle;
+#[macro_use]
 extern crate rustc_smir;
+extern crate rustc_driver;
+extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
 use std::io::Write;
-use std::ops::ControlFlow;
 
 /// This test will generate and analyze a dummy crate using the stable mir.
 /// For that, it will first write the dummy crate into a file.
@@ -33,28 +35,26 @@ fn main() {
 }
 
 fn test_continue(args: Vec<String>) {
-    let continue_fn = |_: TyCtxt| ControlFlow::Continue::<(), bool>(true);
-    let result = rustc_internal::StableMir::new(args, continue_fn).run();
+    let result = run!(args, ControlFlow::Continue::<(), bool>(true));
     assert_eq!(result, Ok(true));
 }
 
 fn test_break(args: Vec<String>) {
-    let continue_fn = |_: TyCtxt| ControlFlow::Break::<bool, i32>(false);
-    let result = rustc_internal::StableMir::new(args, continue_fn).run();
+    let result = run!(args, ControlFlow::Break::<bool, i32>(false));
     assert_eq!(result, Err(stable_mir::CompilerError::Interrupted(false)));
 }
 
+#[allow(unreachable_code)]
 fn test_skipped(mut args: Vec<String>) {
     args.push("--version".to_string());
-    let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
-    let result = rustc_internal::StableMir::new(args, unreach_fn).run();
+    let result = run!(args, unreachable!() as ControlFlow<()>);
     assert_eq!(result, Err(stable_mir::CompilerError::Skipped));
 }
 
+#[allow(unreachable_code)]
 fn test_failed(mut args: Vec<String>) {
     args.push("--cfg=broken".to_string());
-    let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
-    let result = rustc_internal::StableMir::new(args, unreach_fn).run();
+    let result = run!(args, unreachable!() as ControlFlow<()>);
     assert_eq!(result, Err(stable_mir::CompilerError::CompilationFailed));
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 8a812bd3265a1..26a437f5d8698 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -12,7 +12,10 @@
 
 extern crate rustc_hir;
 extern crate rustc_middle;
+#[macro_use]
 extern crate rustc_smir;
+extern crate rustc_driver;
+extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_hir::def::DefKind;
@@ -185,7 +188,7 @@ fn main() {
         CRATE_NAME.to_string(),
         path.to_string(),
     ];
-    rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
+    run!(args, tcx, test_stable_mir(tcx)).unwrap();
 }
 
 fn generate_input(path: &str) -> std::io::Result<()> {
diff --git a/tests/ui-fulldeps/stable-mir/instance.rs b/tests/ui-fulldeps/stable-mir/instance.rs
index fe06d9b5cc967..0ae0ab9c2e3a4 100644
--- a/tests/ui-fulldeps/stable-mir/instance.rs
+++ b/tests/ui-fulldeps/stable-mir/instance.rs
@@ -11,8 +11,11 @@
 #![feature(control_flow_enum)]
 
 extern crate rustc_middle;
+#[macro_use]
 extern crate rustc_smir;
 extern crate stable_mir;
+extern crate rustc_driver;
+extern crate rustc_interface;
 
 use rustc_middle::ty::TyCtxt;
 
@@ -61,7 +64,7 @@ fn main() {
         CRATE_NAME.to_string(),
         path.to_string(),
     ];
-    rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
+    run!(args, tcx, test_stable_mir(tcx)).unwrap();
 }
 
 fn generate_input(path: &str) -> std::io::Result<()> {

From 54eef1601de6ace9d0e49bee1b567292f0918a1f Mon Sep 17 00:00:00 2001
From: blyxyas <blyxyas@gmail.com>
Date: Wed, 18 Oct 2023 12:34:16 +0200
Subject: [PATCH 2/4] Change my name in mailmap

---
 .mailmap | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.mailmap b/.mailmap
index 26d6be9f0c600..37b1e350108ed 100644
--- a/.mailmap
+++ b/.mailmap
@@ -74,6 +74,7 @@ Benoît Cortier <benoit.cortier@fried-world.eu>
 Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
 Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
 blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
+blyxyas <blyxyas@gmail.com> Alejandra González <blyxyas@gmail.com>
 boolean_coercion <booleancoercion@gmail.com>
 Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
 bors <bors@rust-lang.org> bors[bot] <26634292+bors[bot]@users.noreply.github.com>

From c1c5a1d69ace8bdfd34f449bdb00797f1fc723cc Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Wed, 18 Oct 2023 16:34:04 +0000
Subject: [PATCH 3/4] Only check in a single place if a pass is enabled.

---
 compiler/rustc_mir_transform/src/lib.rs       |  2 +-
 .../rustc_mir_transform/src/pass_manager.rs   | 33 ++++++++++++-------
 tests/mir-opt/inline/unit_test.rs             | 19 +++++++++++
 3 files changed, 41 insertions(+), 13 deletions(-)
 create mode 100644 tests/mir-opt/inline/unit_test.rs

diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 0113697473002..d579420ecb835 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 5abb2f3d0412a..a8aba29adcd13 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 0000000000000..0d877bb10b425
--- /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);

From 973d5895829e424e9a8df9cf4de08682760752c8 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Fri, 6 Oct 2023 19:40:16 +0000
Subject: [PATCH 4/4] Bump COINDUCTIVE_OVERLAP_IN_COHERENCE

---
 compiler/rustc_lint_defs/src/builtin.rs       |  4 +--
 ...rn-when-cycle-is-error-in-coherence.stderr | 25 +++++++++++++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 96a98393fb289..c8d42937f7bd8 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4449,11 +4449,11 @@ declare_lint! {
     /// on itself), the blanket impl is not considered to hold for `u8`. This will
     /// change in a future release.
     pub COINDUCTIVE_OVERLAP_IN_COHERENCE,
-    Warn,
+    Deny,
     "impls that are not considered to overlap may be considered to \
     overlap in the future",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
         reference: "issue #114040 <https://github.com/rust-lang/rust/issues/114040>",
     };
 }
diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
index ecc73d994f9ac..4f32639a63107 100644
--- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
+++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
@@ -24,3 +24,28 @@ LL | #![deny(coinductive_overlap_in_coherence)]
 
 error: aborting due to previous error
 
+Future incompatibility report: Future breakage diagnostic:
+error: implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
+  --> $DIR/warn-when-cycle-is-error-in-coherence.rs:13:1
+   |
+LL |   #[derive(PartialEq, Default)]
+   |            --------- the second impl is here
+...
+LL | / impl<T, Q> PartialEq<Q> for Interval<T>
+LL | |
+LL | |
+LL | | where
+LL | |     T: Borrow<Q>,
+LL | |     Q: ?Sized + PartialOrd,
+   | |___________________________^ the first impl is here
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #114040 <https://github.com/rust-lang/rust/issues/114040>
+   = note: impls that are not considered to overlap may be considered to overlap in the future
+   = note: `Interval<_>: PartialOrd` may be considered to hold in future releases, causing the impls to overlap
+note: the lint level is defined here
+  --> $DIR/warn-when-cycle-is-error-in-coherence.rs:1:9
+   |
+LL | #![deny(coinductive_overlap_in_coherence)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+