Auto merge of #124694 - compiler-errors:rollup-pfou5uu, r=compiler-errors

Rollup of 8 pull requests

Successful merges:

 - #124418 (Use a proof tree visitor to refine the `Obligation` for error reporting in new solver)
 - #124480 (Change `SIGPIPE` ui from `#[unix_sigpipe = "..."]` to `-Zon-broken-pipe=...`)
 - #124648 (Trim crate graph)
 - #124656 (release notes 1.78: add link to interior-mut breaking change)
 - #124658 (Migrate `run-make/doctests-keep-binaries` to new rmake.rs format)
 - #124678 (Stabilize `split_at_checked`)
 - #124681 (zkvm: fix run_tests)
 - #124687 (Make `Bounds.clauses` private)

r? `@ghost`
`@rustbot` modify labels: rollup
diff --git a/Cargo.lock b/Cargo.lock
index 7e4db4f..c034cba 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3824,7 +3824,6 @@
  "rustc_session",
  "rustc_smir",
  "rustc_span",
- "rustc_symbol_mangling",
  "rustc_target",
  "rustc_trait_selection",
  "rustc_ty_utils",
@@ -4008,7 +4007,6 @@
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
- "rustc_graphviz",
  "rustc_hir",
  "rustc_hir_analysis",
  "rustc_hir_pretty",
@@ -4468,7 +4466,6 @@
  "rustc_errors",
  "rustc_fluent_macro",
  "rustc_hir",
- "rustc_hir_analysis",
  "rustc_macros",
  "rustc_middle",
  "rustc_session",
@@ -4515,7 +4512,6 @@
  "rustc_session",
  "rustc_span",
  "rustc_target",
- "rustc_type_ir",
  "smallvec",
  "thin-vec",
  "tracing",
diff --git a/RELEASES.md b/RELEASES.md
index 104ea49..3080f03 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -102,6 +102,10 @@
 - [Change equality of higher ranked types to not rely on subtyping](https://github.com/rust-lang/rust/pull/118247)
 - [When called, additionally check bounds on normalized function return type](https://github.com/rust-lang/rust/pull/118882)
 - [Expand coverage for `arithmetic_overflow` lint](https://github.com/rust-lang/rust/pull/119432/)
+- [Fix detection of potential interior mutability in `const` initializers](https://github.com/rust-lang/rust/issues/121250)
+  This code was accidentally accepted. The fix can break generic code that borrows a value of unknown type,
+  as there is currently no way to declare "this type has no interior mutability". In the future, stabilizing
+  the [`Freeze` trait](https://github.com/rust-lang/rust/issues/121675) will allow proper support for such code.
 
 <a id="1.78.0-Internal-Changes"></a>
 
diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs
index 434b978..7ba5840 100644
--- a/compiler/rustc/src/main.rs
+++ b/compiler/rustc/src/main.rs
@@ -1,5 +1,3 @@
-#![feature(unix_sigpipe)]
-
 // A note about jemalloc: rustc uses jemalloc when built for CI and
 // distribution. The obvious way to do this is with the `#[global_allocator]`
 // mechanism. However, for complicated reasons (see
@@ -34,7 +32,6 @@
 // https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef
 // for an example of how to do so.
 
-#[unix_sigpipe = "sig_dfl"]
 fn main() {
     // See the comment at the top of this file for an explanation of this.
     #[cfg(feature = "jemalloc-sys")]
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 2c71766..2450ac8 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -307,7 +307,7 @@
         return ExpandResult::Ready(Err(guar));
     }
 
-    let to_span = |inner_span: rustc_parse_format::InnerSpan| {
+    let to_span = |inner_span: parse::InnerSpan| {
         is_source_literal.then(|| {
             fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end })
         })
@@ -577,7 +577,7 @@
 fn invalid_placeholder_type_error(
     ecx: &ExtCtxt<'_>,
     ty: &str,
-    ty_span: Option<rustc_parse_format::InnerSpan>,
+    ty_span: Option<parse::InnerSpan>,
     fmt_span: Span,
 ) {
     let sp = ty_span.map(|sp| fmt_span.from_inner(InnerSpan::new(sp.start, sp.end)));
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index a8bba3a..cb37644 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -42,9 +42,8 @@
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_resolve = { path = "../rustc_resolve" }
 rustc_session = { path = "../rustc_session" }
-rustc_smir ={ path = "../rustc_smir" }
+rustc_smir = { path = "../rustc_smir" }
 rustc_span = { path = "../rustc_span" }
-rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index b3a1e29..4696917 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -13,7 +13,7 @@
 use rustc_span::Span;
 use rustc_target::abi::TargetDataLayoutErrors;
 use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
-use rustc_type_ir as type_ir;
+use rustc_type_ir::{ClosureKind, FloatTy};
 use std::backtrace::Backtrace;
 use std::borrow::Cow;
 use std::fmt;
@@ -196,7 +196,7 @@
     }
 }
 
-impl IntoDiagArg for type_ir::FloatTy {
+impl IntoDiagArg for FloatTy {
     fn into_diag_arg(self) -> DiagArgValue {
         DiagArgValue::Str(Cow::Borrowed(self.name_str()))
     }
@@ -252,7 +252,7 @@
     }
 }
 
-impl IntoDiagArg for type_ir::ClosureKind {
+impl IntoDiagArg for ClosureKind {
     fn into_diag_arg(self) -> DiagArgValue {
         DiagArgValue::Str(self.as_str().into())
     }
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 9d3aac6..9c33cc8 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -396,10 +396,6 @@
     ),
 
     // Entry point:
-    gated!(
-        unix_sigpipe, Normal, template!(NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing,
-        EncodeCrossCrate::Yes, experimental!(unix_sigpipe)
-    ),
     ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
     ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
     ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index e7d7a9f..fe50499 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -619,8 +619,6 @@
     /// Allows creation of instances of a struct by moving fields that have
     /// not changed from prior instances of the same struct (RFC #2528)
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
-    /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
-    (unstable, unix_sigpipe, "1.65.0", Some(97889)),
     /// Allows unnamed fields of struct and union type
     (incomplete, unnamed_fields, "1.74.0", Some(49804)),
     /// Allows unsized fn parameters.
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index aafb5c1..5562b81 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -23,7 +23,7 @@
 /// include the self type (e.g., `trait_bounds`) but in others we do not
 #[derive(Default, PartialEq, Eq, Clone, Debug)]
 pub struct Bounds<'tcx> {
-    pub clauses: Vec<(ty::Clause<'tcx>, Span)>,
+    clauses: Vec<(ty::Clause<'tcx>, Span)>,
 }
 
 impl<'tcx> Bounds<'tcx> {
diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml
index 9e7f077..73a7756 100644
--- a/compiler/rustc_hir_typeck/Cargo.toml
+++ b/compiler/rustc_hir_typeck/Cargo.toml
@@ -12,7 +12,6 @@
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
-rustc_graphviz = { path = "../rustc_graphviz" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_hir_analysis = { path = "../rustc_hir_analysis" }
 rustc_hir_pretty = { path = "../rustc_hir_pretty" }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 382dba5f..8c7ae7f 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -10,7 +10,6 @@
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::TypeVariableOrigin;
-use rustc_lint as lint;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
@@ -684,7 +683,7 @@
             {
                 // `mut x` resets the binding mode in edition <= 2021.
                 self.tcx.emit_node_span_lint(
-                    lint::builtin::DEREFERENCING_MUT_BINDING,
+                    rustc_lint::builtin::DEREFERENCING_MUT_BINDING,
                     pat.hir_id,
                     pat.span,
                     errors::DereferencingMutBinding { span: pat.span },
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index b593c41..76d5d7a 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -4,7 +4,6 @@
 use crate::util;
 
 use rustc_ast::{self as ast, visit};
-use rustc_borrowck as mir_borrowck;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::parallel;
 use rustc_data_structures::steal::Steal;
@@ -20,7 +19,6 @@
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
-use rustc_mir_build as mir_build;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
 use rustc_passes::{abi_test, hir_stats, layout_test};
 use rustc_resolve::Resolver;
@@ -616,8 +614,8 @@
     proc_macro_decls::provide(providers);
     rustc_const_eval::provide(providers);
     rustc_middle::hir::provide(providers);
-    mir_borrowck::provide(providers);
-    mir_build::provide(providers);
+    rustc_borrowck::provide(providers);
+    rustc_mir_build::provide(providers);
     rustc_mir_transform::provide(providers);
     rustc_monomorphize::provide(providers);
     rustc_privacy::provide(providers);
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index db150cc..36f9dda 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -20,7 +20,7 @@
 use rustc_span::symbol::sym;
 use rustc_span::{FileName, SourceFileHashAlgorithm};
 use rustc_target::spec::{
-    CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi,
+    CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
 };
 use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
 use std::collections::{BTreeMap, BTreeSet};
@@ -809,6 +809,7 @@
     tracked!(no_profiler_runtime, true);
     tracked!(no_trait_vptr, true);
     tracked!(no_unique_section_names, true);
+    tracked!(on_broken_pipe, OnBrokenPipe::Kill);
     tracked!(oom, OomStrategy::Panic);
     tracked!(osx_rpath_install_name, true);
     tracked!(packed_bundled_libs, true);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 02dcfe9..ce4d382 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -7,18 +7,16 @@
 use rustc_metadata::{load_symbol_from_dylib, DylibError};
 use rustc_middle::ty::CurrentGcx;
 use rustc_parse::validate_attr;
-use rustc_session as session;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes};
+use rustc_session::config::{host_triple, Cfg, OutFileName, OutputFilenames, OutputTypes};
 use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
-use rustc_session::{filesearch, Session};
+use rustc_session::output::{categorize_crate_type, CRATE_TYPES};
+use rustc_session::{filesearch, EarlyDiagCtxt, Session};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::SourceMapInputs;
 use rustc_span::symbol::sym;
 use rustc_target::spec::Target;
-use session::output::{categorize_crate_type, CRATE_TYPES};
-use session::EarlyDiagCtxt;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -286,7 +284,7 @@
         "cannot load the default codegen backend twice"
     );
 
-    let target = session::config::host_triple();
+    let target = host_triple();
     let sysroot_candidates = sysroot_candidates();
 
     let sysroot = iter::once(sysroot)
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 4c34bf8..3ad6b68 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -273,6 +273,8 @@
     /// they are from an impl where-clause. This is necessary due to
     /// backwards compatability, cc trait-system-refactor-initiatitive#70.
     ImplWhereBound,
+    /// Instantiating a higher-ranked goal and re-proving it.
+    InstantiateHigherRanked,
 }
 
 /// Possible ways the given goal can be proven.
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 2d73be3..11aa0e1 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -127,6 +127,7 @@
                         let source = match source {
                             GoalSource::Misc => "misc",
                             GoalSource::ImplWhereBound => "impl where-bound",
+                            GoalSource::InstantiateHigherRanked => "higher-ranked goal",
                         };
                         writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")?
                     }
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index a545c17..8878310 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -695,9 +695,6 @@
 passes_undefined_naked_function_abi =
     Rust ABI is unsupported in naked functions
 
-passes_unix_sigpipe_values =
-    valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
-
 passes_unknown_external_lang_item =
     unknown external lang item: `{$lang_item}`
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index c403e91..e60aa27 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2523,7 +2523,6 @@
         sym::automatically_derived,
         sym::start,
         sym::rustc_main,
-        sym::unix_sigpipe,
         sym::derive,
         sym::test,
         sym::test_case,
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 438c583..d52092f 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -12,8 +12,7 @@
 use rustc_span::{Span, Symbol};
 
 use crate::errors::{
-    AttrOnlyInFunctions, AttrOnlyOnMain, AttrOnlyOnRootMain, ExternMain, MultipleRustcMain,
-    MultipleStartFunctions, NoMainErr, UnixSigpipeValues,
+    AttrOnlyInFunctions, ExternMain, MultipleRustcMain, MultipleStartFunctions, NoMainErr,
 };
 
 struct EntryContext<'tcx> {
@@ -67,11 +66,7 @@
         ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
     );
     match entry_point_type {
-        EntryPointType::None => {
-            if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
-                ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
-            }
-        }
+        EntryPointType::None => (),
         _ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
             for attr in [sym::start, sym::rustc_main] {
                 if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
@@ -81,9 +76,6 @@
         }
         EntryPointType::MainNamed => (),
         EntryPointType::OtherMain => {
-            if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
-                ctxt.tcx.dcx().emit_err(AttrOnlyOnRootMain { span, attr: sym::unix_sigpipe });
-            }
             ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
         }
         EntryPointType::RustcMainAttr => {
@@ -98,9 +90,6 @@
             }
         }
         EntryPointType::Start => {
-            if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
-                ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
-            }
             if ctxt.start_fn.is_none() {
                 ctxt.start_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
             } else {
@@ -120,7 +109,7 @@
         Some((def_id.to_def_id(), EntryFnType::Start))
     } else if let Some((local_def_id, _)) = visitor.attr_main_fn {
         let def_id = local_def_id.to_def_id();
-        Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }))
+        Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
     } else {
         if let Some(main_def) = tcx.resolutions(()).main_def
             && let Some(def_id) = main_def.opt_fn_def_id()
@@ -133,31 +122,19 @@
                 return None;
             }
 
-            return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }));
+            return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }));
         }
         no_main_err(tcx, visitor);
         None
     }
 }
 
-fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
-    if let Some(attr) = tcx.get_attr(def_id, sym::unix_sigpipe) {
-        match (attr.value_str(), attr.meta_item_list()) {
-            (Some(sym::inherit), None) => sigpipe::INHERIT,
-            (Some(sym::sig_ign), None) => sigpipe::SIG_IGN,
-            (Some(sym::sig_dfl), None) => sigpipe::SIG_DFL,
-            (Some(_), None) => {
-                tcx.dcx().emit_err(UnixSigpipeValues { span: attr.span });
-                sigpipe::DEFAULT
-            }
-            _ => {
-                // Keep going so that `fn emit_malformed_attribute()` can print
-                // an excellent error message
-                sigpipe::DEFAULT
-            }
-        }
-    } else {
-        sigpipe::DEFAULT
+fn sigpipe(tcx: TyCtxt<'_>) -> u8 {
+    match tcx.sess.opts.unstable_opts.on_broken_pipe {
+        rustc_target::spec::OnBrokenPipe::Default => sigpipe::DEFAULT,
+        rustc_target::spec::OnBrokenPipe::Kill => sigpipe::SIG_DFL,
+        rustc_target::spec::OnBrokenPipe::Error => sigpipe::SIG_IGN,
+        rustc_target::spec::OnBrokenPipe::Inherit => sigpipe::INHERIT,
     }
 }
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 03a6073..743faf5 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1259,13 +1259,6 @@
     pub span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_unix_sigpipe_values)]
-pub struct UnixSigpipeValues {
-    #[primary_span]
-    pub span: Span,
-}
-
 pub struct NoMainErr {
     pub sp: Span,
     pub crate_name: Symbol,
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index e7a3277..f998e0f 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -11,7 +11,6 @@
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
-rustc_hir_analysis = { path = "../rustc_hir_analysis" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 6ea87a4..4d845ab 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -19,7 +19,6 @@
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
-rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index ad66e5e..f2bdabb 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2909,7 +2909,9 @@
     use rustc_feature::UnstableFeatures;
     use rustc_span::edition::Edition;
     use rustc_span::RealFileName;
-    use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi};
+    use rustc_target::spec::{
+        CodeModel, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
+    };
     use rustc_target::spec::{
         RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
     };
@@ -2973,6 +2975,7 @@
         InstrumentXRay,
         CrateType,
         MergeFunctions,
+        OnBrokenPipe,
         PanicStrategy,
         RelroLevel,
         OptLevel,
diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs
index 1fadc75..1830ee0 100644
--- a/compiler/rustc_session/src/config/sigpipe.rs
+++ b/compiler/rustc_session/src/config/sigpipe.rs
@@ -1,6 +1,6 @@
 //! NOTE: Keep these constants in sync with `library/std/src/sys/pal/unix/mod.rs`!
 
-/// The default value if `#[unix_sigpipe]` is not specified. This resolves
+/// The default value if `-Zon-broken-pipe=...` is not specified. This resolves
 /// to `SIG_IGN` in `library/std/src/sys/pal/unix/mod.rs`.
 ///
 /// Note that `SIG_IGN` has been the Rust default since 2014. See
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 7355e5b..6566028 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -12,7 +12,7 @@
 use rustc_span::RealFileName;
 use rustc_span::SourceFileHashAlgorithm;
 use rustc_target::spec::{
-    CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi,
+    CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, SanitizerSet, WasmCAbi,
 };
 use rustc_target::spec::{
     RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
@@ -378,6 +378,7 @@
     pub const parse_time_passes_format: &str = "`text` (default) or `json`";
     pub const parse_passes: &str = "a space-separated list of passes, or `all`";
     pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
+    pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
     pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
     pub const parse_oom_strategy: &str = "either `panic` or `abort`";
     pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -708,6 +709,17 @@
         true
     }
 
+    pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
+        match v {
+            // OnBrokenPipe::Default can't be explicitly specified
+            Some("kill") => *slot = OnBrokenPipe::Kill,
+            Some("error") => *slot = OnBrokenPipe::Error,
+            Some("inherit") => *slot = OnBrokenPipe::Inherit,
+            _ => return false,
+        }
+        true
+    }
+
     pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
         match v {
             Some("panic") => *slot = OomStrategy::Panic,
@@ -1833,6 +1845,8 @@
         "do not use unique names for text and data sections when -Z function-sections is used"),
     normalize_docs: bool = (false, parse_bool, [TRACKED],
         "normalize associated items in rustdoc when generating documentation"),
+    on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED],
+        "behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"),
     oom: OomStrategy = (OomStrategy::Abort, parse_oom_strategy, [TRACKED],
         "panic strategy for out-of-memory handling"),
     osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7fe94c2..9c556f1 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1936,7 +1936,6 @@
         unit,
         universal_impl_trait,
         unix,
-        unix_sigpipe,
         unlikely,
         unmarked_api,
         unnamed_fields,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index bd347c1..cbb248a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -778,6 +778,14 @@
     Abort,
 }
 
+#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
+pub enum OnBrokenPipe {
+    Default,
+    Kill,
+    Error,
+    Inherit,
+}
+
 impl PanicStrategy {
     pub fn desc(&self) -> &str {
         match *self {
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 280975f..f2ca42a 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -58,15 +58,15 @@
     /// goal by equating it with the assumption.
     fn probe_and_consider_implied_clause(
         ecx: &mut EvalCtxt<'_, 'tcx>,
-        source: CandidateSource,
+        parent_source: CandidateSource,
         goal: Goal<'tcx, Self>,
         assumption: ty::Clause<'tcx>,
-        requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
+        requirements: impl IntoIterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>,
     ) -> Result<Candidate<'tcx>, NoSolution> {
-        Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
-            // FIXME(-Znext-solver=coinductive): check whether this should be
-            // `GoalSource::ImplWhereBound` for any caller.
-            ecx.add_goals(GoalSource::Misc, requirements);
+        Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| {
+            for (nested_source, goal) in requirements {
+                ecx.add_goal(nested_source, goal);
+            }
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -85,9 +85,8 @@
             let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
                 bug!("expected object type in `probe_and_consider_object_bound_candidate`");
             };
-            // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
             ecx.add_goals(
-                GoalSource::Misc,
+                GoalSource::ImplWhereBound,
                 structural_traits::predicates_for_object_candidate(
                     ecx,
                     goal.param_env,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 6722abd..d6bf2b5 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -90,6 +90,8 @@
         &mut self,
         certainty: Certainty,
     ) -> QueryResult<'tcx> {
+        self.inspect.make_canonical_response(certainty);
+
         let goals_certainty = self.try_evaluate_added_goals()?;
         assert_eq!(
             self.tainted,
@@ -98,8 +100,6 @@
             previous call to `try_evaluate_added_goals!`"
         );
 
-        self.inspect.make_canonical_response(certainty);
-
         // When normalizing, we've replaced the expected term with an unconstrained
         // inference variable. This means that we dropped information which could
         // have been important. We handle this by instead returning the nested goals
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 1710746..bae1c6b 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -454,7 +454,7 @@
         } else {
             self.infcx.enter_forall(kind, |kind| {
                 let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
-                self.add_goal(GoalSource::Misc, goal);
+                self.add_goal(GoalSource::InstantiateHigherRanked, goal);
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             })
         }
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 3fa409e..7962221 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -1,15 +1,19 @@
 use std::mem;
+use std::ops::ControlFlow;
 
 use rustc_infer::infer::InferCtxt;
-use rustc_infer::traits::solve::MaybeCause;
+use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::solve::inspect::ProbeKind;
+use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
 use rustc_infer::traits::{
-    query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
-    PredicateObligation, SelectionError, TraitEngine,
+    self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation,
+    ObligationCause, PredicateObligation, SelectionError, TraitEngine,
 };
-use rustc_middle::ty;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::{self, TyCtxt};
 
 use super::eval_ctxt::GenerateProofTree;
+use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
 use super::{Certainty, InferCtxtEvalExt};
 
 /// A trait engine using the new trait solver.
@@ -133,9 +137,9 @@
             .collect();
 
         errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError {
-            root_obligation: obligation.clone(),
+            obligation: find_best_leaf_obligation(infcx, &obligation),
             code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
-            obligation,
+            root_obligation: obligation,
         }));
 
         errors
@@ -192,8 +196,10 @@
 
 fn fulfillment_error_for_no_solution<'tcx>(
     infcx: &InferCtxt<'tcx>,
-    obligation: PredicateObligation<'tcx>,
+    root_obligation: PredicateObligation<'tcx>,
 ) -> FulfillmentError<'tcx> {
+    let obligation = find_best_leaf_obligation(infcx, &root_obligation);
+
     let code = match obligation.predicate.kind().skip_binder() {
         ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
             FulfillmentErrorCode::ProjectionError(
@@ -234,7 +240,8 @@
             bug!("unexpected goal: {obligation:?}")
         }
     };
-    FulfillmentError { root_obligation: obligation.clone(), code, obligation }
+
+    FulfillmentError { obligation, code, root_obligation }
 }
 
 fn fulfillment_error_for_stalled<'tcx>(
@@ -258,5 +265,136 @@
         }
     });
 
-    FulfillmentError { obligation: obligation.clone(), code, root_obligation: obligation }
+    FulfillmentError {
+        obligation: find_best_leaf_obligation(infcx, &obligation),
+        code,
+        root_obligation: obligation,
+    }
+}
+
+fn find_best_leaf_obligation<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    obligation: &PredicateObligation<'tcx>,
+) -> PredicateObligation<'tcx> {
+    let obligation = infcx.resolve_vars_if_possible(obligation.clone());
+    infcx
+        .visit_proof_tree(
+            obligation.clone().into(),
+            &mut BestObligation { obligation: obligation.clone() },
+        )
+        .break_value()
+        .unwrap_or(obligation)
+}
+
+struct BestObligation<'tcx> {
+    obligation: PredicateObligation<'tcx>,
+}
+
+impl<'tcx> BestObligation<'tcx> {
+    fn with_derived_obligation(
+        &mut self,
+        derived_obligation: PredicateObligation<'tcx>,
+        and_then: impl FnOnce(&mut Self) -> <Self as ProofTreeVisitor<'tcx>>::Result,
+    ) -> <Self as ProofTreeVisitor<'tcx>>::Result {
+        let old_obligation = std::mem::replace(&mut self.obligation, derived_obligation);
+        let res = and_then(self);
+        self.obligation = old_obligation;
+        res
+    }
+}
+
+impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
+    type Result = ControlFlow<PredicateObligation<'tcx>>;
+
+    fn span(&self) -> rustc_span::Span {
+        self.obligation.cause.span
+    }
+
+    fn visit_goal(&mut self, goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
+        // FIXME: Throw out candidates that have no failing WC and >0 failing misc goal.
+        // This most likely means that the goal just didn't unify at all, e.g. a param
+        // candidate with an alias in it.
+        let candidates = goal.candidates();
+
+        let [candidate] = candidates.as_slice() else {
+            return ControlFlow::Break(self.obligation.clone());
+        };
+
+        // FIXME: Could we extract a trait ref from a projection here too?
+        // FIXME: Also, what about considering >1 layer up the stack? May be necessary
+        // for normalizes-to.
+        let Some(parent_trait_pred) = goal.goal().predicate.to_opt_poly_trait_pred() else {
+            return ControlFlow::Break(self.obligation.clone());
+        };
+
+        let tcx = goal.infcx().tcx;
+        let mut impl_where_bound_count = 0;
+        for nested_goal in candidate.instantiate_nested_goals(self.span()) {
+            let obligation;
+            match nested_goal.source() {
+                GoalSource::Misc => {
+                    continue;
+                }
+                GoalSource::ImplWhereBound => {
+                    obligation = Obligation {
+                        cause: derive_cause(
+                            tcx,
+                            candidate.kind(),
+                            self.obligation.cause.clone(),
+                            impl_where_bound_count,
+                            parent_trait_pred,
+                        ),
+                        param_env: nested_goal.goal().param_env,
+                        predicate: nested_goal.goal().predicate,
+                        recursion_depth: self.obligation.recursion_depth + 1,
+                    };
+                    impl_where_bound_count += 1;
+                }
+                GoalSource::InstantiateHigherRanked => {
+                    obligation = self.obligation.clone();
+                }
+            }
+
+            // Skip nested goals that hold.
+            //FIXME: We should change the max allowed certainty based on if we're
+            // visiting an ambiguity or error obligation.
+            if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
+                continue;
+            }
+
+            self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
+        }
+
+        ControlFlow::Break(self.obligation.clone())
+    }
+}
+
+fn derive_cause<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    candidate_kind: ProbeKind<'tcx>,
+    mut cause: ObligationCause<'tcx>,
+    idx: usize,
+    parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+) -> ObligationCause<'tcx> {
+    match candidate_kind {
+        ProbeKind::TraitCandidate { source: CandidateSource::Impl(impl_def_id), result: _ } => {
+            if let Some((_, span)) =
+                tcx.predicates_of(impl_def_id).instantiate_identity(tcx).iter().nth(idx)
+            {
+                cause = cause.derived_cause(parent_trait_pred, |derived| {
+                    traits::ImplDerivedObligation(Box::new(traits::ImplDerivedObligationCause {
+                        derived,
+                        impl_or_alias_def_id: impl_def_id,
+                        impl_def_predicate_index: Some(idx),
+                        span,
+                    }))
+                })
+            }
+        }
+        ProbeKind::TraitCandidate { source: CandidateSource::BuiltinImpl(..), result: _ } => {
+            cause = cause.derived_cause(parent_trait_pred, traits::BuiltinDerivedObligation);
+        }
+        _ => {}
+    };
+    cause
 }
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 97de252..4f79f1b 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -41,6 +41,7 @@
     result: Result<Certainty, NoSolution>,
     evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>,
     normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
+    source: GoalSource,
 }
 
 /// The expected term of a `NormalizesTo` goal gets replaced
@@ -90,7 +91,7 @@
 pub struct InspectCandidate<'a, 'tcx> {
     goal: &'a InspectGoal<'a, 'tcx>,
     kind: inspect::ProbeKind<'tcx>,
-    nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
+    nested_goals: Vec<(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>)>,
     final_state: inspect::CanonicalState<'tcx, ()>,
     result: QueryResult<'tcx>,
     shallow_certainty: Certainty,
@@ -125,10 +126,8 @@
     /// back their inference constraints. This function modifies
     /// the state of the `infcx`.
     pub fn visit_nested_no_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
-        if self.goal.depth < visitor.config().max_depth {
-            for goal in self.instantiate_nested_goals(visitor.span()) {
-                try_visit!(visitor.visit_goal(&goal));
-            }
+        for goal in self.instantiate_nested_goals(visitor.span()) {
+            try_visit!(goal.visit_with(visitor));
         }
 
         V::Result::output()
@@ -143,13 +142,16 @@
         let instantiated_goals: Vec<_> = self
             .nested_goals
             .iter()
-            .map(|goal| {
-                canonical::instantiate_canonical_state(
-                    infcx,
-                    span,
-                    param_env,
-                    &mut orig_values,
-                    *goal,
+            .map(|(source, goal)| {
+                (
+                    *source,
+                    canonical::instantiate_canonical_state(
+                        infcx,
+                        span,
+                        param_env,
+                        &mut orig_values,
+                        *goal,
+                    ),
                 )
             })
             .collect();
@@ -171,7 +173,7 @@
 
         instantiated_goals
             .into_iter()
-            .map(|goal| match goal.predicate.kind().no_bound_vars() {
+            .map(|(source, goal)| match goal.predicate.kind().no_bound_vars() {
                 Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
                     let unconstrained_term = match term.unpack() {
                         ty::TermKind::Ty(_) => infcx
@@ -195,6 +197,7 @@
                         self.goal.depth + 1,
                         proof_tree.unwrap(),
                         Some(NormalizesToTermHack { term, unconstrained_term }),
+                        source,
                     )
                 }
                 _ => InspectGoal::new(
@@ -202,6 +205,7 @@
                     self.goal.depth + 1,
                     infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(),
                     None,
+                    source,
                 ),
             })
             .collect()
@@ -227,16 +231,23 @@
         self.result
     }
 
+    pub fn source(&self) -> GoalSource {
+        self.source
+    }
+
     fn candidates_recur(
         &'a self,
         candidates: &mut Vec<InspectCandidate<'a, 'tcx>>,
-        nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
+        nested_goals: &mut Vec<(
+            GoalSource,
+            inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>,
+        )>,
         probe: &inspect::Probe<'tcx>,
     ) {
         let mut shallow_certainty = None;
         for step in &probe.steps {
             match step {
-                &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
+                &inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
                 inspect::ProbeStep::NestedProbe(ref probe) => {
                     // Nested probes have to prove goals added in their parent
                     // but do not leak them, so we truncate the added goals
@@ -319,6 +330,7 @@
         depth: usize,
         root: inspect::GoalEvaluation<'tcx>,
         normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>,
+        source: GoalSource,
     ) -> Self {
         let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
         let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() };
@@ -341,8 +353,17 @@
             result,
             evaluation_kind: evaluation.kind,
             normalizes_to_term_hack,
+            source,
         }
     }
+
+    pub(crate) fn visit_with<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
+        if self.depth < visitor.config().max_depth {
+            try_visit!(visitor.visit_goal(self));
+        }
+
+        V::Result::output()
+    }
 }
 
 /// The public API to interact with proof trees.
@@ -367,6 +388,6 @@
     ) -> V::Result {
         let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
         let proof_tree = proof_tree.unwrap();
-        visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None))
+        visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None, GoalSource::Misc))
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index dab87ff..f886c58 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -389,7 +389,7 @@
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             pred,
-            [goal.with(tcx, output_is_sized_pred)],
+            [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
         )
     }
 
@@ -473,7 +473,8 @@
             pred,
             [goal.with(tcx, output_is_sized_pred)]
                 .into_iter()
-                .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
+                .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
+                .map(|goal| (GoalSource::ImplWhereBound, goal)),
         )
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index c8cb14a..d2b893d 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -321,7 +321,7 @@
             CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
             goal,
             pred,
-            [goal.with(tcx, output_is_sized_pred)],
+            [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
         )
     }
 
@@ -367,7 +367,8 @@
             pred,
             [goal.with(tcx, output_is_sized_pred)]
                 .into_iter()
-                .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
+                .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
+                .map(|goal| (GoalSource::ImplWhereBound, goal)),
         )
     }
 
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 5dcef63..dcf68b3 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -186,7 +186,6 @@
 #![feature(ptr_metadata)]
 #![feature(set_ptr_value)]
 #![feature(slice_ptr_get)]
-#![feature(split_at_checked)]
 #![feature(str_internals)]
 #![feature(str_split_inclusive_remainder)]
 #![feature(str_split_remainder)]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 9c523fd..de766a4 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -2051,8 +2051,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_at_checked)]
-    ///
     /// let v = [1, -2, 3, -4, 5, -6];
     ///
     /// {
@@ -2075,8 +2073,8 @@
     ///
     /// assert_eq!(None, v.split_at_checked(7));
     /// ```
-    #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
-    #[rustc_const_unstable(feature = "split_at_checked", issue = "119128")]
+    #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     #[must_use]
     pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
@@ -2102,8 +2100,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_at_checked)]
-    ///
     /// let mut v = [1, 0, 3, 0, 5, 6];
     ///
     /// if let Some((left, right)) = v.split_at_mut_checked(2) {
@@ -2116,8 +2112,8 @@
     ///
     /// assert_eq!(None, v.split_at_mut_checked(7));
     /// ```
-    #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
-    #[rustc_const_unstable(feature = "split_at_checked", issue = "119128")]
+    #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
     #[inline]
     #[must_use]
     pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index adccbe0..b6f6590 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -721,8 +721,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_at_checked)]
-    ///
     /// let s = "Per Martin-Löf";
     ///
     /// let (first, last) = s.split_at_checked(3).unwrap();
@@ -734,7 +732,7 @@
     /// ```
     #[inline]
     #[must_use]
-    #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
+    #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(mid) {
@@ -761,8 +759,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(split_at_checked)]
-    ///
     /// let mut s = "Per Martin-Löf".to_string();
     /// if let Some((first, last)) = s.split_at_mut_checked(3) {
     ///     first.make_ascii_uppercase();
@@ -776,7 +772,7 @@
     /// ```
     #[inline]
     #[must_use]
-    #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
+    #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(mid) {
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 59e118f..46f691d 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -74,7 +74,7 @@
 //
 // Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to
 // `SIG_IGN`. Applications have good reasons to want a different behavior
-// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that
+// though, so there is a `-Zon-broken-pipe` compiler flag that
 // can be used to select how `SIGPIPE` shall be setup (if changed at all) before
 // `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>
 // for more info.
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 01d7fb3..1ac5729 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -55,8 +55,8 @@
     // want!
     //
     // Hence, we set SIGPIPE to ignore when the program starts up in order
-    // to prevent this problem. Add `#[unix_sigpipe = "..."]` above `fn main()` to
-    // alter this behavior.
+    // to prevent this problem. Use `-Zon-broken-pipe=...` to alter this
+    // behavior.
     reset_sigpipe(sigpipe);
 
     stack_overflow::init();
@@ -190,7 +190,7 @@
                 _ => unreachable!(),
             };
             if sigpipe_attr_specified {
-                UNIX_SIGPIPE_ATTR_SPECIFIED.store(true, crate::sync::atomic::Ordering::Relaxed);
+                ON_BROKEN_PIPE_FLAG_USED.store(true, crate::sync::atomic::Ordering::Relaxed);
             }
             if let Some(handler) = handler {
                 rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
@@ -210,7 +210,7 @@
     target_os = "fuchsia",
     target_os = "horizon",
 )))]
-static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
+static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
     crate::sync::atomic::AtomicBool::new(false);
 
 #[cfg(not(any(
@@ -219,8 +219,8 @@
     target_os = "fuchsia",
     target_os = "horizon",
 )))]
-pub(crate) fn unix_sigpipe_attr_specified() -> bool {
-    UNIX_SIGPIPE_ATTR_SPECIFIED.load(crate::sync::atomic::Ordering::Relaxed)
+pub(crate) fn on_broken_pipe_flag_used() -> bool {
+    ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
 }
 
 // SAFETY: must be called only once during runtime cleanup.
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index f294716..e2fca8c 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -353,11 +353,11 @@
             // Inherit the signal mask from the parent rather than resetting it (i.e. do not call
             // pthread_sigmask).
 
-            // If #[unix_sigpipe] is specified, don't reset SIGPIPE to SIG_DFL.
-            // If #[unix_sigpipe] is not specified, reset SIGPIPE to SIG_DFL for backward compatibility.
+            // If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
+            // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
             //
-            // #[unix_sigpipe] is an opportunity to change the default here.
-            if !crate::sys::pal::unix_sigpipe_attr_specified() {
+            // -Zon-broken-pipe is an opportunity to change the default here.
+            if !crate::sys::pal::on_broken_pipe_flag_used() {
                 #[cfg(target_os = "android")] // see issue #88585
                 {
                     let mut action: libc::sigaction = mem::zeroed();
@@ -450,7 +450,7 @@
     ) -> io::Result<Option<Process>> {
         use crate::mem::MaybeUninit;
         use crate::sys::weak::weak;
-        use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified};
+        use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used};
 
         if self.get_gid().is_some()
             || self.get_uid().is_some()
@@ -612,11 +612,11 @@
             // Inherit the signal mask from this process rather than resetting it (i.e. do not call
             // posix_spawnattr_setsigmask).
 
-            // If #[unix_sigpipe] is specified, don't reset SIGPIPE to SIG_DFL.
-            // If #[unix_sigpipe] is not specified, reset SIGPIPE to SIG_DFL for backward compatibility.
+            // If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
+            // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
             //
-            // #[unix_sigpipe] is an opportunity to change the default here.
-            if !unix_sigpipe_attr_specified() {
+            // -Zon-broken-pipe is an opportunity to change the default here.
+            if !on_broken_pipe_flag_used() {
                 let mut default_set = MaybeUninit::<libc::sigset_t>::uninit();
                 cvt(sigemptyset(default_set.as_mut_ptr()))?;
                 cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?;
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index f3a26e2..7bd08a0 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -589,7 +589,9 @@
             // If the platform is single-threaded we're just going to run
             // the test synchronously, regardless of the concurrency
             // level.
-            let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
+            let supports_threads = !cfg!(target_os = "emscripten")
+                && !cfg!(target_family = "wasm")
+                && !cfg!(target_os = "zkvm");
             if supports_threads {
                 let cfg = thread::Builder::new().name(name.as_slice().to_owned());
                 let mut runtest = Arc::new(Mutex::new(Some(runtest)));
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 1d46a15..48a6602 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1006,6 +1006,13 @@
 
     cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)");
 
+    // If the rustc output is piped to e.g. `head -n1` we want the process to be
+    // killed, rather than having an error bubble up and cause a panic.
+    // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it.
+    if compiler.stage != 0 {
+        cargo.rustflag("-Zon-broken-pipe=kill");
+    }
+
     // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary
     // and may just be a time sink.
     if compiler.stage != 0 {
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 2e2c5e9..21344a4 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -471,7 +471,7 @@
             features.push("jemalloc".to_string());
         }
 
-        let cargo = prepare_tool_cargo(
+        let mut cargo = prepare_tool_cargo(
             builder,
             build_compiler,
             Mode::ToolRustc,
@@ -482,6 +482,14 @@
             features.as_slice(),
         );
 
+        // If the rustdoc output is piped to e.g. `head -n1` we want the process
+        // to be killed, rather than having an error bubble up and cause a
+        // panic.
+        // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it.
+        if build_compiler.stage > 0 {
+            cargo.rustflag("-Zon-broken-pipe=kill");
+        }
+
         let _guard = builder.msg_tool(
             Kind::Build,
             Mode::ToolRustc,
diff --git a/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md b/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md
new file mode 100644
index 0000000..bdc175f
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md
@@ -0,0 +1,84 @@
+# `on-broken-pipe`
+
+--------------------
+
+The tracking issue for this feature is: [#97889]
+
+Note: The ui for this feature was previously an attribute named `#[unix_sigpipe = "..."]`.
+
+[#97889]: https://github.com/rust-lang/rust/issues/97889
+
+---
+
+
+## Overview
+
+The `-Zon-broken-pipe=...` compiler flag can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This flag is ignored on non-Unix targets. The flag can be used with three different values or be omitted entirely. It affects `SIGPIPE` before `fn main()` and before children get `exec()`'ed:
+
+| Compiler flag              | `SIGPIPE` before `fn main()` | `SIGPIPE` before child `exec()` |
+|----------------------------|------------------------------|---------------------------------|
+| not used                   | `SIG_IGN`                    | `SIG_DFL`                       |
+| `-Zon-broken-pipe=kill`    | `SIG_DFL`                    | not touched                     |
+| `-Zon-broken-pipe=error`   | `SIG_IGN`                    | not touched                     |
+| `-Zon-broken-pipe=inherit` | not touched                  | not touched                     |
+
+
+## `-Zon-broken-pipe` not used
+
+If `-Zon-broken-pipe` is not used, libstd will behave in the manner it has since 2014, before Rust 1.0. `SIGPIPE` will be set to `SIG_IGN` before `fn main()` and result in `EPIPE` errors which are converted to `std::io::ErrorKind::BrokenPipe`.
+
+When spawning child processes, `SIGPIPE` will be set to `SIG_DFL` before doing the underlying `exec()` syscall.
+
+
+## `-Zon-broken-pipe=kill`
+
+Set the `SIGPIPE` handler to `SIG_DFL` before invoking `fn main()`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output.
+
+When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`.
+
+### Example
+
+```rust,no_run
+fn main() {
+    loop {
+        println!("hello world");
+    }
+}
+```
+
+```console
+$ rustc -Zon-broken-pipe=kill main.rs
+$ ./main | head -n1
+hello world
+```
+
+## `-Zon-broken-pipe=error`
+
+Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers.
+
+When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_IGN` for `SIGPIPE`.
+
+### Example
+
+```rust,no_run
+fn main() {
+    loop {
+        println!("hello world");
+    }
+}
+```
+
+```console
+$ rustc -Zon-broken-pipe=error main.rs
+$ ./main | head -n1
+hello world
+thread 'main' panicked at library/std/src/io/stdio.rs:1118:9:
+failed printing to stdout: Broken pipe (os error 32)
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+```
+
+## `-Zon-broken-pipe=inherit`
+
+Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `-Zon-broken-pipe=kill`.
+
+When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`.
diff --git a/src/doc/unstable-book/src/language-features/unix-sigpipe.md b/src/doc/unstable-book/src/language-features/unix-sigpipe.md
deleted file mode 100644
index 7ed6a7d..0000000
--- a/src/doc/unstable-book/src/language-features/unix-sigpipe.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# `unix_sigpipe`
-
-The tracking issue for this feature is: [#97889]
-
-[#97889]: https://github.com/rust-lang/rust/issues/97889
-
----
-
-The `#[unix_sigpipe = "..."]` attribute on `fn main()` can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This attribute is ignored on non-Unix targets. There are three variants:
-* `#[unix_sigpipe = "inherit"]`
-* `#[unix_sigpipe = "sig_dfl"]`
-* `#[unix_sigpipe = "sig_ign"]`
-
-## `#[unix_sigpipe = "inherit"]`
-
-Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `#[unix_sigpipe = "sig_dfl"]`.
-
-## `#[unix_sigpipe = "sig_dfl"]`
-
-Set the `SIGPIPE` handler to `SIG_DFL`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output.
-
-### Example
-
-```rust,no_run
-#![feature(unix_sigpipe)]
-#[unix_sigpipe = "sig_dfl"]
-fn main() { loop { println!("hello world"); } }
-```
-
-```bash
-% ./main | head -n 1
-hello world
-```
-
-## `#[unix_sigpipe = "sig_ign"]`
-
-Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers.
-
-This is what libstd has done by default since 2014. (However, see the note on child processes below.)
-
-### Example
-
-```rust,no_run
-#![feature(unix_sigpipe)]
-#[unix_sigpipe = "sig_ign"]
-fn main() { loop { println!("hello world"); } }
-```
-
-```bash
-% ./main | head -n 1
-hello world
-thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9
-note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-```
-
-### Note on child processes
-
-When spawning child processes, the legacy Rust behavior if `#[unix_sigpipe]` is not specified is to
-reset `SIGPIPE` to `SIG_DFL`.
-
-If `#[unix_sigpipe = "..."]` is specified, no matter what its value is, the signal disposition of
-`SIGPIPE` is no longer reset. This means that the child inherits the parent's `SIGPIPE` behavior.
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 2242768..97c5e9a 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -387,7 +387,7 @@
             let main_ptr = ecx.fn_ptr(FnVal::Instance(entry_instance));
 
             // Always using DEFAULT is okay since we don't support signals in Miri anyway.
-            // (This means we are effectively ignoring `#[unix_sigpipe]`.)
+            // (This means we are effectively ignoring `-Zon-broken-pipe`.)
             let sigpipe = rustc_session::config::sigpipe::DEFAULT;
 
             ecx.call_function(
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 239f90b..d040b05 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -261,6 +261,12 @@
                 }
                 output
             }
+
+            /// Set the path where the command will be run.
+            pub fn current_dir<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+                self.cmd.current_dir(path);
+                self
+            }
         }
     };
 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
index 55b9a1d..1fba2e2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs
@@ -207,7 +207,6 @@
     ),
 
     // Entry point:
-    gated!(unix_sigpipe, Normal, template!(Word, NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing, experimental!(unix_sigpipe)),
     ungated!(start, Normal, template!(Word), WarnFollowing),
     ungated!(no_start, CrateLevel, template!(Word), WarnFollowing),
     ungated!(no_main, CrateLevel, template!(Word), WarnFollowing),
diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs
index b81f46d..5b499a1 100644
--- a/src/tools/rustdoc/main.rs
+++ b/src/tools/rustdoc/main.rs
@@ -1,6 +1,3 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_dfl"]
 fn main() {
     rustdoc::main()
 }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 4b79b91..a56ea8d 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -44,7 +44,6 @@
 run-make/dep-info-doesnt-run-much/Makefile
 run-make/dep-info-spaces/Makefile
 run-make/dep-info/Makefile
-run-make/doctests-keep-binaries/Makefile
 run-make/doctests-runtool/Makefile
 run-make/dump-ice-to-disk/Makefile
 run-make/dump-mono-stats/Makefile
diff --git a/tests/run-make/doctests-keep-binaries/Makefile b/tests/run-make/doctests-keep-binaries/Makefile
deleted file mode 100644
index 2c64785..0000000
--- a/tests/run-make/doctests-keep-binaries/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Check that valid binaries are persisted by running them, regardless of whether the --run or --no-run option is used.
-
-MY_SRC_DIR := ${CURDIR}
-
-all: run no_run test_run_directory
-
-run:
-	mkdir -p $(TMPDIR)/doctests
-	$(RUSTC) --crate-type rlib t.rs
-	$(RUSTDOC) -Zunstable-options --test --persist-doctests $(TMPDIR)/doctests --extern t=$(TMPDIR)/libt.rlib t.rs
-	$(TMPDIR)/doctests/t_rs_2_0/rust_out
-	$(TMPDIR)/doctests/t_rs_8_0/rust_out
-	rm -rf $(TMPDIR)/doctests
-
-no_run:
-	mkdir -p $(TMPDIR)/doctests
-	$(RUSTC) --crate-type rlib t.rs
-	$(RUSTDOC) -Zunstable-options --test --persist-doctests $(TMPDIR)/doctests --extern t=$(TMPDIR)/libt.rlib t.rs --no-run
-	$(TMPDIR)/doctests/t_rs_2_0/rust_out
-	$(TMPDIR)/doctests/t_rs_8_0/rust_out
-	rm -rf $(TMPDIR)/doctests
-
-# Behavior with --test-run-directory with relative paths.
-test_run_directory:
-	mkdir -p $(TMPDIR)/doctests
-	mkdir -p $(TMPDIR)/rundir
-	$(RUSTC) --crate-type rlib t.rs
-	( cd $(TMPDIR); \
-		$(RUSTDOC) -Zunstable-options --test --persist-doctests doctests --test-run-directory rundir --extern t=libt.rlib $(MY_SRC_DIR)/t.rs )
-	rm -rf $(TMPDIR)/doctests $(TMPDIR)/rundir
diff --git a/tests/run-make/doctests-keep-binaries/rmake.rs b/tests/run-make/doctests-keep-binaries/rmake.rs
new file mode 100644
index 0000000..ad0c276
--- /dev/null
+++ b/tests/run-make/doctests-keep-binaries/rmake.rs
@@ -0,0 +1,68 @@
+// Check that valid binaries are persisted by running them, regardless of whether the
+// --run or --no-run option is used.
+
+use run_make_support::{run, rustc, rustdoc, tmp_dir};
+use std::fs::{create_dir, remove_dir_all};
+use std::path::Path;
+
+fn setup_test_env<F: FnOnce(&Path, &Path)>(callback: F) {
+    let out_dir = tmp_dir().join("doctests");
+    create_dir(&out_dir).expect("failed to create doctests folder");
+    rustc().input("t.rs").crate_type("rlib").run();
+    callback(&out_dir, &tmp_dir().join("libt.rlib"));
+    remove_dir_all(out_dir);
+}
+
+fn check_generated_binaries() {
+    run("doctests/t_rs_2_0/rust_out");
+    run("doctests/t_rs_8_0/rust_out");
+}
+
+fn main() {
+    setup_test_env(|out_dir, extern_path| {
+        rustdoc()
+            .input("t.rs")
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg(out_dir)
+            .arg("--extern")
+            .arg(format!("t={}", extern_path.display()))
+            .run();
+        check_generated_binaries();
+    });
+    setup_test_env(|out_dir, extern_path| {
+        rustdoc()
+            .input("t.rs")
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg(out_dir)
+            .arg("--extern")
+            .arg(format!("t={}", extern_path.display()))
+            .arg("--no-run")
+            .run();
+        check_generated_binaries();
+    });
+    // Behavior with --test-run-directory with relative paths.
+    setup_test_env(|_out_dir, extern_path| {
+        let run_dir = "rundir";
+        let run_dir_path = tmp_dir().join("rundir");
+        create_dir(&run_dir_path).expect("failed to create rundir folder");
+
+        rustdoc()
+            .current_dir(tmp_dir())
+            .input(std::env::current_dir().unwrap().join("t.rs"))
+            .arg("-Zunstable-options")
+            .arg("--test")
+            .arg("--persist-doctests")
+            .arg("doctests")
+            .arg("--test-run-directory")
+            .arg(run_dir)
+            .arg("--extern")
+            .arg("t=libt.rlib")
+            .run();
+
+        remove_dir_all(run_dir_path);
+    });
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs
deleted file mode 100644
index 9d1bd9f..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-//@ revisions: default sig_dfl sig_ign inherit
-//@ ignore-cross-compile because aux-bin does not yet support it
-//@ only-unix because SIGPIPE is a unix thing
-//@ run-pass
-//@ aux-bin:assert-sigpipe-disposition.rs
-//@ aux-crate:sigpipe_utils=sigpipe-utils.rs
-
-// Checks the signal disposition of `SIGPIPE` in child processes, and in our own
-// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is
-// the default. But there is a difference in how `SIGPIPE` is treated in child
-// processes with and without the attribute. Search for
-// `unix_sigpipe_attr_specified()` in the code base to learn more.
-
-#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))]
-
-extern crate sigpipe_utils;
-
-use sigpipe_utils::*;
-
-#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")]
-#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")]
-#[cfg_attr(inherit, unix_sigpipe = "inherit")]
-fn main() {
-    // By default we get SIG_IGN but the child gets SIG_DFL through an explicit
-    // reset before exec:
-    // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L363-L384
-    #[cfg(default)]
-    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_DFL");
-
-    // With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too
-    // without any special code running before exec.
-    #[cfg(sig_dfl)]
-    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
-
-    // With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too
-    // without any special code running before exec.
-    #[cfg(sig_ign)]
-    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_IGN");
-
-    // With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too
-    // without any special code running before exec.
-    #[cfg(inherit)]
-    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
-
-    assert_sigpipe_handler(we_expect);
-
-    assert!(
-        std::process::Command::new("./auxiliary/bin/assert-sigpipe-disposition")
-            .arg(child_expects)
-            .status()
-            .unwrap()
-            .success()
-    );
-}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs
deleted file mode 100644
index 5d95fc7..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe] //~ error: malformed `unix_sigpipe` attribute input
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr
deleted file mode 100644
index c1b4470..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: malformed `unix_sigpipe` attribute input
-  --> $DIR/unix_sigpipe-bare.rs:3:1
-   |
-LL | #[unix_sigpipe]
-   | ^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
deleted file mode 100644
index f5fa177..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![feature(unix_sigpipe)]
-#![unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute cannot be used at crate level
-
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
deleted file mode 100644
index fdfa301..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: `unix_sigpipe` attribute cannot be used at crate level
-  --> $DIR/unix_sigpipe-crate.rs:2:1
-   |
-LL | #![unix_sigpipe = "sig_dfl"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |
-LL | fn main() {}
-   |    ---- the inner attribute doesn't annotate this function
-   |
-help: perhaps you meant to use an outer attribute
-   |
-LL - #![unix_sigpipe = "sig_dfl"]
-LL + #[unix_sigpipe = "sig_dfl"]
-   |
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs
deleted file mode 100644
index 294cb38..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_ign"]
-#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr
deleted file mode 100644
index c2a3b9f..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: multiple `unix_sigpipe` attributes
-  --> $DIR/unix_sigpipe-different-duplicates.rs:4:1
-   |
-LL | #[unix_sigpipe = "inherit"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
-   |
-note: attribute also specified here
-  --> $DIR/unix_sigpipe-different-duplicates.rs:3:1
-   |
-LL | #[unix_sigpipe = "sig_ign"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
deleted file mode 100644
index eccb230..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "inherit"]
-#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
deleted file mode 100644
index c86e54a..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: multiple `unix_sigpipe` attributes
-  --> $DIR/unix_sigpipe-duplicates.rs:4:1
-   |
-LL | #[unix_sigpipe = "inherit"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
-   |
-note: attribute also specified here
-  --> $DIR/unix_sigpipe-duplicates.rs:3:1
-   |
-LL | #[unix_sigpipe = "inherit"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs
deleted file mode 100644
index 462ae24..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe(sig_dfl)] //~ error: malformed `unix_sigpipe` attribute input
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr
deleted file mode 100644
index a020f21..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: malformed `unix_sigpipe` attribute input
-  --> $DIR/unix_sigpipe-ident-list.rs:3:1
-   |
-LL | #[unix_sigpipe(sig_dfl)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
deleted file mode 100644
index 16731a4..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
-fn f() {}
-
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
deleted file mode 100644
index fcdd5db..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `unix_sigpipe` attribute can only be used on `fn main()`
-  --> $DIR/unix_sigpipe-non-main-fn.rs:3:1
-   |
-LL | #[unix_sigpipe = "sig_dfl"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
deleted file mode 100644
index a243525..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![feature(unix_sigpipe)]
-
-mod m {
-    #[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on root `fn main()`
-    fn main() {}
-}
-
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
deleted file mode 100644
index 98afb62..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `unix_sigpipe` attribute can only be used on root `fn main()`
-  --> $DIR/unix_sigpipe-non-root-main.rs:4:5
-   |
-LL |     #[unix_sigpipe = "sig_dfl"]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
deleted file mode 100644
index b0044f5..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ revisions: with_feature without_feature
-//@ run-pass
-//@ aux-build:sigpipe-utils.rs
-
-#![cfg_attr(with_feature, feature(unix_sigpipe))]
-
-fn main() {
-    extern crate sigpipe_utils;
-
-    // SIGPIPE shall be ignored since #[unix_sigpipe = "..."] is not used
-    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
-}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs
deleted file mode 100644
index ccd6c67..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ run-pass
-//@ aux-build:sigpipe-utils.rs
-
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_ign"]
-fn main() {
-    extern crate sigpipe_utils;
-
-    // #[unix_sigpipe = "sig_ign"] is active, so the legacy behavior of ignoring
-    // SIGPIPE shall be in effect
-    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
-}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
deleted file mode 100644
index 945b820..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(start)]
-#![feature(unix_sigpipe)]
-
-#[start]
-#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
-fn custom_start(argc: isize, argv: *const *const u8) -> isize { 0 }
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
deleted file mode 100644
index 3d56b36..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `unix_sigpipe` attribute can only be used on `fn main()`
-  --> $DIR/unix_sigpipe-start.rs:5:1
-   |
-LL | #[unix_sigpipe = "sig_dfl"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs
deleted file mode 100644
index 2232683..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe("sig_dfl")] //~ error: malformed `unix_sigpipe` attribute input
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr
deleted file mode 100644
index b62c086..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: malformed `unix_sigpipe` attribute input
-  --> $DIR/unix_sigpipe-str-list.rs:3:1
-   |
-LL | #[unix_sigpipe("sig_dfl")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
deleted file mode 100644
index 662779c..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()`
-struct S;
-
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
deleted file mode 100644
index a8fc51b..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: `unix_sigpipe` attribute can only be used on `fn main()`
-  --> $DIR/unix_sigpipe-struct.rs:3:1
-   |
-LL | #[unix_sigpipe = "sig_dfl"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
deleted file mode 100644
index 4ec25de..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "wrong"] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
-fn main() {}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
deleted file mode 100644
index d750443..0000000
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
-  --> $DIR/unix_sigpipe-wrong.rs:3:1
-   |
-LL | #[unix_sigpipe = "wrong"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr
index a5182eb..f6c5255 100644
--- a/tests/ui/coherence/occurs-check/opaques.next.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.next.stderr
@@ -11,7 +11,7 @@
   --> $DIR/opaques.rs:13:20
    |
 LL |     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
-   |                    ^ cannot infer type for struct `Container<T, T>`
+   |                    ^ cannot infer type for associated type `<T as Trait<T>>::Assoc`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs b/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs
deleted file mode 100644
index 46dc3f6..0000000
--- a/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![crate_type = "bin"]
-
-#[unix_sigpipe = "inherit"] //~ the `#[unix_sigpipe]` attribute is an experimental feature
-fn main () {}
diff --git a/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr b/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr
deleted file mode 100644
index 88c18e7..0000000
--- a/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: the `#[unix_sigpipe]` attribute is an experimental feature
-  --> $DIR/feature-gate-unix_sigpipe.rs:3:1
-   |
-LL | #[unix_sigpipe = "inherit"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #97889 <https://github.com/rust-lang/rust/issues/97889> for more information
-   = help: add `#![feature(unix_sigpipe)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr
index 0669999..6855e17 100644
--- a/tests/ui/for/issue-20605.next.stderr
+++ b/tests/ui/for/issue-20605.next.stderr
@@ -2,9 +2,14 @@
   --> $DIR/issue-20605.rs:6:17
    |
 LL |     for item in *things { *item = 0 }
-   |                 ^^^^^^^ `dyn Iterator<Item = &'a mut u8>` is not an iterator
+   |                 ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
    |
-   = help: the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
+   = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
+   = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
+help: consider mutably borrowing here
+   |
+LL |     for item in &mut *things { *item = 0 }
+   |                 ++++
 
 error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
   --> $DIR/issue-20605.rs:6:17
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr
index 8a8118d..5be683c 100644
--- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr
@@ -23,7 +23,20 @@
 LL |     impls_indirect_leak::<Box<_>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
    |
-   = note: cannot satisfy `for<'a> Box<_>: IndirectLeak<'a>`
+note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
+  --> $DIR/leak-check-in-selection-3.rs:9:1
+   |
+LL | impl Leak<'_> for Box<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Leak<'static> for Box<u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required for `Box<_>` to implement `for<'a> IndirectLeak<'a>`
+  --> $DIR/leak-check-in-selection-3.rs:23:23
+   |
+LL | impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {}
+   |             --------  ^^^^^^^^^^^^^^^^     ^
+   |             |
+   |             unsatisfied trait bound introduced here
 note: required by a bound in `impls_indirect_leak`
   --> $DIR/leak-check-in-selection-3.rs:25:27
    |
diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs
index 1df8c76..798db3c 100644
--- a/tests/ui/process/println-with-broken-pipe.rs
+++ b/tests/ui/process/println-with-broken-pipe.rs
@@ -6,16 +6,14 @@
 //@ ignore-horizon
 //@ ignore-android
 //@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+//@ compile-flags: -Zon-broken-pipe=error
 
 // Test what the error message looks like when `println!()` panics because of
 // `std::io::ErrorKind::BrokenPipe`
 
-#![feature(unix_sigpipe)]
-
 use std::env;
 use std::process::{Command, Stdio};
 
-#[unix_sigpipe = "sig_ign"]
 fn main() {
     let mut args = env::args();
     let me = args.next().unwrap();
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs
similarity index 72%
rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs
rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs
index 7f95fa7..b179e48 100644
--- a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs
+++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs
@@ -1,8 +1,6 @@
 //@ aux-crate: sigpipe_utils=sigpipe-utils.rs
+//@ compile-flags: -Zon-broken-pipe=inherit
 
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "inherit"]
 fn main() {
     sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
 }
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs
similarity index 71%
rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs
rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs
index d96e8b8..5ea4355 100644
--- a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs
+++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs
@@ -1,8 +1,6 @@
 //@ aux-crate: sigpipe_utils=sigpipe-utils.rs
+//@ compile-flags: -Zon-broken-pipe=inherit
 
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "inherit"]
 fn main() {
     sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
 }
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs
similarity index 100%
rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs
rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs
similarity index 100%
rename from tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
rename to tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs
diff --git a/tests/ui/runtime/on-broken-pipe/child-processes.rs b/tests/ui/runtime/on-broken-pipe/child-processes.rs
new file mode 100644
index 0000000..0da2347
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/child-processes.rs
@@ -0,0 +1,49 @@
+//@ revisions: default error kill inherit
+//@ ignore-cross-compile because aux-bin does not yet support it
+//@ only-unix because SIGPIPE is a unix thing
+//@ run-pass
+//@ aux-bin:assert-sigpipe-disposition.rs
+//@ aux-crate:sigpipe_utils=sigpipe-utils.rs
+//@ [kill] compile-flags: -Zunstable-options -Zon-broken-pipe=kill
+//@ [error] compile-flags: -Zunstable-options -Zon-broken-pipe=error
+//@ [inherit] compile-flags: -Zunstable-options -Zon-broken-pipe=inherit
+
+// Checks the signal disposition of `SIGPIPE` in child processes, and in our own
+// process for robustness.
+
+extern crate sigpipe_utils;
+
+use sigpipe_utils::*;
+
+fn main() {
+    // By default we get SIG_IGN but the child gets SIG_DFL through an explicit
+    // reset before exec:
+    // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L363-L384
+    #[cfg(default)]
+    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_DFL");
+
+    // We get SIG_DFL and the child does too without any special code running
+    // before exec.
+    #[cfg(kill)]
+    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
+
+    // We get SIG_IGN and the child does too without any special code running
+    // before exec.
+    #[cfg(error)]
+    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_IGN");
+
+    // We get SIG_DFL and the child does too without any special code running
+    // before exec.
+    #[cfg(inherit)]
+    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
+
+    assert_sigpipe_handler(we_expect);
+
+    assert!(
+        std::process::Command::new("./auxiliary/bin/assert-sigpipe-disposition")
+            .arg(child_expects)
+            .status()
+            .unwrap()
+            .success()
+    );
+}
diff --git a/tests/ui/runtime/on-broken-pipe/default.rs b/tests/ui/runtime/on-broken-pipe/default.rs
new file mode 100644
index 0000000..c10d1cf
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/default.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: -Zon-broken-pipe=default
+//@ check-fail
+
+fn main() {}
diff --git a/tests/ui/runtime/on-broken-pipe/default.stderr b/tests/ui/runtime/on-broken-pipe/default.stderr
new file mode 100644
index 0000000..b90d756
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/default.stderr
@@ -0,0 +1,2 @@
+error: incorrect value `default` for unstable option `on-broken-pipe` - either `kill`, `error`, or `inherit` was expected
+
diff --git a/tests/ui/runtime/on-broken-pipe/error.rs b/tests/ui/runtime/on-broken-pipe/error.rs
new file mode 100644
index 0000000..ab2036c
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/error.rs
@@ -0,0 +1,10 @@
+//@ run-pass
+//@ aux-build:sigpipe-utils.rs
+//@ compile-flags: -Zon-broken-pipe=error
+
+fn main() {
+    extern crate sigpipe_utils;
+
+    // `-Zon-broken-pipe=error` is active, so we expect SIGPIPE to be ignored.
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/runtime/on-broken-pipe/inherit.rs
similarity index 73%
rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
rename to tests/ui/runtime/on-broken-pipe/inherit.rs
index 3e63349..64909b7 100644
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
+++ b/tests/ui/runtime/on-broken-pipe/inherit.rs
@@ -3,20 +3,20 @@
 //@ aux-bin: assert-inherit-sig_dfl.rs
 //@ aux-bin: assert-inherit-sig_ign.rs
 //@ run-pass
+//@ compile-flags: -Zon-broken-pipe=kill
 
-#![feature(rustc_private, unix_sigpipe)]
+#![feature(rustc_private)]
 
 extern crate libc;
 
 // By default the Rust runtime resets SIGPIPE to SIG_DFL before exec'ing child
-// processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See
+// processes so opt-out of that with `-Zon-broken-pipe=kill`. See
 // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384
-#[unix_sigpipe = "sig_dfl"]
 fn main() {
-    // First expect SIG_DFL in a child process with #[unix_sigpipe = "inherit"].
+    // First expect SIG_DFL in a child process with -`Zon-broken-pipe=inherit`.
     assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_dfl");
 
-    // With SIG_IGN we expect #[unix_sigpipe = "inherit"] to also get SIG_IGN.
+    // With SIG_IGN we expect `-Zon-broken-pipe=inherit` to also get SIG_IGN.
     unsafe {
         libc::signal(libc::SIGPIPE, libc::SIG_IGN);
     }
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs b/tests/ui/runtime/on-broken-pipe/kill.rs
similarity index 60%
rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
rename to tests/ui/runtime/on-broken-pipe/kill.rs
index 30f2a9b..5dace6f 100644
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs
+++ b/tests/ui/runtime/on-broken-pipe/kill.rs
@@ -1,13 +1,11 @@
 //@ run-pass
 //@ aux-build:sigpipe-utils.rs
+//@ compile-flags: -Zon-broken-pipe=kill
 
-#![feature(unix_sigpipe)]
-
-#[unix_sigpipe = "sig_dfl"]
 fn main() {
     extern crate sigpipe_utils;
 
-    // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE shall NOT be ignored, instead
+    // `-Zon-broken-pipe=kill` is active, so SIGPIPE shall NOT be ignored, instead
     // the default handler shall be installed
     sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
 }
diff --git a/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs b/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs
new file mode 100644
index 0000000..2273291
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: -Zon-broken-pipe
+//@ check-fail
+
+fn main() {}
diff --git a/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr b/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr
new file mode 100644
index 0000000..3d3e12d
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr
@@ -0,0 +1,2 @@
+error: unstable option `on-broken-pipe` requires either `kill`, `error`, or `inherit` (Z on-broken-pipe=<value>)
+
diff --git a/tests/ui/runtime/on-broken-pipe/not-used.rs b/tests/ui/runtime/on-broken-pipe/not-used.rs
new file mode 100644
index 0000000..e31236f
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/not-used.rs
@@ -0,0 +1,9 @@
+//@ run-pass
+//@ aux-build:sigpipe-utils.rs
+
+fn main() {
+    extern crate sigpipe_utils;
+
+    // SIGPIPE shall be ignored since `-Zon-broken-pipe` is not used
+    sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs
similarity index 69%
rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
rename to tests/ui/runtime/on-broken-pipe/with-rustc_main.rs
index 02a3f48..c173120 100644
--- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs
+++ b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs
@@ -1,15 +1,14 @@
 //@ run-pass
 //@ aux-build:sigpipe-utils.rs
+//@ compile-flags: -Zon-broken-pipe=kill
 
-#![feature(unix_sigpipe)]
 #![feature(rustc_attrs)]
 
-#[unix_sigpipe = "sig_dfl"]
 #[rustc_main]
 fn rustc_main() {
     extern crate sigpipe_utils;
 
-    // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE handler shall be
+    // `-Zon-broken-pipe=kill` is active, so SIGPIPE handler shall be
     // SIG_DFL. Note that we have a #[rustc_main], but it should still work.
     sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
 }
diff --git a/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs
new file mode 100644
index 0000000..14d0ac5
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: -Zon-broken-pipe=wrong
+//@ check-fail
+
+fn main() {}
diff --git a/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr
new file mode 100644
index 0000000..3635418
--- /dev/null
+++ b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr
@@ -0,0 +1,2 @@
+error: incorrect value `wrong` for unstable option `on-broken-pipe` - either `kill`, `error`, or `inherit` was expected
+
diff --git a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr
index ac05dfb..562d7cc 100644
--- a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -1,18 +1,26 @@
-error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
+error: future cannot be sent between threads safely
   --> $DIR/auto-with-drop_tracking_mir.rs:25:13
    |
 LL |     is_send(foo());
-   |     ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
+   |             ^^^^^ future returned by `foo` is not `Send`
    |
-   = help: the trait `Send` is not implemented for `impl Future<Output = ()>`
+   = help: the trait `Sync` is not implemented for `impl Future<Output = ()>`, which is required by `impl Future<Output = ()>: Send`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/auto-with-drop_tracking_mir.rs:16:11
+   |
+LL |     let x = &NotSync;
+   |         - has type `&NotSync` which is not `Send`
+LL |     bar().await;
+   |           ^^^^^ await occurs here, with `x` maybe used later
 note: required by a bound in `is_send`
   --> $DIR/auto-with-drop_tracking_mir.rs:24:24
    |
 LL |     fn is_send(_: impl Send) {}
    |                        ^^^^ required by this bound in `is_send`
+help: consider dereferencing here
+   |
+LL |     is_send(*foo());
+   |             +
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs
index c82c179..1774116 100644
--- a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs
@@ -23,5 +23,5 @@
 fn main() {
     fn is_send(_: impl Send) {}
     is_send(foo());
-    //[fail]~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely
+    //[fail]~^ ERROR future cannot be sent between threads safely
 }
diff --git a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs
index ccb10ba..f8926b2 100644
--- a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs
+++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs
@@ -13,5 +13,5 @@
 
 fn main() {
     foo::<fn() -> str, _>(None, ());
-    //~^ expected a `Fn<_>` closure, found `fn() -> str`
+    //~^ the size for values of type `str` cannot be known at compilation time
 }
diff --git a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr
index 0804785..b487cee 100644
--- a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr
+++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr
@@ -1,10 +1,11 @@
-error[E0277]: expected a `Fn<_>` closure, found `fn() -> str`
+error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/builtin-fn-must-return-sized.rs:15:11
    |
 LL |     foo::<fn() -> str, _>(None, ());
-   |           ^^^^^^^^^^^ expected an `Fn<_>` closure, found `fn() -> str`
+   |           ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `Fn<_>` is not implemented for `fn() -> str`
+   = help: within `fn() -> str`, the trait `Sized` is not implemented for `str`, which is required by `fn() -> str: Fn<_>`
+   = note: required because it appears within the type `fn() -> str`
 note: required by a bound in `foo`
   --> $DIR/builtin-fn-must-return-sized.rs:10:11
    |
diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
index 57cba79..6e68646 100644
--- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr
@@ -1,12 +1,12 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
   --> $DIR/coherence-fulfill-overflow.rs:12:1
    |
 LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
    | ------------------------------------- first implementation here
 LL | impl<T: ?Sized + TwoW> Trait for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
    |
-   = note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
+   = note: overflow evaluating the requirement `W<W<W<W<_>>>>: TwoW`
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 8d7d8ce..df25150 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -1,9 +1,16 @@
-error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+error[E0275]: overflow evaluating the requirement `_: Sized`
   --> $DIR/fixpoint-exponential-growth.rs:33:13
    |
 LL |     impls::<W<_>>();
    |             ^^^^
    |
+note: required for `W<(W<_>, W<_>)>` to implement `Trait`
+  --> $DIR/fixpoint-exponential-growth.rs:23:12
+   |
+LL | impl<T, U> Trait for W<(W<T>, W<U>)>
+   |      -     ^^^^^     ^^^^^^^^^^^^^^^
+   |      |
+   |      unsatisfied trait bound introduced here
 note: required by a bound in `impls`
   --> $DIR/fixpoint-exponential-growth.rs:30:13
    |
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs
index 7eea81c..bc9bb6c 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs
+++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs
@@ -61,7 +61,7 @@
     // entering the cycle from `A` fails, but would work if we were to use the cache
     // result of `B<X>`.
     impls_trait::<A<X>, _, _, _>();
-    //~^ ERROR the trait bound `A<X>: Trait<_, _, _>` is not satisfied
+    //~^ ERROR the trait bound `X: IncompleteGuidance<_, _>` is not satisfied
 }
 
 fn main() {
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr
index d493219..78116eb 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr
@@ -1,10 +1,21 @@
-error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied
+error[E0277]: the trait bound `X: IncompleteGuidance<_, _>` is not satisfied
   --> $DIR/incompleteness-unstable-result.rs:63:19
    |
 LL |     impls_trait::<A<X>, _, _, _>();
-   |                   ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>`
+   |                   ^^^^ the trait `IncompleteGuidance<_, _>` is not implemented for `X`, which is required by `A<X>: Trait<_, _, _>`
    |
-   = help: the trait `Trait<U, V, D>` is implemented for `A<T>`
+   = help: the following other types implement trait `IncompleteGuidance<T, V>`:
+             <T as IncompleteGuidance<U, i16>>
+             <T as IncompleteGuidance<U, i8>>
+             <T as IncompleteGuidance<U, u8>>
+note: required for `A<X>` to implement `Trait<_, _, u8>`
+  --> $DIR/incompleteness-unstable-result.rs:32:50
+   |
+LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T>
+   |                                                  ^^^^^^^^^^^^^^     ^^^^
+LL | where
+LL |     T: IncompleteGuidance<U, V>,
+   |        ------------------------ unsatisfied trait bound introduced here
 note: required by a bound in `impls_trait`
   --> $DIR/incompleteness-unstable-result.rs:51:28
    |
diff --git a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
index 7cedb4d..86c71ad 100644
--- a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
+++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr
@@ -1,21 +1,53 @@
-error[E0275]: overflow evaluating the requirement `(): Trait`
+error[E0275]: overflow evaluating the requirement `(): Inductive`
   --> $DIR/double-cycle-inductive-coinductive.rs:32:19
    |
 LL |     impls_trait::<()>();
    |                   ^^
    |
+note: required for `()` to implement `Trait`
+  --> $DIR/double-cycle-inductive-coinductive.rs:9:34
+   |
+LL | impl<T: Inductive + Coinductive> Trait for T {}
+   |         ---------                ^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `()` to implement `Inductive`
+  --> $DIR/double-cycle-inductive-coinductive.rs:12:16
+   |
+LL | impl<T: Trait> Inductive for T {}
+   |         -----  ^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: 7 redundant requirements hidden
+   = note: required for `()` to implement `Trait`
 note: required by a bound in `impls_trait`
   --> $DIR/double-cycle-inductive-coinductive.rs:17:19
    |
 LL | fn impls_trait<T: Trait>() {}
    |                   ^^^^^ required by this bound in `impls_trait`
 
-error[E0275]: overflow evaluating the requirement `(): TraitRev`
+error[E0275]: overflow evaluating the requirement `(): CoinductiveRev`
   --> $DIR/double-cycle-inductive-coinductive.rs:35:23
    |
 LL |     impls_trait_rev::<()>();
    |                       ^^
    |
+note: required for `()` to implement `TraitRev`
+  --> $DIR/double-cycle-inductive-coinductive.rs:21:40
+   |
+LL | impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
+   |         --------------                 ^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `()` to implement `CoinductiveRev`
+  --> $DIR/double-cycle-inductive-coinductive.rs:27:19
+   |
+LL | impl<T: TraitRev> CoinductiveRev for T {}
+   |         --------  ^^^^^^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: 7 redundant requirements hidden
+   = note: required for `()` to implement `TraitRev`
 note: required by a bound in `impls_trait_rev`
   --> $DIR/double-cycle-inductive-coinductive.rs:29:23
    |
diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
index a2a5c02..ea46c0f 100644
--- a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr
@@ -1,9 +1,19 @@
-error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+error[E0275]: overflow evaluating the requirement `W<W<_>>: Trait`
   --> $DIR/inductive-fixpoint-hang.rs:31:19
    |
 LL |     impls_trait::<W<_>>();
    |                   ^^^^
    |
+note: required for `W<W<W<_>>>` to implement `Trait`
+  --> $DIR/inductive-fixpoint-hang.rs:22:17
+   |
+LL | impl<T: ?Sized> Trait for W<W<T>>
+   |                 ^^^^^     ^^^^^^^
+LL | where
+LL |     W<T>: Trait,
+   |           ----- unsatisfied trait bound introduced here
+   = note: 8 redundant requirements hidden
+   = note: required for `W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>` to implement `Trait`
 note: required by a bound in `impls_trait`
   --> $DIR/inductive-fixpoint-hang.rs:28:19
    |
diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs
index 7868337..9d0ea51 100644
--- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs
+++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs
@@ -39,7 +39,7 @@
 
 fn main() {
     impls_a::<()>();
-    //~^ ERROR overflow evaluating the requirement `(): A`
+    //~^ ERROR overflow evaluating the requirement `(): B`
 
     impls_ar::<()>();
     //~^ ERROR overflow evaluating the requirement `(): AR`
diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
index e9cc6bc..fe02d3c 100644
--- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
+++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr
@@ -1,9 +1,25 @@
-error[E0275]: overflow evaluating the requirement `(): A`
+error[E0275]: overflow evaluating the requirement `(): B`
   --> $DIR/inductive-not-on-stack.rs:41:15
    |
 LL |     impls_a::<()>();
    |               ^^
    |
+note: required for `()` to implement `A`
+  --> $DIR/inductive-not-on-stack.rs:21:16
+   |
+LL | impl<T: B + C> A for T {}
+   |         -      ^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `()` to implement `B`
+  --> $DIR/inductive-not-on-stack.rs:22:12
+   |
+LL | impl<T: A> B for T {}
+   |         -  ^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: 7 redundant requirements hidden
+   = note: required for `()` to implement `A`
 note: required by a bound in `impls_a`
   --> $DIR/inductive-not-on-stack.rs:25:15
    |
@@ -16,6 +32,29 @@
 LL |     impls_ar::<()>();
    |                ^^
    |
+note: required for `()` to implement `BR`
+  --> $DIR/inductive-not-on-stack.rs:35:13
+   |
+LL | impl<T: AR> BR for T {}
+   |         --  ^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `()` to implement `CR`
+  --> $DIR/inductive-not-on-stack.rs:36:13
+   |
+LL | impl<T: BR> CR for T {}
+   |         --  ^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required for `()` to implement `AR`
+  --> $DIR/inductive-not-on-stack.rs:34:18
+   |
+LL | impl<T: CR + BR> AR for T {}
+   |         --       ^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: 6 redundant requirements hidden
+   = note: required for `()` to implement `AR`
 note: required by a bound in `impls_ar`
   --> $DIR/inductive-not-on-stack.rs:38:16
    |
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs
index 6d75d24..b90a354 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs
@@ -35,5 +35,5 @@
 
 fn main() {
     impls_a::<()>();
-    //~^ ERROR overflow evaluating the requirement `(): A`
+    //~^ ERROR overflow evaluating the requirement `(): CInd`
 }
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
index 17544eb..03e61db 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr
@@ -1,9 +1,46 @@
-error[E0275]: overflow evaluating the requirement `(): A`
+error[E0275]: overflow evaluating the requirement `(): CInd`
   --> $DIR/mixed-cycles-1.rs:37:15
    |
 LL |     impls_a::<()>();
    |               ^^
    |
+note: required for `()` to implement `B`
+  --> $DIR/mixed-cycles-1.rs:31:28
+   |
+LL | impl<T: ?Sized + CInd + C> B for T {}
+   |                  ----      ^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+note: required for `()` to implement `C`
+  --> $DIR/mixed-cycles-1.rs:32:25
+   |
+LL | impl<T: ?Sized + B + A> C for T {}
+   |                  -      ^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+note: required for `()` to implement `CInd`
+  --> $DIR/mixed-cycles-1.rs:28:21
+   |
+LL | impl<T: ?Sized + C> CInd for T {}
+   |                  -  ^^^^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+   = note: 4 redundant requirements hidden
+   = note: required for `()` to implement `B`
+note: required for `()` to implement `BInd`
+  --> $DIR/mixed-cycles-1.rs:23:21
+   |
+LL | impl<T: ?Sized + B> BInd for T {}
+   |                  -  ^^^^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+note: required for `()` to implement `A`
+  --> $DIR/mixed-cycles-1.rs:30:28
+   |
+LL | impl<T: ?Sized + BInd + C> A for T {}
+   |                  ----      ^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
 note: required by a bound in `impls_a`
   --> $DIR/mixed-cycles-1.rs:34:15
    |
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs
index c939a6e..a3ffcaa 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs
@@ -28,5 +28,5 @@
 
 fn main() {
     impls_a::<()>();
-    //~^ ERROR overflow evaluating the requirement `(): A`
+    //~^ ERROR overflow evaluating the requirement `(): BInd`
 }
diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
index a9be101..892426a 100644
--- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
+++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr
@@ -1,9 +1,32 @@
-error[E0275]: overflow evaluating the requirement `(): A`
+error[E0275]: overflow evaluating the requirement `(): BInd`
   --> $DIR/mixed-cycles-2.rs:30:15
    |
 LL |     impls_a::<()>();
    |               ^^
    |
+note: required for `()` to implement `B`
+  --> $DIR/mixed-cycles-2.rs:25:24
+   |
+LL | impl<T: ?Sized + BInd> B for T {}
+   |                  ----  ^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+note: required for `()` to implement `BInd`
+  --> $DIR/mixed-cycles-2.rs:22:21
+   |
+LL | impl<T: ?Sized + B> BInd for T {}
+   |                  -  ^^^^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
+   = note: 6 redundant requirements hidden
+   = note: required for `()` to implement `BInd`
+note: required for `()` to implement `A`
+  --> $DIR/mixed-cycles-2.rs:24:28
+   |
+LL | impl<T: ?Sized + BInd + B> A for T {}
+   |                  ----      ^     ^
+   |                  |
+   |                  unsatisfied trait bound introduced here
 note: required by a bound in `impls_a`
   --> $DIR/mixed-cycles-2.rs:27:15
    |
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
index ce7a380..d11150c 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
+++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
@@ -25,7 +25,7 @@
     //
     //     https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
     require_bar::<T>();
-    //~^ ERROR the trait bound `T: Bar` is not satisfied
+    //~^ ERROR type mismatch resolving `<T as Foo>::Assoc == i32`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
index 2785357..3ef0afa 100644
--- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
+++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
@@ -1,19 +1,25 @@
-error[E0277]: the trait bound `T: Bar` is not satisfied
+error[E0271]: type mismatch resolving `<T as Foo>::Assoc == i32`
   --> $DIR/param-candidate-shadows-project.rs:27:19
    |
 LL |     require_bar::<T>();
-   |                   ^ the trait `Bar` is not implemented for `T`
+   |                   ^ type mismatch resolving `<T as Foo>::Assoc == i32`
    |
+note: types differ
+  --> $DIR/param-candidate-shadows-project.rs:10:18
+   |
+LL |     type Assoc = i32;
+   |                  ^^^
+note: required for `T` to implement `Bar`
+  --> $DIR/param-candidate-shadows-project.rs:13:9
+   |
+LL | impl<T> Bar for T where T: Foo<Assoc = i32> {}
+   |         ^^^     ^              ----------- unsatisfied trait bound introduced here
 note: required by a bound in `require_bar`
   --> $DIR/param-candidate-shadows-project.rs:15:19
    |
 LL | fn require_bar<T: Bar>() {}
    |                   ^^^ required by this bound in `require_bar`
-help: consider further restricting this bound
-   |
-LL | fn foo<T: Foo + Bar>() {
-   |               +++++
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/more-object-bound.rs b/tests/ui/traits/next-solver/more-object-bound.rs
index 511111a..3d3fdc9 100644
--- a/tests/ui/traits/next-solver/more-object-bound.rs
+++ b/tests/ui/traits/next-solver/more-object-bound.rs
@@ -10,7 +10,7 @@
 
 fn transmute<A, B>(x: A) -> B {
     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-    //~^ ERROR the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
+    //~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
 }
 
 fn foo<A, B, T: ?Sized>(x: T::A) -> B
diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr
index 1b776d7..8cc2a51 100644
--- a/tests/ui/traits/next-solver/more-object-bound.stderr
+++ b/tests/ui/traits/next-solver/more-object-bound.stderr
@@ -1,9 +1,10 @@
-error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
+error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
   --> $DIR/more-object-bound.rs:12:5
    |
 LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
    |
+   = note: required because it appears within the type `dyn Trait<A = A, B = B>`
 note: required by a bound in `foo`
   --> $DIR/more-object-bound.rs:18:8
    |
@@ -12,11 +13,7 @@
 LL | where
 LL |     T: Trait<B = B>,
    |        ^^^^^^^^^^^^ required by this bound in `foo`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn transmute<A, B>(x: A) -> B where dyn Trait<A = A, B = B>: Trait {
-   |                               ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs
index 40d68db..12ea1bf 100644
--- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs
+++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs
@@ -24,7 +24,7 @@
 
 fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
     needs_bar::<T>();
-    //~^ ERROR type annotations needed: cannot satisfy `T: Bar`
+    //~^ ERROR type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr
index dfff9f1..21f3fbf 100644
--- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr
+++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr
@@ -1,11 +1,14 @@
-error[E0283]: type annotations needed: cannot satisfy `T: Bar`
+error[E0284]: type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
   --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17
    |
 LL |     needs_bar::<T>();
-   |                 ^
+   |                 ^ cannot satisfy `<T as Foo>::Assoc == i32`
    |
-   = note: cannot satisfy `T: Bar`
-   = help: the trait `Bar` is implemented for `T`
+note: required for `T` to implement `Bar`
+  --> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9
+   |
+LL | impl<T> Bar for T where T: Foo<Assoc = i32> {}
+   |         ^^^     ^              ----------- unsatisfied trait bound introduced here
 note: required by a bound in `needs_bar`
   --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
    |
@@ -14,4 +17,4 @@
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0283`.
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs
index 4222607..3aa1af4 100644
--- a/tests/ui/traits/next-solver/object-unsafety.rs
+++ b/tests/ui/traits/next-solver/object-unsafety.rs
@@ -11,9 +11,9 @@
 pub fn copy_any<T>(t: &T) -> T {
     copy::<dyn Setup<From=T>>(t)
     //~^ ERROR the type `&<dyn Setup<From = T> as Setup>::From` is not well-formed
-    //~| ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
     //~| ERROR mismatched types
     //~| ERROR the type `<dyn Setup<From = T> as Setup>::From` is not well-formed
+    //~| ERROR the trait bound `T: Copy` is not satisfied
 
     // FIXME(-Znext-solver): These error messages are horrible and some of them
     // are even simple fallout from previous error.
diff --git a/tests/ui/traits/next-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr
index a9cbb72..7c9a607 100644
--- a/tests/ui/traits/next-solver/object-unsafety.stderr
+++ b/tests/ui/traits/next-solver/object-unsafety.stderr
@@ -1,18 +1,19 @@
-error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied
+error[E0277]: the trait bound `T: Copy` is not satisfied in `dyn Setup<From = T>`
   --> $DIR/object-unsafety.rs:12:12
    |
 LL |     copy::<dyn Setup<From=T>>(t)
-   |            ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>`
+   |            ^^^^^^^^^^^^^^^^^ within `dyn Setup<From = T>`, the trait `Copy` is not implemented for `T`, which is required by `dyn Setup<From = T>: Setup`
    |
+   = note: required because it appears within the type `dyn Setup<From = T>`
 note: required by a bound in `copy`
   --> $DIR/object-unsafety.rs:7:12
    |
 LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
    |            ^^^^^ required by this bound in `copy`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+help: consider restricting type parameter `T`
    |
-LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup {
-   |                                ++++++++++++++++++++++++++++++++
+LL | pub fn copy_any<T: std::marker::Copy>(t: &T) -> T {
+   |                  +++++++++++++++++++
 
 error: the type `&<dyn Setup<From = T> as Setup>::From` is not well-formed
   --> $DIR/object-unsafety.rs:12:31
diff --git a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs
index 186d0e8..052d803 100644
--- a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs
+++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs
@@ -15,5 +15,5 @@
 
 fn main() {
     impls::<W<_>>();
-    //~^ ERROR overflow evaluating the requirement `W<_>: Trait`
+    //~^ ERROR overflow evaluating the requirement `_: Sized`
 }
diff --git a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
index b032ae3..6583cae 100644
--- a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
+++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr
@@ -1,9 +1,16 @@
-error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+error[E0275]: overflow evaluating the requirement `_: Sized`
   --> $DIR/exponential-trait-goals.rs:17:13
    |
 LL |     impls::<W<_>>();
    |             ^^^^
    |
+note: required for `W<(W<_>, W<_>)>` to implement `Trait`
+  --> $DIR/exponential-trait-goals.rs:7:12
+   |
+LL | impl<T, U> Trait for W<(W<T>, W<U>)>
+   |      -     ^^^^^     ^^^^^^^^^^^^^^^
+   |      |
+   |      unsatisfied trait bound introduced here
 note: required by a bound in `impls`
   --> $DIR/exponential-trait-goals.rs:14:13
    |
diff --git a/tests/ui/traits/next-solver/overflow/global-cache.stderr b/tests/ui/traits/next-solver/overflow/global-cache.stderr
index 6761661..9e46772 100644
--- a/tests/ui/traits/next-solver/overflow/global-cache.stderr
+++ b/tests/ui/traits/next-solver/overflow/global-cache.stderr
@@ -5,6 +5,15 @@
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
+note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>` to implement `Trait`
+  --> $DIR/global-cache.rs:12:16
+   |
+LL | impl<T: Trait> Trait for Inc<T> {}
+   |         -----  ^^^^^     ^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+   = note: 5 redundant requirements hidden
+   = note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>>>>>>` to implement `Trait`
 note: required by a bound in `impls_trait`
   --> $DIR/global-cache.rs:15:19
    |