about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs3
-rw-r--r--compiler/rustc_attr_data_structures/src/encode_cross_crate.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/traits.rs7
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs5
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl6
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_select.rs16
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs68
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs2
-rw-r--r--compiler/rustc_parse/src/parser/cfg_select.rs10
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs59
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs1
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_type_ir/src/walk.rs12
-rw-r--r--library/core/src/macros/mod.rs16
-rw-r--r--library/core/src/str/mod.rs1
-rw-r--r--library/std/Cargo.toml3
-rw-r--r--library/std/src/sys/backtrace.rs100
-rw-r--r--library/sysroot/Cargo.toml1
-rw-r--r--src/bootstrap/src/core/build_steps/mod.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/suggest.rs68
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs9
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs1
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs2
-rw-r--r--src/bootstrap/src/core/builder/mod.rs6
-rw-r--r--src/bootstrap/src/core/config/config.rs2
-rw-r--r--src/bootstrap/src/core/config/flags.rs8
-rw-r--r--src/bootstrap/src/core/sanity.rs1
-rw-r--r--src/bootstrap/src/lib.rs11
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs14
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/metrics.rs2
m---------src/doc/book0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md1
-rw-r--r--src/doc/rustc-dev-guide/src/building/quickstart.md3
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md17
-rw-r--r--src/doc/rustc-dev-guide/src/tests/suggest-tests.md59
-rw-r--r--src/etc/completions/x.fish37
-rw-r--r--src/etc/completions/x.ps144
-rw-r--r--src/etc/completions/x.py.fish37
-rw-r--r--src/etc/completions/x.py.ps144
-rw-r--r--src/etc/completions/x.py.sh191
-rw-r--r--src/etc/completions/x.py.zsh51
-rw-r--r--src/etc/completions/x.sh191
-rw-r--r--src/etc/completions/x.zsh51
-rw-r--r--src/tools/compiletest/src/directives.rs1
-rw-r--r--src/tools/run-make-support/src/symbols.rs184
-rw-r--r--src/tools/suggest-tests/Cargo.toml8
-rw-r--r--src/tools/suggest-tests/src/dynamic_suggestions.rs32
-rw-r--r--src/tools/suggest-tests/src/lib.rs96
-rw-r--r--src/tools/suggest-tests/src/main.rs40
-rw-r--r--src/tools/suggest-tests/src/static_suggestions.rs40
-rw-r--r--src/tools/suggest-tests/src/tests.rs21
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs92
-rw-r--r--tests/run-make/compiletest-self-test/symbols-helpers/sample.rs13
-rw-r--r--tests/run-make/fmt-write-bloat/rmake.rs4
-rw-r--r--tests/run-make/used/rmake.rs4
-rw-r--r--tests/ui/codegen/duplicated-path-in-error.gnu.stderr (renamed from tests/ui/codegen/duplicated-path-in-error.stderr)0
-rw-r--r--tests/ui/codegen/duplicated-path-in-error.musl.stderr2
-rw-r--r--tests/ui/codegen/duplicated-path-in-error.rs7
-rw-r--r--tests/ui/consts/const_transmute_type_id3.rs5
-rw-r--r--tests/ui/consts/const_transmute_type_id3.stderr4
-rw-r--r--tests/ui/consts/const_transmute_type_id5.rs21
-rw-r--r--tests/ui/consts/const_transmute_type_id5.stderr15
-rw-r--r--tests/ui/issues/issue-50571.fixed10
-rw-r--r--tests/ui/issues/issue-50571.rs10
-rw-r--r--tests/ui/issues/issue-50571.stderr15
-rw-r--r--tests/ui/macros/cfg_select.rs7
-rw-r--r--tests/ui/macros/cfg_select.stderr14
-rw-r--r--tests/ui/parser/better-expected.rs2
-rw-r--r--tests/ui/parser/better-expected.stderr12
-rw-r--r--tests/ui/parser/issues/error-pattern-issue-50571.rs11
-rw-r--r--tests/ui/parser/issues/error-pattern-issue-50571.stderr28
-rw-r--r--tests/ui/parser/recover/array-type-no-semi.rs17
-rw-r--r--tests/ui/parser/recover/array-type-no-semi.stderr71
-rw-r--r--tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs7
-rw-r--r--tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr21
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs2
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr26
-rw-r--r--triagebot.toml1
87 files changed, 747 insertions, 1277 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 51fd06972f2..b8a8d7b7d23 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5070,14 +5070,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "suggest-tests"
-version = "0.1.0"
-dependencies = [
- "build_helper",
- "glob",
-]
-
-[[package]]
 name = "syn"
 version = "1.0.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 6d3425f4115..67c7a9d67ed 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,7 +39,6 @@ members = [
   "src/tools/rustdoc-gui-test",
   "src/tools/rustdoc-themes",
   "src/tools/rustfmt",
-  "src/tools/suggest-tests",
   "src/tools/test-float-parse",
   "src/tools/tidy",
   "src/tools/tier-check",
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index 995ac514d8d..3dedeb1b372 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -374,6 +374,9 @@ pub enum AttributeKind {
     /// Represents `#[path]`
     Path(Symbol, Span),
 
+    /// Represents `#[pointee]`
+    Pointee(Span),
+
     /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint).
     PubTransparent(Span),
 
diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
index 494b570c86c..3e2dc0a15b2 100644
--- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
+++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
@@ -57,6 +57,7 @@ impl AttributeKind {
             ParenSugar(..) => No,
             PassByValue(..) => Yes,
             Path(..) => No,
+            Pointee(..) => No,
             PubTransparent(..) => Yes,
             Repr { .. } => No,
             RustcLayoutScalarValidRangeEnd(..) => Yes,
diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs
index ee8a33ae9c4..d5e088effd5 100644
--- a/compiler/rustc_attr_parsing/src/attributes/traits.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs
@@ -145,3 +145,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for FundamentalParser {
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
 }
+
+pub(crate) struct PointeeParser;
+impl<S: Stage> NoArgsAttributeParser<S> for PointeeParser {
+    const PATH: &[Symbol] = &[sym::pointee];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::Pointee;
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 1f6675b4c5a..567341d1517 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -47,8 +47,8 @@ use crate::attributes::test_attrs::IgnoreParser;
 use crate::attributes::traits::{
     AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser,
     DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser,
-    ParenSugarParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser,
-    UnsafeSpecializationMarkerParser,
+    ParenSugarParser, PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser,
+    TypeConstParser, UnsafeSpecializationMarkerParser,
 };
 use crate::attributes::transparency::TransparencyParser;
 use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
@@ -177,6 +177,7 @@ attribute_parsers!(
         Single<WithoutArgs<OmitGdbPrettyPrinterSectionParser>>,
         Single<WithoutArgs<ParenSugarParser>>,
         Single<WithoutArgs<PassByValueParser>>,
+        Single<WithoutArgs<PointeeParser>>,
         Single<WithoutArgs<PubTransparentParser>>,
         Single<WithoutArgs<SpecializationTraitParser>>,
         Single<WithoutArgs<StdInternalSymbolParser>>,
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 183927edb02..ae186d744c4 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -81,11 +81,11 @@ builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a l
 builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
 builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified
 
-builtin_macros_cfg_select_no_matches = none of the rules in this `cfg_select` evaluated to true
+builtin_macros_cfg_select_no_matches = none of the predicates in this `cfg_select` evaluated to true
 
-builtin_macros_cfg_select_unreachable = unreachable rule
+builtin_macros_cfg_select_unreachable = unreachable predicate
     .label = always matches
-    .label2 = this rules is never reached
+    .label2 = this predicate is never reached
 
 builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized`
 
diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs
index 2dc387d5866..f22d5f255c2 100644
--- a/compiler/rustc_builtin_macros/src/cfg_select.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_select.rs
@@ -1,12 +1,12 @@
 use rustc_ast::tokenstream::TokenStream;
 use rustc_attr_parsing as attr;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
-use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectRule, parse_cfg_select};
+use rustc_parse::parser::cfg_select::{CfgSelectBranches, CfgSelectPredicate, parse_cfg_select};
 use rustc_span::{Ident, Span, sym};
 
 use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
 
-/// Selects the first arm whose rule evaluates to true.
+/// Selects the first arm whose predicate evaluates to true.
 fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
     for (cfg, tt, arm_span) in branches.reachable {
         if attr::cfg_matches(
@@ -30,11 +30,11 @@ pub(super) fn expand_cfg_select<'cx>(
     ExpandResult::Ready(match parse_cfg_select(&mut ecx.new_parser_from_tts(tts)) {
         Ok(branches) => {
             if let Some((underscore, _, _)) = branches.wildcard {
-                // Warn for every unreachable rule. We store the fully parsed branch for rustfmt.
-                for (rule, _, _) in &branches.unreachable {
-                    let span = match rule {
-                        CfgSelectRule::Wildcard(underscore) => underscore.span,
-                        CfgSelectRule::Cfg(cfg) => cfg.span(),
+                // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt.
+                for (predicate, _, _) in &branches.unreachable {
+                    let span = match predicate {
+                        CfgSelectPredicate::Wildcard(underscore) => underscore.span,
+                        CfgSelectPredicate::Cfg(cfg) => cfg.span(),
                     };
                     let err = CfgSelectUnreachable { span, wildcard_span: underscore.span };
                     ecx.dcx().emit_warn(err);
@@ -50,7 +50,7 @@ pub(super) fn expand_cfg_select<'cx>(
                     Ident::with_dummy_span(sym::cfg_select),
                 );
             } else {
-                // Emit a compiler error when none of the rules matched.
+                // Emit a compiler error when none of the predicates matched.
                 let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp });
                 DummyResult::any(sp, guar)
             }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 1eba1f2f03c..22d29eda913 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -44,17 +44,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         )?;
         self.copy_op_allow_transmute(&op, dest)?;
 
-        // Give the first pointer-size bytes provenance that knows about the type id.
+        // Give the each pointer-sized chunk provenance that knows about the type id.
         // Here we rely on `TypeId` being a newtype around an array of pointers, so we
-        // first project to its only field and then the first array element.
+        // first project to its only field and then the array elements.
         let alloc_id = tcx.reserve_and_set_type_id_alloc(ty);
         let first = self.project_field(dest, FieldIdx::ZERO)?;
-        let first = self.project_index(&first, 0)?;
-        let offset = self.read_scalar(&first)?.to_target_usize(&tcx)?;
-        let ptr = Pointer::new(alloc_id.into(), Size::from_bytes(offset));
-        let ptr = self.global_root_pointer(ptr)?;
-        let val = Scalar::from_pointer(ptr, &tcx);
-        self.write_scalar(val, &first)
+        let mut elem_iter = self.project_array_fields(&first)?;
+        while let Some((_, elem)) = elem_iter.next(self)? {
+            // Decorate this part of the hash with provenance; leave the integer part unchanged.
+            let hash_fragment = self.read_scalar(&elem)?.to_target_usize(&tcx)?;
+            let ptr = Pointer::new(alloc_id.into(), Size::from_bytes(hash_fragment));
+            let ptr = self.global_root_pointer(ptr)?;
+            let val = Scalar::from_pointer(ptr, &tcx);
+            self.write_scalar(val, &elem)?;
+        }
+        interp_ok(())
     }
 
     /// Returns `true` if emulation happened.
@@ -101,34 +105,36 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let mut a_fields = self.project_array_fields(&a_fields)?;
                 let mut b_fields = self.project_array_fields(&b_fields)?;
 
-                let (_idx, a) = a_fields
-                    .next(self)?
-                    .expect("we know the layout of TypeId has at least 2 array elements");
-                let a = self.deref_pointer(&a)?;
-                let (a, offset_a) = self.get_ptr_type_id(a.ptr())?;
-
-                let (_idx, b) = b_fields
-                    .next(self)?
-                    .expect("we know the layout of TypeId has at least 2 array elements");
-                let b = self.deref_pointer(&b)?;
-                let (b, offset_b) = self.get_ptr_type_id(b.ptr())?;
+                let mut provenance_a = None;
+                let mut provenance_b = None;
+                let mut provenance_matches = true;
 
-                let provenance_matches = a == b;
+                while let Some((i, a)) = a_fields.next(self)? {
+                    let (_, b) = b_fields.next(self)?.unwrap();
 
-                let mut eq_id = offset_a == offset_b;
+                    let a = self.deref_pointer(&a)?;
+                    let (a, offset_a) = self.get_ptr_type_id(a.ptr())?;
 
-                while let Some((_, a)) = a_fields.next(self)? {
-                    let (_, b) = b_fields.next(self)?.unwrap();
+                    let b = self.deref_pointer(&b)?;
+                    let (b, offset_b) = self.get_ptr_type_id(b.ptr())?;
 
-                    let a = self.read_target_usize(&a)?;
-                    let b = self.read_target_usize(&b)?;
-                    eq_id &= a == b;
-                }
+                    if *provenance_a.get_or_insert(a) != a {
+                        throw_ub_format!(
+                            "type_id_eq: the first TypeId argument is invalid, the provenance of chunk {i} does not match the first chunk's"
+                        )
+                    }
+                    if *provenance_b.get_or_insert(b) != b {
+                        throw_ub_format!(
+                            "type_id_eq: the second TypeId argument is invalid, the provenance of chunk {i} does not match the first chunk's"
+                        )
+                    }
+                    provenance_matches &= a == b;
 
-                if !eq_id && provenance_matches {
-                    throw_ub_format!(
-                        "type_id_eq: one of the TypeId arguments is invalid, the hash does not match the type it represents"
-                    )
+                    if offset_a != offset_b && provenance_matches {
+                        throw_ub_format!(
+                            "type_id_eq: one of the TypeId arguments is invalid, chunk {i} of the hash does not match the type it represents"
+                        )
+                    }
                 }
 
                 self.write_scalar(Scalar::from_bool(provenance_matches), dest)?;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index cb106962be1..364ad38556b 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -49,7 +49,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             } = self.lower_poly_trait_ref(
                 &trait_bound.trait_ref,
                 trait_bound.span,
-                hir::BoundConstness::Never,
+                trait_bound.modifiers.constness,
                 hir::BoundPolarity::Positive,
                 dummy_self,
                 &mut user_written_bounds,
diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs
index 24a05afff4a..2c6fb224d70 100644
--- a/compiler/rustc_parse/src/parser/cfg_select.rs
+++ b/compiler/rustc_parse/src/parser/cfg_select.rs
@@ -7,7 +7,7 @@ use rustc_span::Span;
 use crate::exp;
 use crate::parser::Parser;
 
-pub enum CfgSelectRule {
+pub enum CfgSelectPredicate {
     Cfg(MetaItemInner),
     Wildcard(Token),
 }
@@ -20,7 +20,7 @@ pub struct CfgSelectBranches {
     pub wildcard: Option<(Token, TokenStream, Span)>,
     /// All branches after the first wildcard, including further wildcards.
     /// These branches are kept for formatting.
-    pub unreachable: Vec<(CfgSelectRule, TokenStream, Span)>,
+    pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>,
 }
 
 /// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where
@@ -52,7 +52,7 @@ pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches
             match branches.wildcard {
                 None => branches.wildcard = Some((underscore, tts, span)),
                 Some(_) => {
-                    branches.unreachable.push((CfgSelectRule::Wildcard(underscore), tts, span))
+                    branches.unreachable.push((CfgSelectPredicate::Wildcard(underscore), tts, span))
                 }
             }
         } else {
@@ -64,7 +64,9 @@ pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches
 
             match branches.wildcard {
                 None => branches.reachable.push((meta_item, tts, span)),
-                Some(_) => branches.unreachable.push((CfgSelectRule::Cfg(meta_item), tts, span)),
+                Some(_) => {
+                    branches.unreachable.push((CfgSelectPredicate::Cfg(meta_item), tts, span))
+                }
             }
         }
     }
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index a997be3405d..740dd10ea8b 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -575,14 +575,69 @@ impl<'a> Parser<'a> {
                 self.expect(exp!(CloseBracket))?;
             }
             TyKind::Array(elt_ty, length)
-        } else {
-            self.expect(exp!(CloseBracket))?;
+        } else if self.eat(exp!(CloseBracket)) {
             TyKind::Slice(elt_ty)
+        } else {
+            self.maybe_recover_array_ty_without_semi(elt_ty)?
         };
 
         Ok(ty)
     }
 
+    /// Recover from malformed array type syntax.
+    ///
+    /// This method attempts to recover from cases like:
+    /// - `[u8, 5]` → suggests using `;`, return a Array type
+    /// - `[u8 5]` → suggests using `;`, return a Array type
+    /// Consider to add more cases in the future.
+    fn maybe_recover_array_ty_without_semi(&mut self, elt_ty: P<Ty>) -> PResult<'a, TyKind> {
+        let span = self.token.span;
+        let token_descr = super::token_descr(&self.token);
+        let mut err =
+            self.dcx().struct_span_err(span, format!("expected `;` or `]`, found {}", token_descr));
+        err.span_label(span, "expected `;` or `]`");
+        err.note("you might have meant to write a slice or array type");
+
+        // If we cannot recover, return the error immediately.
+        if !self.may_recover() {
+            return Err(err);
+        }
+
+        let snapshot = self.create_snapshot_for_diagnostic();
+
+        let suggestion_span = if self.eat(exp!(Comma)) || self.eat(exp!(Star)) {
+            // Consume common erroneous separators.
+            self.prev_token.span
+        } else {
+            self.token.span.shrink_to_lo()
+        };
+
+        // we first try to parse pattern like `[u8 5]`
+        let length = match self.parse_expr_anon_const() {
+            Ok(length) => length,
+            Err(e) => {
+                e.cancel();
+                self.restore_snapshot(snapshot);
+                return Err(err);
+            }
+        };
+
+        if let Err(e) = self.expect(exp!(CloseBracket)) {
+            e.cancel();
+            self.restore_snapshot(snapshot);
+            return Err(err);
+        }
+
+        err.span_suggestion_verbose(
+            suggestion_span,
+            "you might have meant to use `;` as the separator",
+            ";",
+            Applicability::MaybeIncorrect,
+        );
+        err.emit();
+        Ok(TyKind::Array(elt_ty, length))
+    }
+
     fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
         let and_span = self.prev_token.span;
         let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index e000d61083d..783d79d978a 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -297,6 +297,7 @@ pub fn check_builtin_meta_item(
                 | sym::align
                 | sym::deprecated
                 | sym::optimize
+                | sym::pointee
                 | sym::cold
                 | sym::target_feature
                 | sym::rustc_allow_const_fn_unstable
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 820255afe27..2009ddc1e2d 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -251,6 +251,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     AttributeKind::BodyStability { .. }
                     | AttributeKind::ConstStabilityIndirect
                     | AttributeKind::MacroTransparency(_)
+                    | AttributeKind::Pointee(..)
                     | AttributeKind::Dummy
                     | AttributeKind::OmitGdbPrettyPrinterSection,
                 ) => { /* do nothing  */ }
@@ -381,7 +382,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::cfg_attr_trace
                             // need to be fixed
                             | sym::cfi_encoding // FIXME(cfi_encoding)
-                            | sym::pointee // FIXME(derive_coerce_pointee)
                             | sym::instruction_set // broken on stable!!!
                             | sym::windows_subsystem // broken on stable!!!
                             | sym::patchable_function_entry // FIXME(patchable_function_entry)
diff --git a/compiler/rustc_type_ir/src/walk.rs b/compiler/rustc_type_ir/src/walk.rs
index 737550eb73e..9912fad1756 100644
--- a/compiler/rustc_type_ir/src/walk.rs
+++ b/compiler/rustc_type_ir/src/walk.rs
@@ -12,12 +12,6 @@ use crate::{self as ty, Interner};
 // avoid heap allocations.
 type TypeWalkerStack<I> = SmallVec<[<I as Interner>::GenericArg; 8]>;
 
-pub struct TypeWalker<I: Interner> {
-    stack: TypeWalkerStack<I>,
-    last_subtree: usize,
-    pub visited: SsoHashSet<I::GenericArg>,
-}
-
 /// An iterator for walking the type tree.
 ///
 /// It's very easy to produce a deeply
@@ -26,6 +20,12 @@ pub struct TypeWalker<I: Interner> {
 /// in this situation walker only visits each type once.
 /// It maintains a set of visited types and
 /// skips any types that are already there.
+pub struct TypeWalker<I: Interner> {
+    stack: TypeWalkerStack<I>,
+    last_subtree: usize,
+    pub visited: SsoHashSet<I::GenericArg>,
+}
+
 impl<I: Interner> TypeWalker<I> {
     pub fn new(root: I::GenericArg) -> Self {
         Self { stack: smallvec![root], last_subtree: 1, visited: SsoHashSet::new() }
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 6b9cbb06435..1b6dbc2f428 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -196,16 +196,14 @@ pub macro assert_matches {
     },
 }
 
-/// A macro for defining `#[cfg]` match-like statements.
+/// Selects code at compile-time based on `cfg` predicates.
 ///
-/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
-/// `#[cfg]` cases, emitting the implementation which matches first.
+/// This macro evaluates, at compile-time, a series of `cfg` predicates,
+/// selects the first that is true, and emits the code guarded by that
+/// predicate. The code guarded by other predicates is not emitted.
 ///
-/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
-/// without having to rewrite each clause multiple times.
-///
-/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
-/// all previous declarations do not evaluate to true.
+/// An optional trailing `_` wildcard can be used to specify a fallback. If
+/// none of the predicates are true, a [`compile_error`] is emitted.
 ///
 /// # Example
 ///
@@ -225,7 +223,7 @@ pub macro assert_matches {
 /// }
 /// ```
 ///
-/// If desired, it is possible to return expressions through the use of surrounding braces:
+/// The `cfg_select!` macro can also be used in expression position:
 ///
 /// ```
 /// #![feature(cfg_select)]
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index fba3436496e..2e26cc871df 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -952,6 +952,7 @@ impl str {
     ///
     /// The caller must ensure that `mid` is a valid byte offset from the start
     /// of the string and falls on the boundary of a UTF-8 code point.
+    #[inline]
     const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
         let len = self.len();
         let ptr = self.as_ptr();
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 62ece4b6961..86d23df5238 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -92,6 +92,9 @@ backtrace = [
     'object/rustc-dep-of-std',
     'miniz_oxide/rustc-dep-of-std',
 ]
+# Disable symbolization in backtraces. For use with -Zbuild-std.
+# FIXME: Ideally this should be an additive backtrace-symbolization feature
+backtrace-trace-only = []
 
 panic-unwind = ["dep:panic_unwind"]
 compiler-builtins-c = ["alloc/compiler-builtins-c"]
diff --git a/library/std/src/sys/backtrace.rs b/library/std/src/sys/backtrace.rs
index efa6a896dad..272d0fa4d1a 100644
--- a/library/std/src/sys/backtrace.rs
+++ b/library/std/src/sys/backtrace.rs
@@ -68,61 +68,67 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
                 return false;
             }
 
-            let mut hit = false;
-            backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
-                hit = true;
-
-                // `__rust_end_short_backtrace` means we are done hiding symbols
-                // for now. Print until we see `__rust_begin_short_backtrace`.
-                if print_fmt == PrintFmt::Short {
-                    if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
-                        if sym.contains("__rust_end_short_backtrace") {
-                            print = true;
-                            return;
-                        }
-                        if print && sym.contains("__rust_begin_short_backtrace") {
-                            print = false;
-                            return;
-                        }
-                        if !print {
-                            omitted_count += 1;
+            if cfg!(feature = "backtrace-trace-only") {
+                const HEX_WIDTH: usize = 2 + 2 * size_of::<usize>();
+                let frame_ip = frame.ip();
+                res = writeln!(bt_fmt.formatter(), "{idx:4}: {frame_ip:HEX_WIDTH$?}");
+            } else {
+                let mut hit = false;
+                backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
+                    hit = true;
+
+                    // `__rust_end_short_backtrace` means we are done hiding symbols
+                    // for now. Print until we see `__rust_begin_short_backtrace`.
+                    if print_fmt == PrintFmt::Short {
+                        if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
+                            if sym.contains("__rust_end_short_backtrace") {
+                                print = true;
+                                return;
+                            }
+                            if print && sym.contains("__rust_begin_short_backtrace") {
+                                print = false;
+                                return;
+                            }
+                            if !print {
+                                omitted_count += 1;
+                            }
                         }
                     }
-                }
 
-                if print {
-                    if omitted_count > 0 {
-                        debug_assert!(print_fmt == PrintFmt::Short);
-                        // only print the message between the middle of frames
-                        if !first_omit {
-                            let _ = writeln!(
-                                bt_fmt.formatter(),
-                                "      [... omitted {} frame{} ...]",
-                                omitted_count,
-                                if omitted_count > 1 { "s" } else { "" }
-                            );
+                    if print {
+                        if omitted_count > 0 {
+                            debug_assert!(print_fmt == PrintFmt::Short);
+                            // only print the message between the middle of frames
+                            if !first_omit {
+                                let _ = writeln!(
+                                    bt_fmt.formatter(),
+                                    "      [... omitted {} frame{} ...]",
+                                    omitted_count,
+                                    if omitted_count > 1 { "s" } else { "" }
+                                );
+                            }
+                            first_omit = false;
+                            omitted_count = 0;
                         }
-                        first_omit = false;
-                        omitted_count = 0;
+                        res = bt_fmt.frame().symbol(frame, symbol);
                     }
-                    res = bt_fmt.frame().symbol(frame, symbol);
+                });
+                #[cfg(target_os = "nto")]
+                if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
+                    if !hit && print {
+                        use crate::backtrace_rs::SymbolName;
+                        res = bt_fmt.frame().print_raw(
+                            frame.ip(),
+                            Some(SymbolName::new("__my_thread_exit".as_bytes())),
+                            None,
+                            None,
+                        );
+                    }
+                    return false;
                 }
-            });
-            #[cfg(target_os = "nto")]
-            if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {
                 if !hit && print {
-                    use crate::backtrace_rs::SymbolName;
-                    res = bt_fmt.frame().print_raw(
-                        frame.ip(),
-                        Some(SymbolName::new("__my_thread_exit".as_bytes())),
-                        None,
-                        None,
-                    );
+                    res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
                 }
-                return false;
-            }
-            if !hit && print {
-                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
             }
 
             idx += 1;
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
index 290c2eeed44..032f5272a9c 100644
--- a/library/sysroot/Cargo.toml
+++ b/library/sysroot/Cargo.toml
@@ -20,6 +20,7 @@ test = { path = "../test", public = true }
 [features]
 default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
 backtrace = ["std/backtrace"]
+backtrace-trace-only = ["std/backtrace-trace-only"]
 compiler-builtins-c = ["std/compiler-builtins-c"]
 compiler-builtins-mem = ["std/compiler-builtins-mem"]
 compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"]
diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs
index fcb6abea434..c2ad9a4df59 100644
--- a/src/bootstrap/src/core/build_steps/mod.rs
+++ b/src/bootstrap/src/core/build_steps/mod.rs
@@ -11,7 +11,6 @@ pub(crate) mod llvm;
 pub(crate) mod perf;
 pub(crate) mod run;
 pub(crate) mod setup;
-pub(crate) mod suggest;
 pub(crate) mod synthetic_targets;
 pub(crate) mod test;
 pub(crate) mod tool;
diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs
deleted file mode 100644
index fd4918961ad..00000000000
--- a/src/bootstrap/src/core/build_steps/suggest.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-//! Attempt to magically identify good tests to run
-
-use std::path::PathBuf;
-use std::str::FromStr;
-
-use clap::Parser;
-
-use crate::core::build_steps::tool::Tool;
-use crate::core::builder::Builder;
-
-/// Suggests a list of possible `x.py` commands to run based on modified files in branch.
-pub fn suggest(builder: &Builder<'_>, run: bool) {
-    let git_config = builder.config.git_config();
-    let suggestions = builder
-        .tool_cmd(Tool::SuggestTests)
-        .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch)
-        .env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL", git_config.git_merge_commit_email)
-        .run_capture_stdout(builder)
-        .stdout();
-
-    let suggestions = suggestions
-        .lines()
-        .map(|line| {
-            let mut sections = line.split_ascii_whitespace();
-
-            // this code expects one suggestion per line in the following format:
-            // <x_subcommand> {some number of flags} [optional stage number]
-            let cmd = sections.next().unwrap();
-            let stage = sections.next_back().and_then(|s| str::parse(s).ok());
-            let paths: Vec<PathBuf> = sections.map(|p| PathBuf::from_str(p).unwrap()).collect();
-
-            (cmd, stage, paths)
-        })
-        .collect::<Vec<_>>();
-
-    if !suggestions.is_empty() {
-        println!("==== SUGGESTIONS ====");
-        for sug in &suggestions {
-            print!("x {} ", sug.0);
-            if let Some(stage) = sug.1 {
-                print!("--stage {stage} ");
-            }
-
-            for path in &sug.2 {
-                print!("{} ", path.display());
-            }
-            println!();
-        }
-        println!("=====================");
-    } else {
-        println!("No suggestions found!");
-        return;
-    }
-
-    if run {
-        for sug in suggestions {
-            let mut build: crate::Build = builder.build.clone();
-            build.config.paths = sug.2;
-            build.config.cmd = crate::core::config::flags::Flags::parse_from(["x.py", sug.0]).cmd;
-            if let Some(stage) = sug.1 {
-                build.config.stage = stage;
-            }
-            build.build();
-        }
-    } else {
-        println!("HELP: consider using the `--run` flag to automatically run suggested tests");
-    }
-}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 757eac1475c..9e7ea5c115f 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -47,12 +47,11 @@ impl Step for CrateBootstrap {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        // This step is responsible for several different tool paths. By default
-        // it will test all of them, but requesting specific tools on the
-        // command-line (e.g. `./x test suggest-tests`) will test only the
-        // specified tools.
+        // This step is responsible for several different tool paths.
+        //
+        // By default, it will test all of them, but requesting specific tools on the command-line
+        // (e.g. `./x test src/tools/coverage-dump`) will test only the specified tools.
         run.path("src/tools/jsondoclint")
-            .path("src/tools/suggest-tests")
             .path("src/tools/replace-version-placeholder")
             .path("src/tools/coverage-dump")
             // We want `./x test tidy` to _run_ the tidy tool, not its tests.
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 814a44b9a13..1c994b0ccfc 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -517,7 +517,6 @@ bootstrap_tool!(
     ReplaceVersionPlaceholder, "src/tools/replace-version-placeholder", "replace-version-placeholder";
     CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata";
     GenerateCopyright, "src/tools/generate-copyright", "generate-copyright";
-    SuggestTests, "src/tools/suggest-tests", "suggest-tests";
     GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys";
     // rustdoc-gui-test has a crate dependency on compiletest, so it needs the same unstable features.
     RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = COMPILETEST_ALLOW_FEATURES;
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index d5a290d804c..a3b471ca56e 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -113,7 +113,7 @@ impl Cargo {
 
         match cmd_kind {
             // No need to configure the target linker for these command types.
-            Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {}
+            Kind::Clean | Kind::Check | Kind::Format | Kind::Setup => {}
             _ => {
                 cargo.configure_linker(builder, mode);
             }
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 7115c5a1cbe..1b75d00b30e 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -845,7 +845,6 @@ pub enum Kind {
     #[value(alias = "r")]
     Run,
     Setup,
-    Suggest,
     Vendor,
     Perf,
 }
@@ -869,7 +868,6 @@ impl Kind {
             Kind::Install => "install",
             Kind::Run => "run",
             Kind::Setup => "setup",
-            Kind::Suggest => "suggest",
             Kind::Vendor => "vendor",
             Kind::Perf => "perf",
         }
@@ -881,7 +879,6 @@ impl Kind {
             Kind::Bench => "Benchmarking",
             Kind::Doc => "Documenting",
             Kind::Run => "Running",
-            Kind::Suggest => "Suggesting",
             Kind::Clippy => "Linting",
             Kind::Perf => "Profiling & benchmarking",
             _ => {
@@ -1201,7 +1198,7 @@ impl<'a> Builder<'a> {
             Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
             Kind::Vendor => describe!(vendor::Vendor),
             // special-cased in Build::build()
-            Kind::Format | Kind::Suggest | Kind::Perf => vec![],
+            Kind::Format | Kind::Perf => vec![],
             Kind::MiriTest | Kind::MiriSetup => unreachable!(),
         }
     }
@@ -1269,7 +1266,6 @@ impl<'a> Builder<'a> {
             Subcommand::Run { .. } => (Kind::Run, &paths[..]),
             Subcommand::Clean { .. } => (Kind::Clean, &paths[..]),
             Subcommand::Format { .. } => (Kind::Format, &[][..]),
-            Subcommand::Suggest { .. } => (Kind::Suggest, &[][..]),
             Subcommand::Setup { profile: ref path } => (
                 Kind::Setup,
                 path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)),
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 0039d44785c..28958b60fc3 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1050,7 +1050,6 @@ impl Config {
             | Subcommand::Run { .. }
             | Subcommand::Setup { .. }
             | Subcommand::Format { .. }
-            | Subcommand::Suggest { .. }
             | Subcommand::Vendor { .. } => flags_stage.unwrap_or(0),
         };
 
@@ -1098,7 +1097,6 @@ impl Config {
                 | Subcommand::Run { .. }
                 | Subcommand::Setup { .. }
                 | Subcommand::Format { .. }
-                | Subcommand::Suggest { .. }
                 | Subcommand::Vendor { .. }
                 | Subcommand::Perf { .. } => {}
             }
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 155b6f58758..1547ca44494 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -481,13 +481,6 @@ Arguments:
         #[arg(value_name = "<PROFILE>|hook|editor|link")]
         profile: Option<PathBuf>,
     },
-    /// Suggest a subset of tests to run, based on modified files
-    #[command(long_about = "\n")]
-    Suggest {
-        /// run suggested tests
-        #[arg(long)]
-        run: bool,
-    },
     /// Vendor dependencies
     Vendor {
         /// Additional `Cargo.toml` to sync and vendor
@@ -518,7 +511,6 @@ impl Subcommand {
             Subcommand::Install => Kind::Install,
             Subcommand::Run { .. } => Kind::Run,
             Subcommand::Setup { .. } => Kind::Setup,
-            Subcommand::Suggest { .. } => Kind::Suggest,
             Subcommand::Vendor { .. } => Kind::Vendor,
             Subcommand::Perf { .. } => Kind::Perf,
         }
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index f2119e84cce..b39d464493e 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -216,7 +216,6 @@ than building it.
             build.config.cmd,
             Subcommand::Clean { .. }
                 | Subcommand::Check { .. }
-                | Subcommand::Suggest { .. }
                 | Subcommand::Format { .. }
                 | Subcommand::Setup { .. }
         );
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 66a164703b7..44be51815c7 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -651,11 +651,9 @@ impl Build {
         // Handle hard-coded subcommands.
         {
             #[cfg(feature = "tracing")]
-            let _hardcoded_span = span!(
-                tracing::Level::DEBUG,
-                "handling hardcoded subcommands (Format, Suggest, Perf)"
-            )
-            .entered();
+            let _hardcoded_span =
+                span!(tracing::Level::DEBUG, "handling hardcoded subcommands (Format, Perf)")
+                    .entered();
 
             match &self.config.cmd {
                 Subcommand::Format { check, all } => {
@@ -666,9 +664,6 @@ impl Build {
                         &self.config.paths,
                     );
                 }
-                Subcommand::Suggest { run } => {
-                    return core::build_steps::suggest::suggest(&builder::Builder::new(self), *run);
-                }
                 Subcommand::Perf(args) => {
                     return core::build_steps::perf::perf(&builder::Builder::new(self), args);
                 }
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index dcafeb80f90..d3926df9650 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -67,7 +67,6 @@ pub fn fill_compilers(build: &mut Build) {
         // We don't need to check cross targets for these commands.
         crate::Subcommand::Clean { .. }
         | crate::Subcommand::Check { .. }
-        | crate::Subcommand::Suggest { .. }
         | crate::Subcommand::Format { .. }
         | crate::Subcommand::Setup { .. } => {
             build.hosts.iter().cloned().chain(iter::once(build.host_target)).collect()
@@ -221,10 +220,15 @@ fn default_compiler(
         }
 
         t if t.contains("-wasi") => {
-            let root = build
-                .wasi_sdk_path
-                .as_ref()
-                .expect("WASI_SDK_PATH mut be configured for a -wasi target");
+            let root = if let Some(path) = build.wasi_sdk_path.as_ref() {
+                path
+            } else {
+                if build.config.is_running_on_ci {
+                    panic!("ERROR: WASI_SDK_PATH must be configured for a -wasi target on CI");
+                }
+                println!("WARNING: WASI_SDK_PATH not set, using default cc/cxx compiler");
+                return None;
+            };
             let compiler = match compiler {
                 Language::C => format!("{t}-clang"),
                 Language::CPlusPlus => format!("{t}-clang++"),
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 1f6ed8129da..d888a7863bc 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -476,4 +476,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "Option `tool.TOOL_NAME.features` now works on any subcommand, not just `build`.",
     },
+    ChangeInfo {
+        change_id: 143630,
+        severity: ChangeSeverity::Warning,
+        summary: "The current `./x suggest` implementation has been removed due to it being quite broken and a lack of maintenance bandwidth, with no prejudice against re-implementing it in a more maintainable form.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs
index 862c4449624..9b1ccc32cb6 100644
--- a/src/bootstrap/src/utils/metrics.rs
+++ b/src/bootstrap/src/utils/metrics.rs
@@ -43,7 +43,7 @@ pub(crate) struct BuildMetrics {
     state: RefCell<MetricsState>,
 }
 
-/// NOTE: this isn't really cloning anything, but `x suggest` doesn't need metrics so this is probably ok.
+// NOTE: this isn't really cloning anything, but necessary for `Build: Clone`.
 impl Clone for BuildMetrics {
     fn clone(&self) -> Self {
         Self::init()
diff --git a/src/doc/book b/src/doc/book
-Subproject ef1ce8f87a8b18feb1b6a9cf9a4939a79bde679
+Subproject b2d1a0821e12a676b496d61891b8e3d374a8e83
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 41f688a598a5022b749e23d37f3c524f6a0b28e
+Subproject fe88fbb68391a465680dd91109f0a151a1676f3
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 8b61acfaea822e9ac926190bc8f15791c33336e
+Subproject 3ff384320598bbe8d8cfe5cb8f18f78a3a3e6b1
diff --git a/src/doc/reference b/src/doc/reference
-Subproject e9fc99f107840813916f62e16b3f6d9556e1f2d
+Subproject 1f45bd41fa6c17b7c048ed6bfe5f168c4311206
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 288b4e4948add43f387cad35adc7b1c54ca6fe1
+Subproject e386be5f44af711854207c11fdd61bb576270b0
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 7f2f32c62ff..651e2925ad5 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -35,7 +35,6 @@
         - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md)
         - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md)
     - [Performance testing](./tests/perf.md)
-    - [Suggest tests tool](./tests/suggest-tests.md)
     - [Misc info](./tests/misc.md)
 - [Debugging the compiler](./compiler-debugging.md)
     - [Using the tracing/logging instrumentation](./tracing.md)
diff --git a/src/doc/rustc-dev-guide/src/building/quickstart.md b/src/doc/rustc-dev-guide/src/building/quickstart.md
index 9a8ab353e02..97314d80369 100644
--- a/src/doc/rustc-dev-guide/src/building/quickstart.md
+++ b/src/doc/rustc-dev-guide/src/building/quickstart.md
@@ -61,9 +61,6 @@ and check the output.
 Use `--bless` if you've made a change and want to update the `.stderr` files
 with the new output.
 
-> `./x suggest` can also be helpful for suggesting which tests to run after a
-> change.
-
 Congrats, you are now ready to make a change to the compiler! If you have more
 questions, [the full chapter](./how-to-build-and-run.md) might contain the
 answers, and if it doesn't, feel free to ask for help on
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index bfb2f4d1084..7f626314f71 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -270,23 +270,6 @@ run the tests at some later time. You can then use `git bisect` to track down
 is that you are left with a fairly fine-grained set of commits at the end, all
 of which build and pass tests. This often helps reviewing.
 
-## `x suggest`
-
-The `x suggest` subcommand suggests (and runs) a subset of the extensive
-`rust-lang/rust` tests based on files you have changed. This is especially
-useful for new contributors who have not mastered the arcane `x` flags yet and
-more experienced contributors as a shorthand for reducing mental effort. In all
-cases it is useful not to run the full tests (which can take on the order of
-tens of minutes) and just run a subset which are relevant to your changes. For
-example, running `tidy` and `linkchecker` is useful when editing Markdown files,
-whereas UI tests are much less likely to be helpful. While `x suggest` is a
-useful tool, it does not guarantee perfect coverage (just as PR CI isn't a
-substitute for bors). See the [dedicated chapter](../tests/suggest-tests.md) for
-more information and contribution instructions.
-
-Please note that `x suggest` is in a beta state currently and the tests that it
-will suggest are limited.
-
 ## Configuring `rustup` to use nightly
 
 Some parts of the bootstrap process uses pinned, nightly versions of tools like
diff --git a/src/doc/rustc-dev-guide/src/tests/suggest-tests.md b/src/doc/rustc-dev-guide/src/tests/suggest-tests.md
deleted file mode 100644
index 663e8a5af3b..00000000000
--- a/src/doc/rustc-dev-guide/src/tests/suggest-tests.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# Suggest tests tool
-
-This chapter is about the internals of and contribution instructions for the
-`suggest-tests` tool. For a high-level overview of the tool, see [this
-section](../building/suggested.md#x-suggest). This tool is currently in a beta
-state and is tracked by [this](https://github.com/rust-lang/rust/issues/109933)
-issue on Github. Currently the number of tests it will suggest are very limited
-in scope, we are looking to expand this (contributions welcome!).
-
-## Internals
-
-The tool is defined in a separate crate
-([`src/tools/suggest-tests`](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests))
-which outputs suggestions which are parsed by a shim in bootstrap
-([`src/bootstrap/src/core/build_steps/suggest.rs`](https://github.com/rust-lang/rust/blob/master/src/bootstrap/src/core/build_steps/suggest.rs)).
-The only notable thing the bootstrap shim does is (when invoked with the `--run`
-flag) use bootstrap's internal mechanisms to create a new `Builder` and uses it
-to invoke the suggested commands. The `suggest-tests` crate is where the fun
-happens, two kinds of suggestions are defined: "static" and "dynamic"
-suggestions.
-
-### Static suggestions
-
-Defined
-[here](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/static_suggestions.rs).
-Static suggestions are simple: they are just
-[globs](https://crates.io/crates/glob) which map to a `x` command. In
-`suggest-tests`, this is implemented with a simple `macro_rules` macro.
-
-### Dynamic suggestions
-
-Defined
-[here](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/dynamic_suggestions.rs).
-These are more complicated than static suggestions and are implemented as
-functions with the following signature: `fn(&Path) -> Vec<Suggestion>`. In other
-words, each suggestion takes a path to a modified file and (after running
-arbitrary Rust code) can return any number of suggestions, or none. Dynamic
-suggestions are useful for situations where fine-grained control over
-suggestions is needed. For example, modifications to the `compiler/xyz/` path
-should trigger the `x test compiler/xyz` suggestion. In the future, dynamic
-suggestions might even read file contents to determine if (what) tests should
-run.
-
-## Adding a suggestion
-
-The following steps should serve as a rough guide to add suggestions to
-`suggest-tests` (very welcome!):
-
-1. Determine the rules for your suggestion. Is it simple and operates only on a
-   single path or does it match globs? Does it need fine-grained control over
-   the resulting command or does "one size fit all"?
-2. Based on the previous step, decide if your suggestion should be implemented
-   as either static or dynamic.
-3. Implement the suggestion. If it is dynamic then a test is highly recommended,
-   to verify that your logic is correct and to give an example of the
-   suggestion. See the
-   [tests.rs](https://github.com/rust-lang/rust/blob/master/src/tools/suggest-tests/src/tests.rs)
-   file.
-4. Open a PR implementing your suggestion. **(TODO: add example PR)**
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index d3da1f353e2..28a228d5464 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -73,7 +73,6 @@ complete -c x -n "__fish_x_needs_command" -a "dist" -d 'Build distribution artif
 complete -c x -n "__fish_x_needs_command" -a "install" -d 'Install distribution artifacts'
 complete -c x -n "__fish_x_needs_command" -a "run" -d 'Run tools contained in this repository'
 complete -c x -n "__fish_x_needs_command" -a "setup" -d 'Set up the environment for development'
-complete -c x -n "__fish_x_needs_command" -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
 complete -c x -n "__fish_x_needs_command" -a "vendor" -d 'Vendor dependencies'
 complete -c x -n "__fish_x_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`'
 complete -c x -n "__fish_x_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F
@@ -599,42 +598,6 @@ complete -c x -n "__fish_x_using_subcommand setup" -l enable-bolt-settings -d 'E
 complete -c x -n "__fish_x_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x -n "__fish_x_using_subcommand setup" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x -n "__fish_x_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x -n "__fish_x_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
-complete -c x -n "__fish_x_using_subcommand suggest" -l build -d 'host target of the stage0 compiler' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l host -d 'host targets to build' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l target -d 'target targets to build' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l exclude -d 'build paths to exclude' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l skip -d 'build paths to skip' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l rustc-error-format -d 'rustc error format' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
-complete -c x -n "__fish_x_using_subcommand suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
-complete -c x -n "__fish_x_using_subcommand suggest" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
-complete -c x -n "__fish_x_using_subcommand suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
-complete -c x -n "__fish_x_using_subcommand suggest" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
-complete -c x -n "__fish_x_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
-complete -c x -n "__fish_x_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f
-complete -c x -n "__fish_x_using_subcommand suggest" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
-complete -c x -n "__fish_x_using_subcommand suggest" -l run -d 'run suggested tests'
-complete -c x -n "__fish_x_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
-complete -c x -n "__fish_x_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation'
-complete -c x -n "__fish_x_using_subcommand suggest" -l include-default-paths -d 'include default paths in addition to the provided ones'
-complete -c x -n "__fish_x_using_subcommand suggest" -l dry-run -d 'dry run; don\'t build anything'
-complete -c x -n "__fish_x_using_subcommand suggest" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
-complete -c x -n "__fish_x_using_subcommand suggest" -l json-output -d 'use message-format=json'
-complete -c x -n "__fish_x_using_subcommand suggest" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)'
-complete -c x -n "__fish_x_using_subcommand suggest" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
-complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
-complete -c x -n "__fish_x_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
-complete -c x -n "__fish_x_using_subcommand suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
-complete -c x -n "__fish_x_using_subcommand suggest" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
-complete -c x -n "__fish_x_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x -n "__fish_x_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F
 complete -c x -n "__fish_x_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F
 complete -c x -n "__fish_x_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index b5b59c58bba..0c9b3828273 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -74,7 +74,6 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install distribution artifacts')
             [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository')
             [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
-            [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
             [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies')
             [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using `rustc-perf`')
             break
@@ -700,49 +699,6 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
-        'x;suggest' {
-            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
-            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
-            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler')
-            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
-            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
-            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
-            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
-            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc error format')
-            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
-            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
-            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
-            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
-            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
-            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
-            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
-            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
-            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
-            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
-            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
-            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
-            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
-            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
-            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
-            [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests')
-            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
-            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
-            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
-            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
-            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
-            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
-            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
-            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
-            [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)')
-            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
-            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
-            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
-            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
-            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
-            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            break
-        }
         'x;vendor' {
             [CompletionResult]::new('--sync', '--sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor')
             [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index da7680a879d..43ae7424e27 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -73,7 +73,6 @@ complete -c x.py -n "__fish_x.py_needs_command" -a "dist" -d 'Build distribution
 complete -c x.py -n "__fish_x.py_needs_command" -a "install" -d 'Install distribution artifacts'
 complete -c x.py -n "__fish_x.py_needs_command" -a "run" -d 'Run tools contained in this repository'
 complete -c x.py -n "__fish_x.py_needs_command" -a "setup" -d 'Set up the environment for development'
-complete -c x.py -n "__fish_x.py_needs_command" -a "suggest" -d 'Suggest a subset of tests to run, based on modified files'
 complete -c x.py -n "__fish_x.py_needs_command" -a "vendor" -d 'Vendor dependencies'
 complete -c x.py -n "__fish_x.py_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F
@@ -599,42 +598,6 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l enable-bolt-settings
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build -d 'host target of the stage0 compiler' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l host -d 'host targets to build' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l target -d 'target targets to build' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l exclude -d 'build paths to exclude' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip -d 'build paths to skip' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rustc-error-format -d 'rustc error format' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny\t'',warn\t'',default\t''}"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always\t'',never\t'',auto\t''}"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l run -d 'run suggested tests'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l include-default-paths -d 'include default paths in addition to the provided ones'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l dry-run -d 'dry run; don\'t build anything'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l json-output -d 'use message-format=json'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l compile-time-deps -d 'only build proc-macros and build scripts (for rust-analyzer)'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l enable-bolt-settings -d 'Enable BOLT link flags'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip-std-check-if-no-download-rustc -d 'Skip checking the standard library if `rust.download-rustc` isn\'t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers'
-complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)"
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 3fc8e7d5bbd..4311e383d64 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -74,7 +74,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install distribution artifacts')
             [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository')
             [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development')
-            [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files')
             [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies')
             [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using `rustc-perf`')
             break
@@ -700,49 +699,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
-        'x.py;suggest' {
-            [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
-            [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`')
-            [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'host target of the stage0 compiler')
-            [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build')
-            [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build')
-            [CompletionResult]::new('--exclude', '--exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
-            [CompletionResult]::new('--skip', '--skip', [CompletionResultType]::ParameterName, 'build paths to skip')
-            [CompletionResult]::new('--rustc-error-format', '--rustc-error-format', [CompletionResultType]::ParameterName, 'rustc error format')
-            [CompletionResult]::new('--on-fail', '--on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
-            [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
-            [CompletionResult]::new('--keep-stage', '--keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
-            [CompletionResult]::new('--keep-stage-std', '--keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
-            [CompletionResult]::new('--src', '--src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
-            [CompletionResult]::new('-j', '-j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
-            [CompletionResult]::new('--jobs', '--jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
-            [CompletionResult]::new('--warnings', '--warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
-            [CompletionResult]::new('--color', '--color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
-            [CompletionResult]::new('--rust-profile-generate', '--rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
-            [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
-            [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
-            [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
-            [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
-            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
-            [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests')
-            [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
-            [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
-            [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
-            [CompletionResult]::new('--incremental', '--incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
-            [CompletionResult]::new('--include-default-paths', '--include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
-            [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
-            [CompletionResult]::new('--dump-bootstrap-shims', '--dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
-            [CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
-            [CompletionResult]::new('--compile-time-deps', '--compile-time-deps', [CompletionResultType]::ParameterName, 'only build proc-macros and build scripts (for rust-analyzer)')
-            [CompletionResult]::new('--bypass-bootstrap-lock', '--bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
-            [CompletionResult]::new('--llvm-profile-generate', '--llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
-            [CompletionResult]::new('--enable-bolt-settings', '--enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
-            [CompletionResult]::new('--skip-stage0-validation', '--skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
-            [CompletionResult]::new('--skip-std-check-if-no-download-rustc', '--skip-std-check-if-no-download-rustc', [CompletionResultType]::ParameterName, 'Skip checking the standard library if `rust.download-rustc` isn''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers')
-            [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
-            break
-        }
         'x.py;vendor' {
             [CompletionResult]::new('--sync', '--sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor')
             [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 8f13de282fb..f31bdb58dc4 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -54,9 +54,6 @@ _x.py() {
             x.py,setup)
                 cmd="x.py__setup"
                 ;;
-            x.py,suggest)
-                cmd="x.py__suggest"
-                ;;
             x.py,test)
                 cmd="x.py__test"
                 ;;
@@ -85,7 +82,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3877,192 +3874,6 @@ _x.py() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
-        x.py__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --config)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --build-dir)
-                    COMPREPLY=()
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o plusdirs
-                    fi
-                    return 0
-                    ;;
-                --build)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --host)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --target)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --exclude)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --skip)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --rustc-error-format)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --on-fail)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --stage)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --keep-stage)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --keep-stage-std)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --src)
-                    COMPREPLY=()
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o plusdirs
-                    fi
-                    return 0
-                    ;;
-                --jobs)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                -j)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --warnings)
-                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
-                    return 0
-                    ;;
-                --color)
-                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
-                    return 0
-                    ;;
-                --rust-profile-generate)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --rust-profile-use)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --llvm-profile-use)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --reproducible-artifact)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --set)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --ci)
-                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
         x.py__test)
             opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index 60ce9002116..aff35b31e21 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -715,51 +715,6 @@ _arguments "${_arguments_options[@]}" : \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
-(suggest)
-_arguments "${_arguments_options[@]}" : \
-'--config=[TOML configuration file for build]:FILE:_files' \
-'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
-'--build=[host target of the stage0 compiler]:BUILD:' \
-'--host=[host targets to build]:HOST:' \
-'--target=[target targets to build]:TARGET:' \
-'*--exclude=[build paths to exclude]:PATH:_files' \
-'*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[rustc error format]:RUSTC_ERROR_FORMAT:' \
-'--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
-'--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:' \
-'--jobs=[number of jobs to run in parallel]:JOBS:' \
-'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
-'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
-'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
-'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
-'*--set=[override options in bootstrap.toml]:section.option=value:' \
-'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
-'--run[run suggested tests]' \
-'*-v[use verbose output (-vv for very verbose)]' \
-'*--verbose[use verbose output (-vv for very verbose)]' \
-'-i[use incremental compilation]' \
-'--incremental[use incremental compilation]' \
-'--include-default-paths[include default paths in addition to the provided ones]' \
-'--dry-run[dry run; don'\''t build anything]' \
-'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
-'--json-output[use message-format=json]' \
-'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \
-'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
-'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
-'--enable-bolt-settings[Enable BOLT link flags]' \
-'--skip-stage0-validation[Skip stage0 compiler validation]' \
-'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
-'-h[Print help (see more with '\''--help'\'')]' \
-'--help[Print help (see more with '\''--help'\'')]' \
-'*::paths -- paths for the subcommand:_files' \
-&& ret=0
-;;
 (vendor)
 _arguments "${_arguments_options[@]}" : \
 '*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \
@@ -1120,7 +1075,6 @@ _x.py_commands() {
 'install:Install distribution artifacts' \
 'run:Run tools contained in this repository' \
 'setup:Set up the environment for development' \
-'suggest:Suggest a subset of tests to run, based on modified files' \
 'vendor:Vendor dependencies' \
 'perf:Perform profiling and benchmarking of the compiler using \`rustc-perf\`' \
     )
@@ -1227,11 +1181,6 @@ _x.py__setup_commands() {
     local commands; commands=()
     _describe -t commands 'x.py setup commands' commands "$@"
 }
-(( $+functions[_x.py__suggest_commands] )) ||
-_x.py__suggest_commands() {
-    local commands; commands=()
-    _describe -t commands 'x.py suggest commands' commands "$@"
-}
 (( $+functions[_x.py__test_commands] )) ||
 _x.py__test_commands() {
     local commands; commands=()
diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh
index f6ecf4cebf4..927d8f7661c 100644
--- a/src/etc/completions/x.sh
+++ b/src/etc/completions/x.sh
@@ -54,9 +54,6 @@ _x() {
             x,setup)
                 cmd="x__setup"
                 ;;
-            x,suggest)
-                cmd="x__suggest"
-                ;;
             x,test)
                 cmd="x__test"
                 ;;
@@ -85,7 +82,7 @@ _x() {
 
     case "${cmd}" in
         x)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3877,192 +3874,6 @@ _x() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
-        x__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
-            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
-                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-                return 0
-            fi
-            case "${prev}" in
-                --config)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --build-dir)
-                    COMPREPLY=()
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o plusdirs
-                    fi
-                    return 0
-                    ;;
-                --build)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --host)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --target)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --exclude)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --skip)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --rustc-error-format)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --on-fail)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --stage)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --keep-stage)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --keep-stage-std)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --src)
-                    COMPREPLY=()
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o plusdirs
-                    fi
-                    return 0
-                    ;;
-                --jobs)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                -j)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --warnings)
-                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
-                    return 0
-                    ;;
-                --color)
-                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
-                    return 0
-                    ;;
-                --rust-profile-generate)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --rust-profile-use)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --llvm-profile-use)
-                    local oldifs
-                    if [ -n "${IFS+x}" ]; then
-                        oldifs="$IFS"
-                    fi
-                    IFS=$'\n'
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    if [ -n "${oldifs+x}" ]; then
-                        IFS="$oldifs"
-                    fi
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o filenames
-                    fi
-                    return 0
-                    ;;
-                --reproducible-artifact)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
-                --set)
-                    COMPREPLY=("${cur}")
-                    if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
-                        compopt -o nospace
-                    fi
-                    return 0
-                    ;;
-                --ci)
-                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
-                    return 0
-                    ;;
-                *)
-                    COMPREPLY=()
-                    ;;
-            esac
-            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
-            return 0
-            ;;
         x__test)
             opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index 452a26fef07..28ad00f3a0d 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -715,51 +715,6 @@ _arguments "${_arguments_options[@]}" : \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
-(suggest)
-_arguments "${_arguments_options[@]}" : \
-'--config=[TOML configuration file for build]:FILE:_files' \
-'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \
-'--build=[host target of the stage0 compiler]:BUILD:' \
-'--host=[host targets to build]:HOST:' \
-'--target=[target targets to build]:TARGET:' \
-'*--exclude=[build paths to exclude]:PATH:_files' \
-'*--skip=[build paths to skip]:PATH:_files' \
-'--rustc-error-format=[rustc error format]:RUSTC_ERROR_FORMAT:' \
-'--on-fail=[command to run on failure]:CMD:_cmdstring' \
-'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:' \
-'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
-'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:' \
-'--src=[path to the root of the rust checkout]:DIR:_files -/' \
-'-j+[number of jobs to run in parallel]:JOBS:' \
-'--jobs=[number of jobs to run in parallel]:JOBS:' \
-'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
-'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
-'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
-'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
-'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
-'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
-'*--set=[override options in bootstrap.toml]:section.option=value:' \
-'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
-'--run[run suggested tests]' \
-'*-v[use verbose output (-vv for very verbose)]' \
-'*--verbose[use verbose output (-vv for very verbose)]' \
-'-i[use incremental compilation]' \
-'--incremental[use incremental compilation]' \
-'--include-default-paths[include default paths in addition to the provided ones]' \
-'--dry-run[dry run; don'\''t build anything]' \
-'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
-'--json-output[use message-format=json]' \
-'--compile-time-deps[only build proc-macros and build scripts (for rust-analyzer)]' \
-'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
-'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
-'--enable-bolt-settings[Enable BOLT link flags]' \
-'--skip-stage0-validation[Skip stage0 compiler validation]' \
-'--skip-std-check-if-no-download-rustc[Skip checking the standard library if \`rust.download-rustc\` isn'\''t available. This is mostly for RA as building the stage1 compiler to check the library tree on each code change might be too much for some computers]' \
-'-h[Print help (see more with '\''--help'\'')]' \
-'--help[Print help (see more with '\''--help'\'')]' \
-'*::paths -- paths for the subcommand:_files' \
-&& ret=0
-;;
 (vendor)
 _arguments "${_arguments_options[@]}" : \
 '*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \
@@ -1120,7 +1075,6 @@ _x_commands() {
 'install:Install distribution artifacts' \
 'run:Run tools contained in this repository' \
 'setup:Set up the environment for development' \
-'suggest:Suggest a subset of tests to run, based on modified files' \
 'vendor:Vendor dependencies' \
 'perf:Perform profiling and benchmarking of the compiler using \`rustc-perf\`' \
     )
@@ -1227,11 +1181,6 @@ _x__setup_commands() {
     local commands; commands=()
     _describe -t commands 'x setup commands' commands "$@"
 }
-(( $+functions[_x__suggest_commands] )) ||
-_x__suggest_commands() {
-    local commands; commands=()
-    _describe -t commands 'x suggest commands' commands "$@"
-}
 (( $+functions[_x__test_commands] )) ||
 _x__test_commands() {
     local commands; commands=()
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index 6bf968a3132..93133ea0bfd 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -971,6 +971,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "only-mips64",
     "only-msp430",
     "only-msvc",
+    "only-musl",
     "only-nightly",
     "only-nvptx64",
     "only-powerpc",
diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs
index e4d244e14a4..0e11360bd5a 100644
--- a/src/tools/run-make-support/src/symbols.rs
+++ b/src/tools/run-make-support/src/symbols.rs
@@ -1,6 +1,7 @@
+use std::collections::BTreeSet;
 use std::path::Path;
 
-use object::{self, Object, ObjectSymbol, SymbolIterator};
+use object::{self, Object, ObjectSymbol};
 
 /// Given an [`object::File`], find the exported dynamic symbol names via
 /// [`object::Object::exports`]. This does not distinguish between which section the symbols appear
@@ -14,47 +15,180 @@ pub fn exported_dynamic_symbol_names<'file>(file: &'file object::File<'file>) ->
         .collect()
 }
 
-/// Iterate through the symbols in an object file. See [`object::Object::symbols`].
+/// Check an object file's symbols for any matching **substrings**. That is, if an object file
+/// contains a symbol named `hello_world`, it will be matched against a provided `substrings` of
+/// `["hello", "bar"]`.
+///
+/// Returns `true` if **any** of the symbols found in the object file at `path` contain a
+/// **substring** listed in `substrings`.
 ///
 /// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
 /// parsed as a recognized object file.
+///
+/// # Platform-specific behavior
+///
+/// On Windows MSVC, the binary (e.g. `main.exe`) does not contain the symbols, but in the separate
+/// PDB file instead. Furthermore, you will need to use [`crate::llvm::llvm_pdbutil`] as `object`
+/// crate does not handle PDB files.
 #[track_caller]
-pub fn with_symbol_iter<P, F, R>(path: P, func: F) -> R
+pub fn object_contains_any_symbol_substring<P, S>(path: P, substrings: &[S]) -> bool
 where
     P: AsRef<Path>,
-    F: FnOnce(&mut SymbolIterator<'_, '_>) -> R,
+    S: AsRef<str>,
 {
     let path = path.as_ref();
     let blob = crate::fs::read(path);
-    let f = object::File::parse(&*blob)
+    let obj = object::File::parse(&*blob)
         .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display()));
-    let mut iter = f.symbols();
-    func(&mut iter)
+    let substrings = substrings.iter().map(|s| s.as_ref()).collect::<Vec<_>>();
+    for sym in obj.symbols() {
+        for substring in &substrings {
+            if sym.name_bytes().unwrap().windows(substring.len()).any(|x| x == substring.as_bytes())
+            {
+                return true;
+            }
+        }
+    }
+    false
 }
 
-/// Check an object file's symbols for substrings.
+/// Check an object file's symbols for any exact matches against those provided in
+/// `candidate_symbols`.
 ///
-/// Returns `true` if any of the symbols found in the object file at `path` contain a substring
-/// listed in `substrings`.
+/// Returns `true` if **any** of the symbols found in the object file at `path` contain an **exact
+/// match** against those listed in `candidate_symbols`. Take care to account for (1) platform
+/// differences and (2) calling convention and symbol decorations differences.
 ///
 /// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
 /// parsed as a recognized object file.
+///
+/// # Platform-specific behavior
+///
+/// See [`object_contains_any_symbol_substring`].
 #[track_caller]
-pub fn any_symbol_contains(path: impl AsRef<Path>, substrings: &[&str]) -> bool {
-    with_symbol_iter(path, |syms| {
-        for sym in syms {
-            for substring in substrings {
-                if sym
-                    .name_bytes()
-                    .unwrap()
-                    .windows(substring.len())
-                    .any(|x| x == substring.as_bytes())
-                {
-                    eprintln!("{:?} contains {}", sym, substring);
-                    return true;
-                }
+pub fn object_contains_any_symbol<P, S>(path: P, candidate_symbols: &[S]) -> bool
+where
+    P: AsRef<Path>,
+    S: AsRef<str>,
+{
+    let path = path.as_ref();
+    let blob = crate::fs::read(path);
+    let obj = object::File::parse(&*blob)
+        .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display()));
+    let candidate_symbols = candidate_symbols.iter().map(|s| s.as_ref()).collect::<Vec<_>>();
+    for sym in obj.symbols() {
+        for candidate_symbol in &candidate_symbols {
+            if sym.name_bytes().unwrap() == candidate_symbol.as_bytes() {
+                return true;
             }
         }
-        false
-    })
+    }
+    false
+}
+
+#[derive(Debug, PartialEq)]
+pub enum ContainsAllSymbolSubstringsOutcome<'a> {
+    Ok,
+    MissingSymbolSubstrings(BTreeSet<&'a str>),
+}
+
+/// Check an object file's symbols for presence of all of provided **substrings**. That is, if an
+/// object file contains symbols `["hello", "goodbye", "world"]`, it will be matched against a list
+/// of `substrings` of `["he", "go"]`. In this case, `he` is a substring of `hello`, and `go` is a
+/// substring of `goodbye`, so each of `substrings` was found.
+///
+/// Returns `true` if **all** `substrings` were present in the names of symbols for the given object
+/// file (as substrings of symbol names).
+///
+/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
+/// parsed as a recognized object file.
+///
+/// # Platform-specific behavior
+///
+/// See [`object_contains_any_symbol_substring`].
+#[track_caller]
+pub fn object_contains_all_symbol_substring<'s, P, S>(
+    path: P,
+    substrings: &'s [S],
+) -> ContainsAllSymbolSubstringsOutcome<'s>
+where
+    P: AsRef<Path>,
+    S: AsRef<str>,
+{
+    let path = path.as_ref();
+    let blob = crate::fs::read(path);
+    let obj = object::File::parse(&*blob)
+        .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display()));
+    let substrings = substrings.iter().map(|s| s.as_ref());
+    let mut unmatched_symbol_substrings = BTreeSet::from_iter(substrings);
+    unmatched_symbol_substrings.retain(|unmatched_symbol_substring| {
+        for sym in obj.symbols() {
+            if sym
+                .name_bytes()
+                .unwrap()
+                .windows(unmatched_symbol_substring.len())
+                .any(|x| x == unmatched_symbol_substring.as_bytes())
+            {
+                return false;
+            }
+        }
+
+        true
+    });
+
+    if unmatched_symbol_substrings.is_empty() {
+        ContainsAllSymbolSubstringsOutcome::Ok
+    } else {
+        ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(unmatched_symbol_substrings)
+    }
+}
+
+#[derive(Debug, PartialEq)]
+pub enum ContainsAllSymbolsOutcome<'a> {
+    Ok,
+    MissingSymbols(BTreeSet<&'a str>),
+}
+
+/// Check an object file contains all symbols provided in `candidate_symbols`.
+///
+/// Returns `true` if **all** of the symbols in `candidate_symbols` are found within the object file
+/// at `path` by **exact match**. Take care to account for (1) platform differences and (2) calling
+/// convention and symbol decorations differences.
+///
+/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
+/// parsed as a recognized object file.
+///
+/// # Platform-specific behavior
+///
+/// See [`object_contains_any_symbol_substring`].
+#[track_caller]
+pub fn object_contains_all_symbols<P, S>(
+    path: P,
+    candidate_symbols: &[S],
+) -> ContainsAllSymbolsOutcome<'_>
+where
+    P: AsRef<Path>,
+    S: AsRef<str>,
+{
+    let path = path.as_ref();
+    let blob = crate::fs::read(path);
+    let obj = object::File::parse(&*blob)
+        .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display()));
+    let candidate_symbols = candidate_symbols.iter().map(|s| s.as_ref());
+    let mut unmatched_symbols = BTreeSet::from_iter(candidate_symbols);
+    unmatched_symbols.retain(|unmatched_symbol| {
+        for sym in obj.symbols() {
+            if sym.name_bytes().unwrap() == unmatched_symbol.as_bytes() {
+                return false;
+            }
+        }
+
+        true
+    });
+
+    if unmatched_symbols.is_empty() {
+        ContainsAllSymbolsOutcome::Ok
+    } else {
+        ContainsAllSymbolsOutcome::MissingSymbols(unmatched_symbols)
+    }
 }
diff --git a/src/tools/suggest-tests/Cargo.toml b/src/tools/suggest-tests/Cargo.toml
deleted file mode 100644
index d6f86078d7e..00000000000
--- a/src/tools/suggest-tests/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "suggest-tests"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-glob = "0.3.0"
-build_helper = { version = "0.1.0", path = "../../build_helper" }
diff --git a/src/tools/suggest-tests/src/dynamic_suggestions.rs b/src/tools/suggest-tests/src/dynamic_suggestions.rs
deleted file mode 100644
index f09720f1c91..00000000000
--- a/src/tools/suggest-tests/src/dynamic_suggestions.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use std::path::Path;
-
-use crate::Suggestion;
-
-type DynamicSuggestion = fn(&Path) -> Vec<Suggestion>;
-
-pub(crate) const DYNAMIC_SUGGESTIONS: &[DynamicSuggestion] = &[
-    |path: &Path| -> Vec<Suggestion> {
-        if path.starts_with("compiler/") || path.starts_with("library/") {
-            let path = path.components().take(2).collect::<Vec<_>>();
-
-            vec![Suggestion::with_single_path(
-                "test",
-                None,
-                &format!(
-                    "{}/{}",
-                    path[0].as_os_str().to_str().unwrap(),
-                    path[1].as_os_str().to_str().unwrap()
-                ),
-            )]
-        } else {
-            Vec::new()
-        }
-    },
-    |path: &Path| -> Vec<Suggestion> {
-        if path.starts_with("compiler/rustc_pattern_analysis") {
-            vec![Suggestion::new("test", None, &["tests/ui", "--test-args", "pattern"])]
-        } else {
-            Vec::new()
-        }
-    },
-];
diff --git a/src/tools/suggest-tests/src/lib.rs b/src/tools/suggest-tests/src/lib.rs
deleted file mode 100644
index cc1288c6b72..00000000000
--- a/src/tools/suggest-tests/src/lib.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-use std::fmt::{self, Display};
-use std::path::Path;
-
-use dynamic_suggestions::DYNAMIC_SUGGESTIONS;
-use glob::Pattern;
-use static_suggestions::static_suggestions;
-
-mod dynamic_suggestions;
-mod static_suggestions;
-
-#[cfg(test)]
-mod tests;
-
-macro_rules! sug {
-    ($cmd:expr) => {
-        Suggestion::new($cmd, None, &[])
-    };
-
-    ($cmd:expr, $paths:expr) => {
-        Suggestion::new($cmd, None, $paths.as_slice())
-    };
-
-    ($cmd:expr, $stage:expr, $paths:expr) => {
-        Suggestion::new($cmd, Some($stage), $paths.as_slice())
-    };
-}
-
-pub(crate) use sug;
-
-pub fn get_suggestions<T: AsRef<str>>(modified_files: &[T]) -> Vec<Suggestion> {
-    let mut suggestions = Vec::new();
-
-    // static suggestions
-    for (globs, sugs) in static_suggestions().iter() {
-        let globs = globs
-            .iter()
-            .map(|glob| Pattern::new(glob).expect("Found invalid glob pattern!"))
-            .collect::<Vec<_>>();
-        let matches_some_glob = |file: &str| globs.iter().any(|glob| glob.matches(file));
-
-        if modified_files.iter().map(AsRef::as_ref).any(matches_some_glob) {
-            suggestions.extend_from_slice(sugs);
-        }
-    }
-
-    // dynamic suggestions
-    for sug in DYNAMIC_SUGGESTIONS {
-        for file in modified_files {
-            let sugs = sug(Path::new(file.as_ref()));
-
-            suggestions.extend_from_slice(&sugs);
-        }
-    }
-
-    suggestions.sort();
-    suggestions.dedup();
-
-    suggestions
-}
-
-#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Debug)]
-pub struct Suggestion {
-    pub cmd: String,
-    pub stage: Option<u32>,
-    pub paths: Vec<String>,
-}
-
-impl Suggestion {
-    pub fn new(cmd: &str, stage: Option<u32>, paths: &[&str]) -> Self {
-        Self { cmd: cmd.to_owned(), stage, paths: paths.iter().map(|p| p.to_string()).collect() }
-    }
-
-    pub fn with_single_path(cmd: &str, stage: Option<u32>, path: &str) -> Self {
-        Self::new(cmd, stage, &[path])
-    }
-}
-
-impl Display for Suggestion {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        write!(f, "{} ", self.cmd)?;
-
-        for path in &self.paths {
-            write!(f, "{} ", path)?;
-        }
-
-        if let Some(stage) = self.stage {
-            write!(f, "{}", stage)?;
-        } else {
-            // write a sentinel value here (in place of a stage) to be consumed
-            // by the shim in bootstrap, it will be read and ignored.
-            write!(f, "N/A")?;
-        }
-
-        Ok(())
-    }
-}
diff --git a/src/tools/suggest-tests/src/main.rs b/src/tools/suggest-tests/src/main.rs
deleted file mode 100644
index d84f8e9fa1b..00000000000
--- a/src/tools/suggest-tests/src/main.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use std::process::ExitCode;
-
-use build_helper::git::{GitConfig, get_git_modified_files};
-use suggest_tests::get_suggestions;
-
-fn main() -> ExitCode {
-    let modified_files = get_git_modified_files(
-        &GitConfig {
-            nightly_branch: &env("SUGGEST_TESTS_NIGHTLY_BRANCH"),
-            git_merge_commit_email: &env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL"),
-        },
-        None,
-        &Vec::new(),
-    );
-    let modified_files = match modified_files {
-        Ok(files) => files,
-        Err(err) => {
-            eprintln!("Could not get modified files from git: \"{err}\"");
-            return ExitCode::FAILURE;
-        }
-    };
-
-    let suggestions = get_suggestions(&modified_files);
-
-    for sug in &suggestions {
-        println!("{sug}");
-    }
-
-    ExitCode::SUCCESS
-}
-
-fn env(key: &str) -> String {
-    match std::env::var(key) {
-        Ok(var) => var,
-        Err(err) => {
-            eprintln!("suggest-tests: failed to read environment variable {key}: {err}");
-            std::process::exit(1);
-        }
-    }
-}
diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs
deleted file mode 100644
index d363d583b54..00000000000
--- a/src/tools/suggest-tests/src/static_suggestions.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use std::sync::OnceLock;
-
-use crate::{Suggestion, sug};
-
-// FIXME: perhaps this could use `std::lazy` when it is stabilized
-macro_rules! static_suggestions {
-    ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => {
-        pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec<Suggestion>)]
-        {
-            static S: OnceLock<Vec<(Vec<&'static str>, Vec<Suggestion>)>> = OnceLock::new();
-            S.get_or_init(|| vec![ $( (vec![ $($glob),* ], vec![ $($suggestion),* ]) ),*])
-        }
-    }
-}
-
-static_suggestions! {
-    ["*.md"] => [
-        sug!("test", 0, ["linkchecker"]),
-    ],
-
-    ["compiler/*"] => [
-        sug!("check"),
-        sug!("test", 1, ["tests/ui", "tests/run-make"]),
-    ],
-
-    ["compiler/rustc_mir_transform/*"] => [
-        sug!("test", 1, ["mir-opt"]),
-    ],
-
-    [
-        "compiler/rustc_mir_transform/src/coverage/*",
-        "compiler/rustc_codegen_llvm/src/coverageinfo/*",
-    ] => [
-        sug!("test", 1, ["coverage"]),
-    ],
-
-    ["src/librustdoc/*"] => [
-        sug!("test", 1, ["rustdoc"]),
-    ],
-}
diff --git a/src/tools/suggest-tests/src/tests.rs b/src/tools/suggest-tests/src/tests.rs
deleted file mode 100644
index b4149136fa3..00000000000
--- a/src/tools/suggest-tests/src/tests.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-macro_rules! sugg_test {
-    ( $( $name:ident: $paths:expr => $suggestions:expr ),* ) => {
-        $(
-            #[test]
-            fn $name() {
-                let suggestions = crate::get_suggestions(&$paths).into_iter().map(|s| s.to_string()).collect::<Vec<_>>();
-                assert_eq!(suggestions, $suggestions);
-            }
-        )*
-    };
-}
-
-sugg_test! {
-    test_error_code_docs: ["compiler/rustc_error_codes/src/error_codes/E0000.md"] =>
-        ["check N/A", "test compiler/rustc_error_codes N/A", "test linkchecker 0", "test tests/ui tests/run-make 1"],
-
-    test_rustdoc: ["src/librustdoc/src/lib.rs"] => ["test rustdoc 1"],
-
-    test_rustdoc_and_libstd: ["src/librustdoc/src/lib.rs", "library/std/src/lib.rs"] =>
-        ["test library/std N/A", "test rustdoc 1"]
-}
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index cac4dba2b49..8b57db23d01 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2338,7 +2338,6 @@ ui/issues/issue-50415.rs
 ui/issues/issue-50442.rs
 ui/issues/issue-50471.rs
 ui/issues/issue-50518.rs
-ui/issues/issue-50571.rs
 ui/issues/issue-50581.rs
 ui/issues/issue-50582.rs
 ui/issues/issue-50585.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index b1ace74e5bd..7e295731c56 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use ignore::Walk;
 const ENTRY_LIMIT: u32 = 901;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1619;
+const ISSUES_ENTRY_LIMIT: u32 = 1616;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs b/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs
new file mode 100644
index 00000000000..73826214aac
--- /dev/null
+++ b/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs
@@ -0,0 +1,92 @@
+//! `run_make_support::symbols` helpers self test.
+
+// Only intended as a basic smoke test, does not try to account for platform or calling convention
+// specific symbol decorations.
+//@ only-x86_64-unknown-linux-gnu
+//@ ignore-cross-compile
+
+use std::collections::BTreeSet;
+
+use object::{Object, ObjectSymbol};
+use run_make_support::symbols::{
+    ContainsAllSymbolSubstringsOutcome, ContainsAllSymbolsOutcome,
+    object_contains_all_symbol_substring, object_contains_all_symbols, object_contains_any_symbol,
+    object_contains_any_symbol_substring,
+};
+use run_make_support::{object, rfs, rust_lib_name, rustc};
+
+fn main() {
+    rustc().input("sample.rs").emit("obj").edition("2024").run();
+
+    // `sample.rs` has two `no_mangle` functions, `eszett` and `beta`, in addition to `main`.
+    //
+    // These two symbol names and the test substrings used below are carefully picked to make sure
+    // they do not overlap with `sample` and contain non-hex characters, to avoid accidentally
+    // matching against CGU names like `sample.dad0f15d00c84e70-cgu.0`.
+
+    let obj_filename = "sample.o";
+    let blob = rfs::read(obj_filename);
+    let obj = object::File::parse(&*blob).unwrap();
+    eprintln!("found symbols:");
+    for sym in obj.symbols() {
+        eprintln!("symbol = {}", sym.name().unwrap());
+    }
+
+    // `hello` contains `hel`
+    assert!(object_contains_any_symbol_substring(obj_filename, &["zett"]));
+    assert!(object_contains_any_symbol_substring(obj_filename, &["zett", "does_not_exist"]));
+    assert!(!object_contains_any_symbol_substring(obj_filename, &["does_not_exist"]));
+
+    assert!(object_contains_any_symbol(obj_filename, &["eszett"]));
+    assert!(object_contains_any_symbol(obj_filename, &["eszett", "beta"]));
+    assert!(!object_contains_any_symbol(obj_filename, &["zett"]));
+    assert!(!object_contains_any_symbol(obj_filename, &["does_not_exist"]));
+
+    assert_eq!(
+        object_contains_all_symbol_substring(obj_filename, &["zett"]),
+        ContainsAllSymbolSubstringsOutcome::Ok
+    );
+    assert_eq!(
+        object_contains_all_symbol_substring(obj_filename, &["zett", "bet"]),
+        ContainsAllSymbolSubstringsOutcome::Ok
+    );
+    assert_eq!(
+        object_contains_all_symbol_substring(obj_filename, &["does_not_exist"]),
+        ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([
+            "does_not_exist"
+        ]))
+    );
+    assert_eq!(
+        object_contains_all_symbol_substring(obj_filename, &["zett", "does_not_exist"]),
+        ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([
+            "does_not_exist"
+        ]))
+    );
+    assert_eq!(
+        object_contains_all_symbol_substring(obj_filename, &["zett", "bet", "does_not_exist"]),
+        ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([
+            "does_not_exist"
+        ]))
+    );
+
+    assert_eq!(
+        object_contains_all_symbols(obj_filename, &["eszett"]),
+        ContainsAllSymbolsOutcome::Ok
+    );
+    assert_eq!(
+        object_contains_all_symbols(obj_filename, &["eszett", "beta"]),
+        ContainsAllSymbolsOutcome::Ok
+    );
+    assert_eq!(
+        object_contains_all_symbols(obj_filename, &["zett"]),
+        ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["zett"]))
+    );
+    assert_eq!(
+        object_contains_all_symbols(obj_filename, &["zett", "beta"]),
+        ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["zett"]))
+    );
+    assert_eq!(
+        object_contains_all_symbols(obj_filename, &["does_not_exist"]),
+        ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["does_not_exist"]))
+    );
+}
diff --git a/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs b/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs
new file mode 100644
index 00000000000..3566d299766
--- /dev/null
+++ b/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs
@@ -0,0 +1,13 @@
+#![crate_type = "lib"]
+
+#[unsafe(no_mangle)]
+pub extern "C" fn eszett() -> i8 {
+    42
+}
+
+#[unsafe(no_mangle)]
+pub extern "C" fn beta() -> u32 {
+    1
+}
+
+fn main() {}
diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs
index af6ff6c2983..b7f18b384cb 100644
--- a/tests/run-make/fmt-write-bloat/rmake.rs
+++ b/tests/run-make/fmt-write-bloat/rmake.rs
@@ -20,7 +20,7 @@
 use run_make_support::artifact_names::bin_name;
 use run_make_support::env::std_debug_assertions_enabled;
 use run_make_support::rustc;
-use run_make_support::symbols::any_symbol_contains;
+use run_make_support::symbols::object_contains_any_symbol_substring;
 
 fn main() {
     rustc().input("main.rs").opt().run();
@@ -31,5 +31,5 @@ fn main() {
         // otherwise, add them to the list of symbols to deny.
         panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]);
     }
-    assert!(!any_symbol_contains(bin_name("main"), &panic_syms));
+    assert!(!object_contains_any_symbol_substring(bin_name("main"), &panic_syms));
 }
diff --git a/tests/run-make/used/rmake.rs b/tests/run-make/used/rmake.rs
index bcdb84132d3..456321e2f56 100644
--- a/tests/run-make/used/rmake.rs
+++ b/tests/run-make/used/rmake.rs
@@ -8,9 +8,9 @@
 // https://rust-lang.github.io/rfcs/2386-used.html
 
 use run_make_support::rustc;
-use run_make_support::symbols::any_symbol_contains;
+use run_make_support::symbols::object_contains_any_symbol_substring;
 
 fn main() {
     rustc().opt_level("3").emit("obj").input("used.rs").run();
-    assert!(any_symbol_contains("used.o", &["FOO"]));
+    assert!(object_contains_any_symbol_substring("used.o", &["FOO"]));
 }
diff --git a/tests/ui/codegen/duplicated-path-in-error.stderr b/tests/ui/codegen/duplicated-path-in-error.gnu.stderr
index d0d34e2f934..d0d34e2f934 100644
--- a/tests/ui/codegen/duplicated-path-in-error.stderr
+++ b/tests/ui/codegen/duplicated-path-in-error.gnu.stderr
diff --git a/tests/ui/codegen/duplicated-path-in-error.musl.stderr b/tests/ui/codegen/duplicated-path-in-error.musl.stderr
new file mode 100644
index 00000000000..2892ebffdde
--- /dev/null
+++ b/tests/ui/codegen/duplicated-path-in-error.musl.stderr
@@ -0,0 +1,2 @@
+error: couldn't load codegen backend /non-existing-one.so: Error loading shared library /non-existing-one.so: No such file or directory
+
diff --git a/tests/ui/codegen/duplicated-path-in-error.rs b/tests/ui/codegen/duplicated-path-in-error.rs
index a446395de20..fed93828ee2 100644
--- a/tests/ui/codegen/duplicated-path-in-error.rs
+++ b/tests/ui/codegen/duplicated-path-in-error.rs
@@ -1,8 +1,15 @@
+//@ revisions: musl gnu
 //@ only-linux
+//@ ignore-cross-compile because this relies on host libc behaviour
 //@ compile-flags: -Zcodegen-backend=/non-existing-one.so
+//@[gnu] only-gnu
+//@[musl] only-musl
 
 // This test ensures that the error of the "not found dylib" doesn't duplicate
 // the path of the dylib.
+//
+// glibc and musl have different dlopen error messages, so the expected error
+// message differs between the two.
 
 fn main() {}
 
diff --git a/tests/ui/consts/const_transmute_type_id3.rs b/tests/ui/consts/const_transmute_type_id3.rs
index ed5ff769701..f1bb8cddf77 100644
--- a/tests/ui/consts/const_transmute_type_id3.rs
+++ b/tests/ui/consts/const_transmute_type_id3.rs
@@ -1,3 +1,6 @@
+//! Test that all bytes of a TypeId must have the
+//! TypeId marker provenance.
+
 #![feature(const_type_id, const_trait_impl, const_cmp)]
 
 use std::any::TypeId;
@@ -10,7 +13,7 @@ const _: () = {
         std::ptr::write(ptr.offset(1), 999);
     }
     assert!(a == b);
-    //~^ ERROR: one of the TypeId arguments is invalid, the hash does not match the type it represents
+    //~^ ERROR: pointer must point to some allocation
 };
 
 fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr
index 8cfdcfebaa4..e731f496652 100644
--- a/tests/ui/consts/const_transmute_type_id3.stderr
+++ b/tests/ui/consts/const_transmute_type_id3.stderr
@@ -1,5 +1,5 @@
-error[E0080]: type_id_eq: one of the TypeId arguments is invalid, the hash does not match the type it represents
-  --> $DIR/const_transmute_type_id3.rs:12:13
+error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got 0x3e7[noalloc] which is a dangling pointer (it has no provenance)
+  --> $DIR/const_transmute_type_id3.rs:15:13
    |
 LL |     assert!(a == b);
    |             ^^^^^^ evaluation of `_` failed inside this call
diff --git a/tests/ui/consts/const_transmute_type_id5.rs b/tests/ui/consts/const_transmute_type_id5.rs
new file mode 100644
index 00000000000..0a9ba01e0dd
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id5.rs
@@ -0,0 +1,21 @@
+//! Test that we require an equal TypeId to have the same integer
+//! part, even if the provenance matches.
+
+#![feature(const_type_id, const_trait_impl, const_cmp)]
+
+use std::any::TypeId;
+
+const _: () = {
+    let a = TypeId::of::<()>();
+    let mut b = TypeId::of::<()>();
+    unsafe {
+        let ptr = &mut b as *mut TypeId as *mut *const ();
+        // Copy the ptr at index 0 to index 1
+        let val = std::ptr::read(ptr);
+        std::ptr::write(ptr.offset(1), val);
+    }
+    assert!(a == b);
+    //~^ ERROR: type_id_eq: one of the TypeId arguments is invalid, chunk 1 of the hash does not match the type it represents
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const_transmute_type_id5.stderr b/tests/ui/consts/const_transmute_type_id5.stderr
new file mode 100644
index 00000000000..59823fcc1c9
--- /dev/null
+++ b/tests/ui/consts/const_transmute_type_id5.stderr
@@ -0,0 +1,15 @@
+error[E0080]: type_id_eq: one of the TypeId arguments is invalid, chunk 1 of the hash does not match the type it represents
+  --> $DIR/const_transmute_type_id5.rs:17:13
+   |
+LL |     assert!(a == b);
+   |             ^^^^^^ evaluation of `_` failed inside this call
+   |
+note: inside `<TypeId as PartialEq>::eq`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+note: inside `<TypeId as PartialEq>::eq::compiletime`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/issues/issue-50571.fixed b/tests/ui/issues/issue-50571.fixed
deleted file mode 100644
index 6d73f17cca4..00000000000
--- a/tests/ui/issues/issue-50571.fixed
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ edition: 2015
-//@ run-rustfix
-
-#![allow(dead_code)]
-trait Foo {
-    fn foo(_: [i32; 2]) {}
-    //~^ ERROR: patterns aren't allowed in methods without bodies
-}
-
-fn main() {}
diff --git a/tests/ui/issues/issue-50571.rs b/tests/ui/issues/issue-50571.rs
deleted file mode 100644
index dd840ffe4d1..00000000000
--- a/tests/ui/issues/issue-50571.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ edition: 2015
-//@ run-rustfix
-
-#![allow(dead_code)]
-trait Foo {
-    fn foo([a, b]: [i32; 2]) {}
-    //~^ ERROR: patterns aren't allowed in methods without bodies
-}
-
-fn main() {}
diff --git a/tests/ui/issues/issue-50571.stderr b/tests/ui/issues/issue-50571.stderr
deleted file mode 100644
index 9b00fe0f5db..00000000000
--- a/tests/ui/issues/issue-50571.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/issue-50571.rs:6:12
-   |
-LL |     fn foo([a, b]: [i32; 2]) {}
-   |            ^^^^^^
-   |
-help: give this argument a name or use an underscore to ignore it
-   |
-LL -     fn foo([a, b]: [i32; 2]) {}
-LL +     fn foo(_: [i32; 2]) {}
-   |
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0642`.
diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs
index a4d94836a09..461d2e0e8c1 100644
--- a/tests/ui/macros/cfg_select.rs
+++ b/tests/ui/macros/cfg_select.rs
@@ -18,10 +18,13 @@ fn arm_rhs_must_be_in_braces() -> i32 {
 cfg_select! {
     _ => {}
     true => {}
-    //~^ WARN unreachable rule
+    //~^ WARN unreachable predicate
 }
 
 cfg_select! {
-    //~^ ERROR none of the rules in this `cfg_select` evaluated to true
+    //~^ ERROR none of the predicates in this `cfg_select` evaluated to true
     false => {}
 }
+
+cfg_select! {}
+//~^ ERROR none of the predicates in this `cfg_select` evaluated to true
diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr
index fef5e95a6bc..6c18a7c189d 100644
--- a/tests/ui/macros/cfg_select.stderr
+++ b/tests/ui/macros/cfg_select.stderr
@@ -4,15 +4,15 @@ error: expected `{`, found `1`
 LL |         true => 1
    |                 ^ expected `{`
 
-warning: unreachable rule
+warning: unreachable predicate
   --> $DIR/cfg_select.rs:20:5
    |
 LL |     _ => {}
    |     - always matches
 LL |     true => {}
-   |     ^^^^ this rules is never reached
+   |     ^^^^ this predicate is never reached
 
-error: none of the rules in this `cfg_select` evaluated to true
+error: none of the predicates in this `cfg_select` evaluated to true
   --> $DIR/cfg_select.rs:24:1
    |
 LL | / cfg_select! {
@@ -21,5 +21,11 @@ LL | |     false => {}
 LL | | }
    | |_^
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: none of the predicates in this `cfg_select` evaluated to true
+  --> $DIR/cfg_select.rs:29:1
+   |
+LL | cfg_select! {}
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
 
diff --git a/tests/ui/parser/better-expected.rs b/tests/ui/parser/better-expected.rs
index 16b61caa4df..91128c39691 100644
--- a/tests/ui/parser/better-expected.rs
+++ b/tests/ui/parser/better-expected.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
+    let x: [isize 3]; //~ ERROR expected `;` or `]`, found `3`
 }
diff --git a/tests/ui/parser/better-expected.stderr b/tests/ui/parser/better-expected.stderr
index f4ec933be16..4646ce7eff0 100644
--- a/tests/ui/parser/better-expected.stderr
+++ b/tests/ui/parser/better-expected.stderr
@@ -1,10 +1,14 @@
-error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
+error: expected `;` or `]`, found `3`
   --> $DIR/better-expected.rs:2:19
    |
 LL |     let x: [isize 3];
-   |          -        ^ expected one of 7 possible tokens
-   |          |
-   |          while parsing the type for `x`
+   |                   ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL |     let x: [isize ;3];
+   |                   +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/error-pattern-issue-50571.rs b/tests/ui/parser/issues/error-pattern-issue-50571.rs
new file mode 100644
index 00000000000..0c2ce6052cb
--- /dev/null
+++ b/tests/ui/parser/issues/error-pattern-issue-50571.rs
@@ -0,0 +1,11 @@
+// There is a regression introduced for issue #143828
+//@ edition: 2015
+
+#![allow(dead_code)]
+trait Foo {
+    fn foo([a, b]: [i32; 2]) {}
+    //~^ ERROR: expected `;` or `]`, found `,`
+    //~| ERROR: patterns aren't allowed in methods without bodies
+}
+
+fn main() {}
diff --git a/tests/ui/parser/issues/error-pattern-issue-50571.stderr b/tests/ui/parser/issues/error-pattern-issue-50571.stderr
new file mode 100644
index 00000000000..47457cff461
--- /dev/null
+++ b/tests/ui/parser/issues/error-pattern-issue-50571.stderr
@@ -0,0 +1,28 @@
+error: expected `;` or `]`, found `,`
+  --> $DIR/error-pattern-issue-50571.rs:6:14
+   |
+LL |     fn foo([a, b]: [i32; 2]) {}
+   |              ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL -     fn foo([a, b]: [i32; 2]) {}
+LL +     fn foo([a; b]: [i32; 2]) {}
+   |
+
+error[E0642]: patterns aren't allowed in methods without bodies
+  --> $DIR/error-pattern-issue-50571.rs:6:12
+   |
+LL |     fn foo([a, b]: [i32; 2]) {}
+   |            ^^^^^^
+   |
+help: give this argument a name or use an underscore to ignore it
+   |
+LL -     fn foo([a, b]: [i32; 2]) {}
+LL +     fn foo(_: [i32; 2]) {}
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0642`.
diff --git a/tests/ui/parser/recover/array-type-no-semi.rs b/tests/ui/parser/recover/array-type-no-semi.rs
new file mode 100644
index 00000000000..2cc5d979604
--- /dev/null
+++ b/tests/ui/parser/recover/array-type-no-semi.rs
@@ -0,0 +1,17 @@
+// when the next token is not a semicolon,
+// we should suggest to use semicolon if recovery is allowed
+// See issue #143828
+
+fn main() {
+    let x = 5;
+    let b: [i32, 5];
+    //~^ ERROR expected `;` or `]`, found `,`
+    let a: [i32, ];
+    //~^ ERROR expected `;` or `]`, found `,`
+    //~| ERROR expected value, found builtin type `i32` [E0423]
+    let c: [i32, x];
+    //~^ ERROR expected `;` or `]`, found `,`
+    //~| ERROR attempt to use a non-constant value in a constant [E0435]
+    let e: [i32 5];
+    //~^ ERROR expected `;` or `]`, found `5`
+}
diff --git a/tests/ui/parser/recover/array-type-no-semi.stderr b/tests/ui/parser/recover/array-type-no-semi.stderr
new file mode 100644
index 00000000000..82330465144
--- /dev/null
+++ b/tests/ui/parser/recover/array-type-no-semi.stderr
@@ -0,0 +1,71 @@
+error: expected `;` or `]`, found `,`
+  --> $DIR/array-type-no-semi.rs:7:16
+   |
+LL |     let b: [i32, 5];
+   |                ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL -     let b: [i32, 5];
+LL +     let b: [i32; 5];
+   |
+
+error: expected `;` or `]`, found `,`
+  --> $DIR/array-type-no-semi.rs:9:16
+   |
+LL |     let a: [i32, ];
+   |          -     ^ expected `;` or `]`
+   |          |
+   |          while parsing the type for `a`
+   |          help: use `=` if you meant to assign
+   |
+   = note: you might have meant to write a slice or array type
+
+error: expected `;` or `]`, found `,`
+  --> $DIR/array-type-no-semi.rs:12:16
+   |
+LL |     let c: [i32, x];
+   |                ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL -     let c: [i32, x];
+LL +     let c: [i32; x];
+   |
+
+error: expected `;` or `]`, found `5`
+  --> $DIR/array-type-no-semi.rs:15:17
+   |
+LL |     let e: [i32 5];
+   |                 ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL |     let e: [i32 ;5];
+   |                 +
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/array-type-no-semi.rs:12:18
+   |
+LL |     let c: [i32, x];
+   |                  ^ non-constant value
+   |
+help: consider using `const` instead of `let`
+   |
+LL -     let x = 5;
+LL +     const x: /* Type */ = 5;
+   |
+
+error[E0423]: expected value, found builtin type `i32`
+  --> $DIR/array-type-no-semi.rs:9:13
+   |
+LL |     let a: [i32, ];
+   |             ^^^ not a value
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0423, E0435.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs
index 560efecb91c..fb9a1c643fc 100644
--- a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs
+++ b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs
@@ -1 +1,6 @@
-type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
+type v = [isize * 3];
+//~^ ERROR expected `;` or `]`, found `*`
+//~| WARN type `v` should have an upper camel case name [non_camel_case_types]
+
+
+fn main() {}
diff --git a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr
index 5bc9c2ccf00..8d7938a1a46 100644
--- a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr
+++ b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr
@@ -1,8 +1,23 @@
-error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
+error: expected `;` or `]`, found `*`
   --> $DIR/removed-syntax-fixed-vec.rs:1:17
    |
 LL | type v = [isize * 3];
-   |                 ^ expected one of 7 possible tokens
+   |                 ^ expected `;` or `]`
+   |
+   = note: you might have meant to write a slice or array type
+help: you might have meant to use `;` as the separator
+   |
+LL - type v = [isize * 3];
+LL + type v = [isize ; 3];
+   |
+
+warning: type `v` should have an upper camel case name
+  --> $DIR/removed-syntax-fixed-vec.rs:1:6
+   |
+LL | type v = [isize * 3];
+   |      ^ help: convert the identifier to upper camel case (notice the capitalization): `V`
+   |
+   = note: `#[warn(non_camel_case_types)]` on by default
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
index ece87529c3e..1d1da9b0e3d 100644
--- a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs
@@ -14,5 +14,7 @@ fn main() {
 trait NonConst {}
 const fn handle(_: &dyn const NonConst) {}
 //~^ ERROR const trait bounds are not allowed in trait object types
+//~| ERROR `const` can only be applied to `#[const_trait]` traits
 const fn take(_: &dyn [const] NonConst) {}
 //~^ ERROR `[const]` is not allowed here
+//~| ERROR `[const]` can only be applied to `#[const_trait]` traits
diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
index 090555c6377..06e0493024c 100644
--- a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
+++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr
@@ -19,12 +19,34 @@ LL | const fn handle(_: &dyn const NonConst) {}
    |                         ^^^^^^^^^^^^^^
 
 error: `[const]` is not allowed here
-  --> $DIR/const-trait-bounds-trait-objects.rs:17:23
+  --> $DIR/const-trait-bounds-trait-objects.rs:18:23
    |
 LL | const fn take(_: &dyn [const] NonConst) {}
    |                       ^^^^^^^
    |
    = note: trait objects cannot have `[const]` trait bounds
 
-error: aborting due to 4 previous errors
+error: `const` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-trait-bounds-trait-objects.rs:15:25
+   |
+LL | const fn handle(_: &dyn const NonConst) {}
+   |                         ^^^^^ can't be applied to `NonConst`
+   |
+help: mark `NonConst` as `#[const_trait]` to allow it to have `const` implementations
+   |
+LL | #[const_trait] trait NonConst {}
+   | ++++++++++++++
+
+error: `[const]` can only be applied to `#[const_trait]` traits
+  --> $DIR/const-trait-bounds-trait-objects.rs:18:23
+   |
+LL | const fn take(_: &dyn [const] NonConst) {}
+   |                       ^^^^^^^ can't be applied to `NonConst`
+   |
+help: mark `NonConst` as `#[const_trait]` to allow it to have `const` implementations
+   |
+LL | #[const_trait] trait NonConst {}
+   | ++++++++++++++
+
+error: aborting due to 6 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 75e794c700d..2f8114aeb3b 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -506,7 +506,6 @@ trigger_files = [
     "src/tools/remote-test-server",
     "src/tools/remote-test-client",
     "src/tools/rustdoc-gui-test",
-    "src/tools/suggest-tests",
 ]
 
 [autolabel."A-tidy"]