From 65b029b4680313aee06362552e31187b00b6929b Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sat, 3 Aug 2024 15:33:02 -0400
Subject: [PATCH] Don't inline tainted MIR bodies

---
 compiler/rustc_mir_transform/src/inline.rs    |  4 +++
 .../polymorphization/inline-tainted-body.rs}  | 10 +++++--
 .../inline-tainted-body.stderr                | 30 +++++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)
 rename tests/{crashes/122909.rs => ui/polymorphization/inline-tainted-body.rs} (58%)
 create mode 100644 tests/ui/polymorphization/inline-tainted-body.stderr

diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 0f012242c37..324ddc5e799 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -505,6 +505,10 @@ impl<'tcx> Inliner<'tcx> {
     ) -> Result<(), &'static str> {
         let tcx = self.tcx;
 
+        if let Some(_) = callee_body.tainted_by_errors {
+            return Err("Body is tainted");
+        }
+
         let mut threshold = if self.caller_is_inline_forwarder {
             self.tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30)
         } else if cross_crate_inlinable {
diff --git a/tests/crashes/122909.rs b/tests/ui/polymorphization/inline-tainted-body.rs
similarity index 58%
rename from tests/crashes/122909.rs
rename to tests/ui/polymorphization/inline-tainted-body.rs
index 9d17ed83ea9..13aec97e22b 100644
--- a/tests/crashes/122909.rs
+++ b/tests/ui/polymorphization/inline-tainted-body.rs
@@ -1,15 +1,21 @@
 //@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
-//@ known-bug: #122909
 
+#![feature(unboxed_closures)]
 
-use std::sync::{Arc, Context, Weak};
+use std::sync::Arc;
 
 pub struct WeakOnce<T>();
+//~^ ERROR type parameter `T` is never used
+
 impl<T> WeakOnce<T> {
     extern "rust-call" fn try_get(&self) -> Option<Arc<T>> {}
+    //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
+    //~| ERROR mismatched types
 
     pub fn get(&self) -> Arc<T> {
         self.try_get()
             .unwrap_or_else(|| panic!("Singleton {} not available", std::any::type_name::<T>()))
     }
 }
+
+fn main() {}
diff --git a/tests/ui/polymorphization/inline-tainted-body.stderr b/tests/ui/polymorphization/inline-tainted-body.stderr
new file mode 100644
index 00000000000..5c3bd70adae
--- /dev/null
+++ b/tests/ui/polymorphization/inline-tainted-body.stderr
@@ -0,0 +1,30 @@
+error[E0392]: type parameter `T` is never used
+  --> $DIR/inline-tainted-body.rs:7:21
+   |
+LL | pub struct WeakOnce<T>();
+   |                     ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+  --> $DIR/inline-tainted-body.rs:11:35
+   |
+LL |     extern "rust-call" fn try_get(&self) -> Option<Arc<T>> {}
+   |                                   ^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/inline-tainted-body.rs:11:45
+   |
+LL |     extern "rust-call" fn try_get(&self) -> Option<Arc<T>> {}
+   |                           -------           ^^^^^^^^^^^^^^ expected `Option<Arc<T>>`, found `()`
+   |                           |
+   |                           implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note:   expected enum `Option<Arc<T>>`
+           found unit type `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0392.
+For more information about an error, try `rustc --explain E0308`.