about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-03 15:37:22 +0000
committerbors <bors@rust-lang.org>2024-05-03 15:37:22 +0000
commitd6d3b342e85272f5e75c0d7a1dd3a1d8becb40ac (patch)
tree9adb202e3ecf202feb709912067a555e785f39a2
parent561b5dea1e7e5c21f0fb550ca579229ceb878297 (diff)
parenta7f4a2edc67e197d3c445381b7b461047bdeb4ec (diff)
downloadrust-d6d3b342e85272f5e75c0d7a1dd3a1d8becb40ac.tar.gz
rust-d6d3b342e85272f5e75c0d7a1dd3a1d8becb40ac.zip
Auto merge of #124660 - matthiaskrgr:rollup-j8bfzfn, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #124461 (handle the targets that are missing in stage0)
 - #124492 (Generalize `adjust_from_tcx` for `Allocation`)
 - #124588 (Use `ObligationCtxt` in favor of `TraitEngine` in many more places)
 - #124612 (Add support for inputing via stdin with run-make-support)
 - #124613 (Allow fmt to run on rmake.rs test files)
 - #124649 (Fix HorizonOS build broken by #124210)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs36
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs22
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs12
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs12
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs79
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs37
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs32
-rw-r--r--compiler/rustc_traits/src/codegen.rs13
-rw-r--r--library/std/src/sys/pal/unix/fs.rs1
-rw-r--r--rustfmt.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs6
-rw-r--r--src/bootstrap/src/core/sanity.rs57
-rw-r--r--src/tools/run-make-support/src/cc.rs5
-rw-r--r--src/tools/run-make-support/src/clang.rs5
-rw-r--r--src/tools/run-make-support/src/lib.rs18
-rw-r--r--src/tools/run-make-support/src/llvm_readobj.rs6
-rw-r--r--src/tools/run-make-support/src/rustc.rs38
-rw-r--r--src/tools/run-make-support/src/rustdoc.rs39
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs8
-rw-r--r--tests/run-make/compiler-builtins/rmake.rs32
-rw-r--r--tests/run-make/exit-code/rmake.rs30
-rw-r--r--tests/run-make/print-native-static-libs/rmake.rs16
-rw-r--r--tests/run-make/print-to-output/rmake.rs6
-rw-r--r--tests/run-make/stdin-non-utf8/Makefile6
-rw-r--r--tests/run-make/stdin-non-utf8/non-utf81
-rw-r--r--tests/run-make/stdin-rustc/rmake.rs26
-rw-r--r--tests/run-make/wasm-custom-sections-opt/rmake.rs2
-rw-r--r--tests/run-make/wasm-export-all-symbols/rmake.rs2
-rw-r--r--tests/run-make/wasm-import-module/rmake.rs9
32 files changed, 355 insertions, 233 deletions
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index f2ceb470264..f101c595bdf 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -1,6 +1,6 @@
 use crate::errors::AutoDerefReachedRecursionLimit;
+use crate::traits;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
-use crate::traits::{self, TraitEngine, TraitEngineExt};
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -8,7 +8,7 @@ use rustc_session::Limit;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::Span;
-use rustc_trait_selection::traits::StructurallyNormalizeExt;
+use rustc_trait_selection::traits::ObligationCtxt;
 
 #[derive(Copy, Clone, Debug)]
 pub enum AutoderefKind {
@@ -167,25 +167,19 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
         &self,
         ty: Ty<'tcx>,
     ) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> {
-        let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.infcx);
-
-        let cause = traits::ObligationCause::misc(self.span, self.body_id);
-        let normalized_ty = match self
-            .infcx
-            .at(&cause, self.param_env)
-            .structurally_normalize(ty, &mut *fulfill_cx)
-        {
-            Ok(normalized_ty) => normalized_ty,
-            Err(errors) => {
-                // This shouldn't happen, except for evaluate/fulfill mismatches,
-                // but that's not a reason for an ICE (`predicate_may_hold` is conservative
-                // by design).
-                debug!(?errors, "encountered errors while fulfilling");
-                return None;
-            }
+        let ocx = ObligationCtxt::new(self.infcx);
+        let Ok(normalized_ty) = ocx.structurally_normalize(
+            &traits::ObligationCause::misc(self.span, self.body_id),
+            self.param_env,
+            ty,
+        ) else {
+            // We shouldn't have errors here, except for evaluate/fulfill mismatches,
+            // but that's not a reason for an ICE (`predicate_may_hold` is conservative
+            // by design).
+            // FIXME(-Znext-solver): This *actually* shouldn't happen then.
+            return None;
         };
-
-        let errors = fulfill_cx.select_where_possible(self.infcx);
+        let errors = ocx.select_where_possible();
         if !errors.is_empty() {
             // This shouldn't happen, except for evaluate/fulfill mismatches,
             // but that's not a reason for an ICE (`predicate_may_hold` is conservative
@@ -194,7 +188,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        Some((normalized_ty, fulfill_cx.pending_obligations()))
+        Some((normalized_ty, ocx.into_pending_obligations()))
     }
 
     /// Returns the final type we ended up with, which may be an inference
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 825276aef42..076c1936ded 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -45,8 +45,7 @@ use rustc_hir::Expr;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
 use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
-use rustc_infer::traits::TraitEngineExt as _;
-use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine};
+use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause};
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::traits::BuiltinImplSource;
@@ -65,7 +64,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc_trait_selection::traits::TraitEngineExt as _;
 use rustc_trait_selection::traits::{
     self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
@@ -164,11 +162,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             // Filter these cases out to make sure our coercion is more accurate.
             match res {
                 Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligations(self, obligations);
-                    let errs = fulfill_cx.select_where_possible(self);
-                    if errs.is_empty() {
-                        Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligations(obligations);
+                    if ocx.select_where_possible().is_empty() {
+                        Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
                     } else {
                         Err(TypeError::Mismatch)
                     }
@@ -631,13 +628,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 // but we need to constrain vars before processing goals mentioning
                 // them.
                 Some(ty::PredicateKind::AliasRelate(..)) => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligation(self, obligation);
-                    let errs = fulfill_cx.select_where_possible(self);
-                    if !errs.is_empty() {
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligation(obligation);
+                    if !ocx.select_where_possible().is_empty() {
                         return Err(TypeError::Mismatch);
                     }
-                    coercion.obligations.extend(fulfill_cx.pending_obligations());
+                    coercion.obligations.extend(ocx.into_pending_obligations());
                     continue;
                 }
                 _ => {
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index e3611ab28e5..f77a6115861 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -206,6 +206,18 @@ impl<'tcx> FulfillmentError<'tcx> {
     ) -> FulfillmentError<'tcx> {
         FulfillmentError { obligation, code, root_obligation }
     }
+
+    pub fn is_true_error(&self) -> bool {
+        match self.code {
+            FulfillmentErrorCode::SelectionError(_)
+            | FulfillmentErrorCode::ProjectionError(_)
+            | FulfillmentErrorCode::SubtypeError(_, _)
+            | FulfillmentErrorCode::ConstEquateError(_, _) => true,
+            FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
+                false
+            }
+        }
+    }
 }
 
 impl<'tcx> PolyTraitObligation<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 9cc5c6a2ee9..791e87735f4 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -29,9 +29,7 @@ use provenance_map::*;
 pub use init_mask::{InitChunk, InitChunkIter};
 
 /// Functionality required for the bytes of an `Allocation`.
-pub trait AllocBytes:
-    Clone + fmt::Debug + Eq + PartialEq + Hash + Deref<Target = [u8]> + DerefMut<Target = [u8]>
-{
+pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Target = [u8]> {
     /// Create an `AllocBytes` from a slice of `u8`.
     fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self;
 
@@ -346,10 +344,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
     }
 }
 
-impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
+impl Allocation {
     /// Adjust allocation from the ones in `tcx` to a custom Machine instance
-    /// with a different `Provenance` and `Extra` type.
-    pub fn adjust_from_tcx<Prov: Provenance, Extra, Err>(
+    /// with a different `Provenance`, `Extra` and `Byte` type.
+    pub fn adjust_from_tcx<Prov: Provenance, Extra, Bytes: AllocBytes, Err>(
         self,
         cx: &impl HasDataLayout,
         extra: Extra,
@@ -371,7 +369,7 @@ impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
         }
         // Create allocation.
         Ok(Allocation {
-            bytes,
+            bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align),
             provenance: ProvenanceMap::from_presorted_ptrs(new_provenance),
             init_mask: self.init_mask,
             align: self.align,
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index b2400cec42f..3dc55509dad 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -1,8 +1,9 @@
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
-use crate::traits::{self, ObligationCtxt, SelectionContext, TraitEngineExt as _};
+use crate::traits::{self, ObligationCtxt, SelectionContext};
+
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
-use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt as _};
+use rustc_infer::traits::Obligation;
 use rustc_macros::extension;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
@@ -93,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> {
                 ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
             )) {
                 Ok(Some(selection)) => {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
-                    fulfill_cx.register_predicate_obligations(self, selection.nested_obligations());
-                    Some(fulfill_cx.select_all_or_error(self))
+                    let ocx = ObligationCtxt::new(self);
+                    ocx.register_obligations(selection.nested_obligations());
+                    Some(ocx.select_all_or_error())
                 }
                 Ok(None) | Err(_) => None,
             }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 7c6dd4d3feb..97de25295b8 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -14,7 +14,6 @@ use rustc_ast_ir::visit::VisitorResult;
 use rustc_infer::infer::resolve::EagerResolver;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
-use rustc_infer::traits::{TraitEngine, TraitEngineExt};
 use rustc_macros::extension;
 use rustc_middle::infer::unify_key::ConstVariableOrigin;
 use rustc_middle::traits::query::NoSolution;
@@ -26,9 +25,9 @@ use rustc_middle::ty::TypeFoldable;
 use rustc_span::{Span, DUMMY_SP};
 
 use crate::solve::eval_ctxt::canonical;
-use crate::solve::FulfillmentCtxt;
 use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource};
 use crate::solve::{GenerateProofTree, InferCtxtEvalExt};
+use crate::traits::ObligationCtxt;
 
 pub struct InspectConfig {
     pub max_depth: usize,
@@ -74,14 +73,13 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
             .eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term)
             .map_err(|_| NoSolution)
             .and_then(|InferOk { value: (), obligations }| {
-                let mut fulfill_cx = FulfillmentCtxt::new(infcx);
-                fulfill_cx.register_predicate_obligations(infcx, obligations);
-                if fulfill_cx.select_where_possible(infcx).is_empty() {
-                    if fulfill_cx.pending_obligations().is_empty() {
-                        Ok(Certainty::Yes)
-                    } else {
-                        Ok(Certainty::AMBIGUOUS)
-                    }
+                let ocx = ObligationCtxt::new(infcx);
+                ocx.register_obligations(obligations);
+                let errors = ocx.select_all_or_error();
+                if errors.is_empty() {
+                    Ok(Certainty::Yes)
+                } else if errors.iter().all(|e| !e.is_true_error()) {
+                    Ok(Certainty::AMBIGUOUS)
                 } else {
                     Err(NoSolution)
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 86e7c42376a..59725ce9de0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -6,12 +6,9 @@
 
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::InferOk;
-use crate::regions::InferCtxtRegionExt;
 use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
-use crate::solve::{deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt};
-use crate::traits::engine::TraitEngineExt as _;
+use crate::solve::{deeply_normalize_for_diagnostics, inspect};
 use crate::traits::select::IntercrateAmbiguityCause;
-use crate::traits::structural_normalize::StructurallyNormalizeExt;
 use crate::traits::NormalizeExt;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{
@@ -22,7 +19,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt};
+use rustc_infer::traits::{util, FulfillmentErrorCode};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
@@ -35,6 +32,7 @@ use std::fmt::Debug;
 use std::ops::ControlFlow;
 
 use super::error_reporting::suggest_new_overflow_limit;
+use super::ObligationCtxt;
 
 /// Whether we do the orphan check relative to this crate or to some remote crate.
 #[derive(Copy, Clone, Debug)]
@@ -361,23 +359,27 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
     let infcx = selcx.infcx;
 
     if infcx.next_trait_solver() {
-        let mut fulfill_cx = FulfillmentCtxt::new(infcx);
-        fulfill_cx.register_predicate_obligations(infcx, obligations.iter().cloned());
-
+        let ocx = ObligationCtxt::new(infcx);
+        ocx.register_obligations(obligations.iter().cloned());
+        let errors_and_ambiguities = ocx.select_all_or_error();
         // We only care about the obligations that are *definitely* true errors.
         // Ambiguities do not prove the disjointness of two impls.
-        let errors = fulfill_cx.select_where_possible(infcx);
+        let (errors, ambiguities): (Vec<_>, Vec<_>) =
+            errors_and_ambiguities.into_iter().partition(|error| error.is_true_error());
+
         if errors.is_empty() {
-            let overflow_errors = fulfill_cx.collect_remaining_errors(infcx);
-            let overflowing_predicates = overflow_errors
-                .into_iter()
-                .filter(|e| match e.code {
-                    FulfillmentErrorCode::Ambiguity { overflow: Some(true) } => true,
-                    _ => false,
-                })
-                .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
-                .collect();
-            IntersectionHasImpossibleObligations::No { overflowing_predicates }
+            IntersectionHasImpossibleObligations::No {
+                overflowing_predicates: ambiguities
+                    .into_iter()
+                    .filter(|error| {
+                        matches!(
+                            error.code,
+                            FulfillmentErrorCode::Ambiguity { overflow: Some(true) }
+                        )
+                    })
+                    .map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
+                    .collect(),
+            }
         } else {
             IntersectionHasImpossibleObligations::Yes
         }
@@ -589,13 +591,14 @@ fn try_prove_negated_where_clause<'tcx>(
     // Without this, we over-eagerly register coherence ambiguity candidates when
     // impl candidates do exist.
     let ref infcx = root_infcx.fork_with_intercrate(false);
-    let mut fulfill_cx = FulfillmentCtxt::new(infcx);
-
-    fulfill_cx.register_predicate_obligation(
-        infcx,
-        Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, negative_predicate),
-    );
-    if !fulfill_cx.select_all_or_error(infcx).is_empty() {
+    let ocx = ObligationCtxt::new(infcx);
+    ocx.register_obligation(Obligation::new(
+        infcx.tcx,
+        ObligationCause::dummy(),
+        param_env,
+        negative_predicate,
+    ));
+    if !ocx.select_all_or_error().is_empty() {
         return false;
     }
 
@@ -603,8 +606,7 @@ fn try_prove_negated_where_clause<'tcx>(
     // if that wasn't implemented just for LocalDefId, and we'd need to do
     // the normalization ourselves since this is totally fallible...
     let outlives_env = OutlivesEnvironment::new(param_env);
-
-    let errors = infcx.resolve_regions(&outlives_env);
+    let errors = ocx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
         return false;
     }
@@ -1129,22 +1131,17 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
                 result: Ok(_),
             } = cand.kind()
             {
-                let lazily_normalize_ty = |ty: Ty<'tcx>| {
-                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx);
+                let lazily_normalize_ty = |mut ty: Ty<'tcx>| {
                     if matches!(ty.kind(), ty::Alias(..)) {
-                        // FIXME(-Znext-solver=coherence): we currently don't
-                        // normalize opaque types here, resulting in diverging behavior
-                        // for TAITs.
-                        match infcx
-                            .at(&ObligationCause::dummy(), param_env)
-                            .structurally_normalize(ty, &mut *fulfill_cx)
-                        {
-                            Ok(ty) => Ok(ty),
-                            Err(_errs) => Err(()),
+                        let ocx = ObligationCtxt::new(infcx);
+                        ty = ocx
+                            .structurally_normalize(&ObligationCause::dummy(), param_env, ty)
+                            .map_err(|_| ())?;
+                        if !ocx.select_where_possible().is_empty() {
+                            return Err(());
                         }
-                    } else {
-                        Ok(ty)
                     }
+                    Ok(ty)
                 };
 
                 infcx.probe(|_| {
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 432d51ff8f9..551c8e7702e 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -7,6 +7,7 @@ use crate::regions::InferCtxtRegionExt;
 use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
 use crate::traits::error_reporting::TypeErrCtxtExt;
 use crate::traits::NormalizeExt;
+use crate::traits::StructurallyNormalizeExt;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -15,6 +16,7 @@ use rustc_infer::infer::canonical::{
     Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
 };
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::RegionResolutionError;
 use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
 use rustc_infer::traits::{
     FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
@@ -117,6 +119,17 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
     }
 
+    pub fn structurally_normalize(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        value: Ty<'tcx>,
+    ) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
+        self.infcx
+            .at(cause, param_env)
+            .structurally_normalize(value, &mut **self.engine.borrow_mut())
+    }
+
     pub fn eq<T: ToTrace<'tcx>>(
         &self,
         cause: &ObligationCause<'tcx>,
@@ -182,6 +195,18 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.engine.borrow_mut().select_all_or_error(self.infcx)
     }
 
+    /// Returns the not-yet-processed and stalled obligations from the
+    /// `ObligationCtxt`.
+    ///
+    /// Takes ownership of the context as doing operations such as
+    /// [`ObligationCtxt::eq`] afterwards will result in other obligations
+    /// getting ignored. You can make a new `ObligationCtxt` if this
+    /// needs to be done in a loop, for example.
+    #[must_use]
+    pub fn into_pending_obligations(self) -> Vec<PredicateObligation<'tcx>> {
+        self.engine.borrow().pending_obligations()
+    }
+
     /// Resolves regions and reports errors.
     ///
     /// Takes ownership of the context as doing trait solving afterwards
@@ -199,6 +224,18 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         }
     }
 
+    /// Resolves regions and reports errors.
+    ///
+    /// Takes ownership of the context as doing trait solving afterwards
+    /// will result in region constraints getting ignored.
+    #[must_use]
+    pub fn resolve_regions(
+        self,
+        outlives_env: &OutlivesEnvironment<'tcx>,
+    ) -> Vec<RegionResolutionError<'tcx>> {
+        self.infcx.resolve_regions(outlives_env)
+    }
+
     pub fn assumed_wf_types_and_report_errors(
         &self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 5f2a8944135..87d240cf8ac 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -1,9 +1,10 @@
-use rustc_infer::traits::{TraitEngine, TraitEngineExt};
 use rustc_macros::extension;
 
 use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::InferCtxt;
-use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
+use crate::traits::{
+    EvaluationResult, ObligationCtxt, OverflowError, PredicateObligation, SelectionContext,
+};
 
 #[extension(pub trait InferCtxtExt<'tcx>)]
 impl<'tcx> InferCtxt<'tcx> {
@@ -67,21 +68,22 @@ impl<'tcx> InferCtxt<'tcx> {
 
         if self.next_trait_solver() {
             self.probe(|snapshot| {
-                let mut fulfill_cx = crate::solve::FulfillmentCtxt::new(self);
-                fulfill_cx.register_predicate_obligation(self, obligation.clone());
-                // True errors
-                // FIXME(-Znext-solver): Overflows are reported as ambig here, is that OK?
-                if !fulfill_cx.select_where_possible(self).is_empty() {
-                    Ok(EvaluationResult::EvaluatedToErr)
-                } else if !fulfill_cx.select_all_or_error(self).is_empty() {
-                    Ok(EvaluationResult::EvaluatedToAmbig)
-                } else if self.opaque_types_added_in_snapshot(snapshot) {
-                    Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes)
+                let ocx = ObligationCtxt::new(self);
+                ocx.register_obligation(obligation.clone());
+                let mut result = EvaluationResult::EvaluatedToOk;
+                for error in ocx.select_all_or_error() {
+                    if error.is_true_error() {
+                        return Ok(EvaluationResult::EvaluatedToErr);
+                    } else {
+                        result = result.max(EvaluationResult::EvaluatedToAmbig);
+                    }
+                }
+                if self.opaque_types_added_in_snapshot(snapshot) {
+                    result = result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes);
                 } else if self.region_constraints_added_in_snapshot(snapshot) {
-                    Ok(EvaluationResult::EvaluatedToOkModuloRegions)
-                } else {
-                    Ok(EvaluationResult::EvaluatedToOk)
+                    result = result.max(EvaluationResult::EvaluatedToOkModuloRegions);
                 }
+                Ok(result)
             })
         } else {
             assert!(!self.intercrate);
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index 51f38964415..b96b1b67a74 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -4,14 +4,13 @@
 // general routines.
 
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
+use rustc_infer::traits::FulfillmentErrorCode;
 use rustc_middle::bug;
 use rustc_middle::traits::CodegenObligationError;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::{
-    ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
-    Unimplemented,
+    ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext, Unimplemented,
 };
 use tracing::debug;
 
@@ -51,15 +50,15 @@ pub fn codegen_select_candidate<'tcx>(
     // Currently, we use a fulfillment context to completely resolve
     // all nested obligations. This is because they can inform the
     // inference of the impl's type parameters.
-    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&infcx);
-    let impl_source = selection.map(|predicate| {
-        fulfill_cx.register_predicate_obligation(&infcx, predicate);
+    let ocx = ObligationCtxt::new(&infcx);
+    let impl_source = selection.map(|obligation| {
+        ocx.register_obligation(obligation);
     });
 
     // In principle, we only need to do this so long as `impl_source`
     // contains unbound type parameters. It could be a slight
     // optimization to stop iterating early.
-    let errors = fulfill_cx.select_all_or_error(&infcx);
+    let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
         // `rustc_monomorphize::collector` assumes there are no type errors.
         // Cycle errors are the only post-monomorphization errors possible; emit them now so
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index d2006dfc12b..32cdd13fbeb 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -860,6 +860,7 @@ impl Drop for Dir {
             target_os = "hurd",
             target_os = "espidf",
             target_os = "fuchsia",
+            target_os = "horizon",
         )))]
         {
             let fd = unsafe { libc::dirfd(self.0) };
diff --git a/rustfmt.toml b/rustfmt.toml
index 0b0674af8b4..67219b15d20 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -13,7 +13,7 @@ ignore = [
 
     # tests for now are not formatted, as they are sometimes pretty-printing constrained
     # (and generally rustfmt can move around comments in UI-testing incompatible ways)
-    "/tests/",
+    "!/tests/run-make/*/rmake.rs",
 
     # do not format submodules
     # FIXME: sync submodule list with tidy/bootstrap/etc
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 9fc65a0a73a..d9dc34c0137 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -115,7 +115,11 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
     let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
     let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
     for ignore in rustfmt_config.ignore {
-        fmt_override.add(&format!("!{ignore}")).expect(&ignore);
+        if let Some(ignore) = ignore.strip_prefix('!') {
+            fmt_override.add(ignore).expect(ignore);
+        } else {
+            fmt_override.add(&format!("!{ignore}")).expect(&ignore);
+        }
     }
     let git_available = match Command::new("git")
         .arg("--version")
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 6ccf29fb6cb..0c069a54069 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -26,6 +26,17 @@ pub struct Finder {
     path: OsString,
 }
 
+// During sanity checks, we search for target names to determine if they exist in the compiler's built-in
+// target list (`rustc --print target-list`). While a target name may be present in the stage2 compiler,
+// it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
+//
+// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
+const STAGE0_MISSING_TARGETS: &[&str] = &[
+    // just a dummy comment so the list doesn't get onelined
+    "aarch64-apple-visionos",
+    "aarch64-apple-visionos-sim",
+];
+
 impl Finder {
     pub fn new() -> Self {
         Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
@@ -178,32 +189,40 @@ than building it.
             continue;
         }
 
-        // Check if there exists a built-in target in the list of supported targets.
-        let mut has_target = false;
         let target_str = target.to_string();
 
-        let supported_target_list =
-            output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]));
+        // Ignore fake targets that are only used for unit tests in bootstrap.
+        if !["A", "B", "C"].contains(&target_str.as_str()) {
+            let mut has_target = false;
+
+            let supported_target_list =
+                output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]));
+
+            // Check if it's a built-in target.
+            has_target |= supported_target_list.contains(&target_str);
+            has_target |= STAGE0_MISSING_TARGETS.contains(&target_str.as_str());
 
-        has_target |= supported_target_list.contains(&target_str);
+            if !has_target {
+                // This might also be a custom target, so check the target file that could have been specified by the user.
+                if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") {
+                    let mut target_filename = OsString::from(&target_str);
+                    // Target filename ends with `.json`.
+                    target_filename.push(".json");
 
-        // If not, check for a valid file location that may have been specified
-        // by the user for the custom target.
-        if let Some(custom_target_path) = env::var_os("RUST_TARGET_PATH") {
-            let mut target_os_str = OsString::from(&target_str);
-            target_os_str.push(".json");
-            // Recursively traverse through nested directories.
-            let walker = WalkDir::new(custom_target_path).into_iter();
-            for entry in walker.filter_map(|e| e.ok()) {
-                has_target |= entry.file_name() == target_os_str;
+                    // Recursively traverse through nested directories.
+                    let walker = WalkDir::new(custom_target_path).into_iter();
+                    for entry in walker.filter_map(|e| e.ok()) {
+                        has_target |= entry.file_name() == target_filename;
+                    }
+                }
             }
-        }
 
-        if !has_target && !["A", "B", "C"].contains(&target_str.as_str()) {
-            panic!(
-                "No such target exists in the target list,
+            if !has_target {
+                panic!(
+                    "No such target exists in the target list,
                 specify a correct location of the JSON specification file for custom targets!"
-            );
+                );
+            }
         }
 
         if !build.config.dry_run() {
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
index 146123793be..4082639f618 100644
--- a/src/tools/run-make-support/src/cc.rs
+++ b/src/tools/run-make-support/src/cc.rs
@@ -71,6 +71,11 @@ impl Cc {
 
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
 
 /// `EXTRACFLAGS`
diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs
index ed9f8383dc3..c30ba29ed76 100644
--- a/src/tools/run-make-support/src/clang.rs
+++ b/src/tools/run-make-support/src/clang.rs
@@ -70,4 +70,9 @@ impl Clang {
         self.cmd.arg(format!("-fuse-ld={ld}"));
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index a874c1313b5..239f90b23c9 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -144,7 +144,7 @@ pub fn set_host_rpath(cmd: &mut Command) {
 }
 
 /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
-/// containing a `cmd: Command` field. The provided helpers are:
+/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
 ///
 /// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended
 ///    to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add
@@ -160,7 +160,12 @@ pub fn set_host_rpath(cmd: &mut Command) {
 /// Example usage:
 ///
 /// ```ignore (illustrative)
-/// struct CommandWrapper { cmd: Command }
+/// struct CommandWrapper { cmd: Command } // <- required `cmd` field
+///
+/// impl CommandWrapper {
+///     /// Get the [`Output`][::std::process::Output] of the finished process.
+///     pub fn output(&mut self) -> Output { /* ... */ } // <- required `output()` method
+/// }
 ///
 /// crate::impl_common_helpers!(CommandWrapper);
 ///
@@ -231,18 +236,13 @@ macro_rules! impl_common_helpers {
                 self
             }
 
-            /// Get the [`Output`][::std::process::Output] of the finished process.
-            pub fn output(&mut self) -> ::std::process::Output {
-                self.cmd.output().expect("failed to get output of finished process")
-            }
-
             /// Run the constructed command and assert that it is successfully run.
             #[track_caller]
             pub fn run(&mut self) -> ::std::process::Output {
                 let caller_location = ::std::panic::Location::caller();
                 let caller_line_number = caller_location.line();
 
-                let output = self.cmd.output().unwrap();
+                let output = self.output();
                 if !output.status.success() {
                     handle_failed_output(&self.cmd, output, caller_line_number);
                 }
@@ -255,7 +255,7 @@ macro_rules! impl_common_helpers {
                 let caller_location = ::std::panic::Location::caller();
                 let caller_line_number = caller_location.line();
 
-                let output = self.cmd.output().unwrap();
+                let output = self.output();
                 if output.status.success() {
                     handle_failed_output(&self.cmd, output, caller_line_number);
                 }
diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs
index 32ea07e932e..4e1f2b002f3 100644
--- a/src/tools/run-make-support/src/llvm_readobj.rs
+++ b/src/tools/run-make-support/src/llvm_readobj.rs
@@ -41,4 +41,10 @@ impl LlvmReadobj {
         self.cmd.arg("--file-header");
         self
     }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        self.cmd.output().expect("failed to get output of finished process")
+    }
 }
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index ddaae3236c2..37539528ab3 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -1,7 +1,8 @@
 use std::env;
 use std::ffi::OsString;
+use std::io::Write;
 use std::path::Path;
-use std::process::{Command, Output};
+use std::process::{Command, Output, Stdio};
 
 use crate::{handle_failed_output, set_host_rpath, tmp_dir};
 
@@ -19,6 +20,7 @@ pub fn aux_build() -> Rustc {
 #[derive(Debug)]
 pub struct Rustc {
     cmd: Command,
+    stdin: Option<Box<[u8]>>,
 }
 
 crate::impl_common_helpers!(Rustc);
@@ -37,14 +39,14 @@ impl Rustc {
     /// Construct a new `rustc` invocation.
     pub fn new() -> Self {
         let cmd = setup_common();
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`).
     pub fn new_aux_build() -> Self {
         let mut cmd = setup_common();
         cmd.arg("--crate-type=lib");
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     // Argument provider methods
@@ -161,12 +163,40 @@ impl Rustc {
         self
     }
 
+    /// Specify a stdin input
+    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
+        self
+    }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        // let's make sure we piped all the input and outputs
+        self.cmd.stdin(Stdio::piped());
+        self.cmd.stdout(Stdio::piped());
+        self.cmd.stderr(Stdio::piped());
+
+        if let Some(input) = &self.stdin {
+            let mut child = self.cmd.spawn().unwrap();
+
+            {
+                let mut stdin = child.stdin.take().unwrap();
+                stdin.write_all(input.as_ref()).unwrap();
+            }
+
+            child.wait_with_output().expect("failed to get output of finished process")
+        } else {
+            self.cmd.output().expect("failed to get output of finished process")
+        }
+    }
+
     #[track_caller]
     pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
         let caller_location = std::panic::Location::caller();
         let caller_line_number = caller_location.line();
 
-        let output = self.cmd.output().unwrap();
+        let output = self.output();
         if output.status.code().unwrap() != code {
             handle_failed_output(&self.cmd, output, caller_line_number);
         }
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
index 1054ac83c10..c2c4f2e68e2 100644
--- a/src/tools/run-make-support/src/rustdoc.rs
+++ b/src/tools/run-make-support/src/rustdoc.rs
@@ -1,6 +1,7 @@
 use std::env;
+use std::io::Write;
 use std::path::Path;
-use std::process::{Command, Output};
+use std::process::{Command, Output, Stdio};
 
 use crate::{handle_failed_output, set_host_rpath};
 
@@ -17,6 +18,7 @@ pub fn rustdoc() -> Rustdoc {
 #[derive(Debug)]
 pub struct Rustdoc {
     cmd: Command,
+    stdin: Option<Box<[u8]>>,
 }
 
 crate::impl_common_helpers!(Rustdoc);
@@ -32,7 +34,7 @@ impl Rustdoc {
     /// Construct a bare `rustdoc` invocation.
     pub fn bare() -> Self {
         let cmd = setup_common();
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
@@ -40,7 +42,7 @@ impl Rustdoc {
         let mut cmd = setup_common();
         let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
         cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
-        Self { cmd }
+        Self { cmd, stdin: None }
     }
 
     /// Specify path to the input file.
@@ -62,12 +64,41 @@ impl Rustdoc {
         self
     }
 
+    /// Specify a stdin input
+    pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
+        self.cmd.stdin(Stdio::piped());
+        self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
+        self
+    }
+
+    /// Get the [`Output`][::std::process::Output] of the finished process.
+    #[track_caller]
+    pub fn output(&mut self) -> ::std::process::Output {
+        // let's make sure we piped all the input and outputs
+        self.cmd.stdin(Stdio::piped());
+        self.cmd.stdout(Stdio::piped());
+        self.cmd.stderr(Stdio::piped());
+
+        if let Some(input) = &self.stdin {
+            let mut child = self.cmd.spawn().unwrap();
+
+            {
+                let mut stdin = child.stdin.take().unwrap();
+                stdin.write_all(input.as_ref()).unwrap();
+            }
+
+            child.wait_with_output().expect("failed to get output of finished process")
+        } else {
+            self.cmd.output().expect("failed to get output of finished process")
+        }
+    }
+
     #[track_caller]
     pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
         let caller_location = std::panic::Location::caller();
         let caller_line_number = caller_location.line();
 
-        let output = self.cmd.output().unwrap();
+        let output = self.output();
         if output.status.code().unwrap() != code {
             handle_failed_output(&self.cmd, output, caller_line_number);
         }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 69c6dda4b19..4b79b910ec3 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -288,7 +288,6 @@ run-make/static-unwinding/Makefile
 run-make/staticlib-blank-lib/Makefile
 run-make/staticlib-dylib-linkage/Makefile
 run-make/std-core-cycle/Makefile
-run-make/stdin-non-utf8/Makefile
 run-make/suspicious-library/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/symbol-visibility/Makefile
diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
index fe0ceaf6b04..4b7ce4e57d5 100644
--- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
+++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
@@ -5,7 +5,7 @@
 
 use std::path::PathBuf;
 
-use run_make_support::{rustc, aux_build};
+use run_make_support::{aux_build, rustc};
 
 fn main() {
     aux_build().input("stable.rs").emit("metadata").run();
@@ -13,11 +13,7 @@ fn main() {
     let mut stable_path = PathBuf::from(env!("TMPDIR"));
     stable_path.push("libstable.rmeta");
 
-    let output = rustc()
-        .input("main.rs")
-        .emit("metadata")
-        .extern_("stable", &stable_path)
-        .output();
+    let output = rustc().input("main.rs").emit("metadata").extern_("stable", &stable_path).output();
 
     let stderr = String::from_utf8_lossy(&output.stderr);
     let version = include_str!(concat!(env!("S"), "/src/version"));
diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
index 17847848459..f5da50ebb04 100644
--- a/tests/run-make/compiler-builtins/rmake.rs
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -49,22 +49,22 @@ fn main() {
     let bootstrap_cargo = std::env::var("BOOTSTRAP_CARGO").unwrap();
     let mut cmd = std::process::Command::new(bootstrap_cargo);
     cmd.args([
-            "build",
-            "--manifest-path",
-            manifest_path.to_str().unwrap(),
-            "-Zbuild-std=core",
-            "--target",
-            &target,
-        ])
-        .env_clear()
-        .env("PATH", path)
-        .env("RUSTC", rustc)
-        .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
-        .env("CARGO_TARGET_DIR", &target_dir)
-        .env("RUSTC_BOOTSTRAP", "1")
-        // Visual Studio 2022 requires that the LIB env var be set so it can
-        // find the Windows SDK.
-        .env("LIB", std::env::var("LIB").unwrap_or_default());
+        "build",
+        "--manifest-path",
+        manifest_path.to_str().unwrap(),
+        "-Zbuild-std=core",
+        "--target",
+        &target,
+    ])
+    .env_clear()
+    .env("PATH", path)
+    .env("RUSTC", rustc)
+    .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
+    .env("CARGO_TARGET_DIR", &target_dir)
+    .env("RUSTC_BOOTSTRAP", "1")
+    // Visual Studio 2022 requires that the LIB env var be set so it can
+    // find the Windows SDK.
+    .env("LIB", std::env::var("LIB").unwrap_or_default());
     set_host_rpath(&mut cmd);
 
     let status = cmd.status().unwrap();
diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs
index f4ceabe126c..b1143153d0a 100644
--- a/tests/run-make/exit-code/rmake.rs
+++ b/tests/run-make/exit-code/rmake.rs
@@ -3,17 +3,11 @@
 use run_make_support::{rustc, rustdoc, tmp_dir};
 
 fn main() {
-    rustc()
-        .arg("success.rs")
-        .run();
+    rustc().arg("success.rs").run();
 
-    rustc()
-        .arg("--invalid-arg-foo")
-        .run_fail_assert_exit_code(1);
+    rustc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1);
 
-    rustc()
-        .arg("compile-error.rs")
-        .run_fail_assert_exit_code(1);
+    rustc().arg("compile-error.rs").run_fail_assert_exit_code(1);
 
     rustc()
         .env("RUSTC_ICE", "0")
@@ -21,21 +15,11 @@ fn main() {
         .arg("compile-error.rs")
         .run_fail_assert_exit_code(101);
 
-    rustdoc()
-        .arg("success.rs")
-        .arg("-o")
-        .arg(tmp_dir().join("exit-code"))
-        .run();
+    rustdoc().arg("success.rs").arg("-o").arg(tmp_dir().join("exit-code")).run();
 
-    rustdoc()
-        .arg("--invalid-arg-foo")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1);
 
-    rustdoc()
-        .arg("compile-error.rs")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("compile-error.rs").run_fail_assert_exit_code(1);
 
-    rustdoc()
-        .arg("lint-failure.rs")
-        .run_fail_assert_exit_code(1);
+    rustdoc().arg("lint-failure.rs").run_fail_assert_exit_code(1);
 }
diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs
index 5249920cc60..edb85d568c6 100644
--- a/tests/run-make/print-native-static-libs/rmake.rs
+++ b/tests/run-make/print-native-static-libs/rmake.rs
@@ -14,15 +14,11 @@
 
 use std::io::BufRead;
 
-use run_make_support::{rustc, is_msvc};
+use run_make_support::{is_msvc, rustc};
 
 fn main() {
     // build supporting crate
-    rustc()
-        .input("bar.rs")
-        .crate_type("rlib")
-        .arg("-lbar_cli")
-        .run();
+    rustc().input("bar.rs").crate_type("rlib").arg("-lbar_cli").run();
 
     // build main crate as staticlib
     let output = rustc()
@@ -37,7 +33,9 @@ fn main() {
     for l in output.stderr.lines() {
         let l = l.expect("utf-8 string");
 
-        let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; };
+        let Some(args) = l.strip_prefix("note: native-static-libs:") else {
+            continue;
+        };
         assert!(!found_note);
         found_note = true;
 
@@ -53,11 +51,11 @@ fn main() {
                 );
                 let found = $args.contains(&&*lib);
                 assert!(found, "unable to find lib `{}` in those linker args: {:?}", lib, $args);
-            }}
+            }};
         }
 
         assert_contains_lib!("glib-2.0" in args); // in bar.rs
-        assert_contains_lib!("systemd" in args);  // in foo.rs
+        assert_contains_lib!("systemd" in args); // in foo.rs
         assert_contains_lib!("bar_cli" in args);
         assert_contains_lib!("foo_cli" in args);
 
diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs
index f710d0dc3c9..1763cd378d2 100644
--- a/tests/run-make/print-to-output/rmake.rs
+++ b/tests/run-make/print-to-output/rmake.rs
@@ -13,11 +13,7 @@ struct Option<'a> {
 
 fn main() {
     // Printed from CodegenBackend trait impl in rustc_codegen_llvm/src/lib.rs
-    check(Option {
-        target: &target(),
-        option: "relocation-models",
-        includes: &["dynamic-no-pic"],
-    });
+    check(Option { target: &target(), option: "relocation-models", includes: &["dynamic-no-pic"] });
 
     // Printed by compiler/rustc_codegen_llvm/src/llvm_util.rs
     check(Option {
diff --git a/tests/run-make/stdin-non-utf8/Makefile b/tests/run-make/stdin-non-utf8/Makefile
deleted file mode 100644
index 709d4cf1408..00000000000
--- a/tests/run-make/stdin-non-utf8/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-include ../tools.mk
-
-all:
-	cp non-utf8 $(TMPDIR)/non-utf.rs
-	cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \
-		| $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8"
diff --git a/tests/run-make/stdin-non-utf8/non-utf8 b/tests/run-make/stdin-non-utf8/non-utf8
deleted file mode 100644
index bc87051a852..00000000000
--- a/tests/run-make/stdin-non-utf8/non-utf8
+++ /dev/null
@@ -1 +0,0 @@

diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs
new file mode 100644
index 00000000000..c07a6df4d84
--- /dev/null
+++ b/tests/run-make/stdin-rustc/rmake.rs
@@ -0,0 +1,26 @@
+//! This test checks rustc `-` (stdin) support
+
+use run_make_support::{is_windows, rustc, tmp_dir};
+
+const HELLO_WORLD: &str = r#"
+fn main() {
+    println!("Hello world!");
+}
+"#;
+
+const NOT_UTF8: &[u8] = &[0xff, 0xff, 0xff];
+
+fn main() {
+    let out_dir = tmp_dir();
+
+    // echo $HELLO_WORLD | rustc -
+    rustc().arg("-").stdin(HELLO_WORLD).run();
+    assert!(
+        out_dir.join(if !is_windows() { "rust_out" } else { "rust_out.exe" }).try_exists().unwrap()
+    );
+
+    // echo $NOT_UTF8 | rustc -
+    let output = rustc().arg("-").stdin(NOT_UTF8).run_fail();
+    let stderr = String::from_utf8(output.stderr).unwrap();
+    assert!(stderr.contains("error: couldn't read from stdin, as it did not contain valid UTF-8"));
+}
diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs
index 24570d8baf5..50916b1bf81 100644
--- a/tests/run-make/wasm-custom-sections-opt/rmake.rs
+++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs
@@ -1,6 +1,6 @@
 //@ only-wasm32-wasip1
 
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use std::path::Path;
 
diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs
index 50c99d027d5..f4c51bc4ab4 100644
--- a/tests/run-make/wasm-export-all-symbols/rmake.rs
+++ b/tests/run-make/wasm-export-all-symbols/rmake.rs
@@ -1,6 +1,6 @@
 //@ only-wasm32-wasip1
 
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use std::path::Path;
 use wasmparser::ExternalKind::*;
diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs
index 333d0df4653..6eed229e907 100644
--- a/tests/run-make/wasm-import-module/rmake.rs
+++ b/tests/run-make/wasm-import-module/rmake.rs
@@ -1,17 +1,12 @@
 //@ only-wasm32-wasip1
 
-use run_make_support::{tmp_dir, wasmparser, rustc};
+use run_make_support::{rustc, tmp_dir, wasmparser};
 use std::collections::HashMap;
 use wasmparser::TypeRef::Func;
 
 fn main() {
     rustc().input("foo.rs").target("wasm32-wasip1").run();
-    rustc()
-        .input("bar.rs")
-        .target("wasm32-wasip1")
-        .arg("-Clto")
-        .opt()
-        .run();
+    rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run();
 
     let file = std::fs::read(&tmp_dir().join("bar.wasm")).unwrap();