about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-22 13:05:31 +0000
committerbors <bors@rust-lang.org>2024-06-22 13:05:31 +0000
commitac47dbad504b892bc0f3be8fa097537c6e0544a3 (patch)
tree4cefb49e7b94fed6b1922a19f2778d9a1e9cbd0d
parentd03d6c0fead582c98c6446ec92456ca8fd03ff65 (diff)
parentd265538016883df447b7335abcb83ccfa97d63cb (diff)
downloadrust-ac47dbad504b892bc0f3be8fa097537c6e0544a3.tar.gz
rust-ac47dbad504b892bc0f3be8fa097537c6e0544a3.zip
Auto merge of #126824 - GuillaumeGomez:rollup-sybv8o7, r=GuillaumeGomez
Rollup of 5 pull requests

Successful merges:

 - #126555 (Add `f16` inline ASM support for 32-bit ARM)
 - #126686 (Add `#[rustc_dump_{predicates,item_bounds}]`)
 - #126723 (Fix `...` in multline code-skips in suggestions)
 - #126731 (Bootstrap command refactoring: refactor `BootstrapCommand` (step 1))
 - #126823 (Migrate `run-make/inline-always-many-cgu` to `rmake.rs`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs39
-rw-r--r--compiler/rustc_errors/src/emitter.rs4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs8
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/dump.rs43
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/dump.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/mod.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/test.rs31
-rw-r--r--compiler/rustc_hir_analysis/src/variance/dump.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/variance/test.rs37
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/asm/arm.rs12
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs43
-rw-r--r--src/bootstrap/src/lib.rs127
-rw-r--r--src/bootstrap/src/utils/exec.rs67
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr2
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/assembly/asm/arm-types.rs497
-rw-r--r--tests/run-make/inline-always-many-cgu/Makefile8
-rw-r--r--tests/run-make/inline-always-many-cgu/rmake.rs18
-rw-r--r--tests/ui/attributes/dump-preds.rs20
-rw-r--r--tests/ui/attributes/dump-preds.stderr39
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr4
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr2
-rw-r--r--tests/ui/imports/issue-59764.stderr2
-rw-r--r--tests/ui/issues/issue-22644.stderr2
-rw-r--r--tests/ui/issues/issue-57271.stderr2
-rw-r--r--tests/ui/let-else/let-else-if.stderr2
-rw-r--r--tests/ui/loops/loop-else-break-with-value.stderr2
-rw-r--r--tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr4
-rw-r--r--tests/ui/parser/recover/recover-labeled-non-block-expr.stderr2
-rw-r--r--tests/ui/span/recursive-type-field.stderr2
-rw-r--r--tests/ui/suggestions/issue-68049-2.stderr2
-rw-r--r--tests/ui/try-trait/try-operator-on-main.stderr2
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr2
45 files changed, 723 insertions, 424 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 34a0f9973f6..597ebd97365 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -1037,6 +1037,19 @@ fn llvm_fixup_input<'ll, 'tcx>(
                 value
             }
         }
+        (
+            InlineAsmRegClass::Arm(
+                ArmInlineAsmRegClass::dreg
+                | ArmInlineAsmRegClass::dreg_low8
+                | ArmInlineAsmRegClass::dreg_low16
+                | ArmInlineAsmRegClass::qreg
+                | ArmInlineAsmRegClass::qreg_low4
+                | ArmInlineAsmRegClass::qreg_low8,
+            ),
+            Abi::Vector { element, count: count @ (4 | 8) },
+        ) if element.primitive() == Primitive::Float(Float::F16) => {
+            bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
+        }
         (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
@@ -1158,6 +1171,19 @@ fn llvm_fixup_output<'ll, 'tcx>(
                 value
             }
         }
+        (
+            InlineAsmRegClass::Arm(
+                ArmInlineAsmRegClass::dreg
+                | ArmInlineAsmRegClass::dreg_low8
+                | ArmInlineAsmRegClass::dreg_low16
+                | ArmInlineAsmRegClass::qreg
+                | ArmInlineAsmRegClass::qreg_low4
+                | ArmInlineAsmRegClass::qreg_low8,
+            ),
+            Abi::Vector { element, count: count @ (4 | 8) },
+        ) if element.primitive() == Primitive::Float(Float::F16) => {
+            bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
+        }
         (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
@@ -1270,6 +1296,19 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
                 layout.llvm_type(cx)
             }
         }
+        (
+            InlineAsmRegClass::Arm(
+                ArmInlineAsmRegClass::dreg
+                | ArmInlineAsmRegClass::dreg_low8
+                | ArmInlineAsmRegClass::dreg_low16
+                | ArmInlineAsmRegClass::qreg
+                | ArmInlineAsmRegClass::qreg_low4
+                | ArmInlineAsmRegClass::qreg_low8,
+            ),
+            Abi::Vector { element, count: count @ (4 | 8) },
+        ) if element.primitive() == Primitive::Float(Float::F16) => {
+            cx.type_vector(cx.type_i16(), count)
+        }
         (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 245deda50d5..7405705dd33 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1905,7 +1905,7 @@ impl HumanEmitter {
                     //
                     // LL | this line was highlighted
                     // LL | this line is just for context
-                    //   ...
+                    // ...
                     // LL | this line is just for context
                     // LL | this line was highlighted
                     _ => {
@@ -1926,7 +1926,7 @@ impl HumanEmitter {
                             )
                         }
 
-                        buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
+                        buffer.puts(row_num, 0, "...", Style::LineNumber);
                         row_num += 1;
 
                         if let Some((p, l)) = last_line {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index c165620f657..9e2756f07ed 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1089,6 +1089,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         "the `#[custom_mir]` attribute is just used for the Rust test suite",
     ),
     rustc_attr!(
+        TEST, rustc_dump_item_bounds, Normal, template!(Word),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    rustc_attr!(
+        TEST, rustc_dump_predicates, Normal, template!(Word),
+        WarnFollowing, EncodeCrossCrate::No
+    ),
+    rustc_attr!(
         TEST, rustc_object_lifetime_default, Normal, template!(Word),
         WarnFollowing, EncodeCrossCrate::No
     ),
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index ca653e50aab..7ed32fb9d9f 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -510,7 +510,7 @@ hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type
     .note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
     .only_note = only traits defined in the current crate can be implemented for a type parameter
 
-hir_analysis_type_of = {$type_of}
+hir_analysis_type_of = {$ty}
 
 hir_analysis_typeof_reserved_keyword_used =
     `typeof` is a reserved keyword but unimplemented
@@ -566,7 +566,7 @@ hir_analysis_value_of_associated_struct_already_specified =
 hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
     .label = C-variadic function must have a compatible calling convention
 
-hir_analysis_variances_of = {$variances_of}
+hir_analysis_variances_of = {$variances}
 
 hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
     .label = `main` cannot have a `where` clause
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index c6e8759327f..e5bd147352d 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -45,8 +45,8 @@ use std::ops::Bound;
 use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::errors;
 use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
-pub use type_of::test_opaque_hidden_types;
 
+pub(crate) mod dump;
 mod generics_of;
 mod item_bounds;
 mod predicates_of;
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
new file mode 100644
index 00000000000..85e1c600d6d
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -0,0 +1,43 @@
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::CRATE_DEF_ID;
+use rustc_middle::ty::TyCtxt;
+use rustc_span::sym;
+
+pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
+    if !tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
+        return;
+    }
+
+    for id in tcx.hir().items() {
+        let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
+
+        let ty = tcx.type_of(id.owner_id).instantiate_identity();
+
+        tcx.dcx().emit_err(crate::errors::TypeOf { span: tcx.def_span(id.owner_id), ty });
+    }
+}
+
+pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
+    for id in tcx.hir_crate_items(()).owners() {
+        if tcx.has_attr(id, sym::rustc_dump_predicates) {
+            let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates;
+            let span = tcx.def_span(id);
+
+            let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str());
+            for pred in preds {
+                diag.note(format!("{pred:?}"));
+            }
+            diag.emit();
+        }
+        if tcx.has_attr(id, sym::rustc_dump_item_bounds) {
+            let bounds = tcx.item_bounds(id).instantiate_identity();
+            let span = tcx.def_span(id);
+
+            let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_item_bounds.as_str());
+            for bound in bounds {
+                diag.note(format!("{bound:?}"));
+            }
+            diag.emit();
+        }
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 2684467a438..1e2b0c43233 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -15,7 +15,6 @@ use crate::errors::TypeofReservedKeywordUsed;
 
 use super::bad_placeholder;
 use super::ItemCtxt;
-pub use opaque::test_opaque_hidden_types;
 
 mod opaque;
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 2b2f07001d2..d1048b742a0 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -1,28 +1,14 @@
 use rustc_errors::StashKey;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
-use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
+use rustc_span::DUMMY_SP;
 
-use crate::errors::{TaitForwardCompat, TaitForwardCompat2, TypeOf, UnconstrainedOpaqueType};
-
-pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
-    let mut res = Ok(());
-    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_hidden_type_of_opaques) {
-        for id in tcx.hir().items() {
-            if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
-                let type_of = tcx.type_of(id.owner_id).instantiate_identity();
-
-                res = Err(tcx.dcx().emit_err(TypeOf { span: tcx.def_span(id.owner_id), type_of }));
-            }
-        }
-    }
-    res
-}
+use crate::errors::{TaitForwardCompat, TaitForwardCompat2, UnconstrainedOpaqueType};
 
 /// Checks "defining uses" of opaque `impl Trait` in associated types.
 /// These can only be defined by associated items of the same trait.
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index cff8d5a5ea5..44025c3cd61 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -682,7 +682,7 @@ pub(crate) enum CannotCaptureLateBound {
 pub(crate) struct VariancesOf {
     #[primary_span]
     pub span: Span,
-    pub variances_of: String,
+    pub variances: String,
 }
 
 #[derive(Diagnostic)]
@@ -690,7 +690,7 @@ pub(crate) struct VariancesOf {
 pub(crate) struct TypeOf<'tcx> {
     #[primary_span]
     pub span: Span,
-    pub type_of: Ty<'tcx>,
+    pub ty: Ty<'tcx>,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1927359421d..0428abcdf24 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -151,10 +151,6 @@ pub fn provide(providers: &mut Providers) {
 pub fn check_crate(tcx: TyCtxt<'_>) {
     let _prof_timer = tcx.sess.timer("type_check_crate");
 
-    if tcx.features().rustc_attrs {
-        let _ = tcx.sess.time("outlives_testing", || outlives::test::test_inferred_outlives(tcx));
-    }
-
     tcx.sess.time("coherence_checking", || {
         tcx.hir().par_for_each_module(|module| {
             let _ = tcx.ensure().check_mod_type_wf(module);
@@ -169,11 +165,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     });
 
     if tcx.features().rustc_attrs {
-        let _ = tcx.sess.time("variance_testing", || variance::test::test_variance(tcx));
-    }
-
-    if tcx.features().rustc_attrs {
-        let _ = collect::test_opaque_hidden_types(tcx);
+        tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
+        tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
+        collect::dump::opaque_hidden_types(tcx);
+        collect::dump::predicates_and_item_bounds(tcx);
     }
 
     // Make sure we evaluate all static and (non-associated) const items, even if unused.
diff --git a/compiler/rustc_hir_analysis/src/outlives/dump.rs b/compiler/rustc_hir_analysis/src/outlives/dump.rs
new file mode 100644
index 00000000000..ab50d9e86ef
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/outlives/dump.rs
@@ -0,0 +1,29 @@
+use rustc_middle::bug;
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::sym;
+
+pub(crate) fn inferred_outlives(tcx: TyCtxt<'_>) {
+    for id in tcx.hir().items() {
+        if !tcx.has_attr(id.owner_id, sym::rustc_outlives) {
+            continue;
+        }
+
+        let preds = tcx.inferred_outlives_of(id.owner_id);
+        let mut preds: Vec<_> = preds
+            .iter()
+            .map(|(pred, _)| match pred.kind().skip_binder() {
+                ty::ClauseKind::RegionOutlives(p) => p.to_string(),
+                ty::ClauseKind::TypeOutlives(p) => p.to_string(),
+                err => bug!("unexpected clause {:?}", err),
+            })
+            .collect();
+        preds.sort();
+
+        let span = tcx.def_span(id.owner_id);
+        let mut err = tcx.dcx().struct_span_err(span, sym::rustc_outlives.as_str());
+        for pred in preds {
+            err.note(pred);
+        }
+        err.emit();
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs
index 97fd7731b1e..1f74ebf99f1 100644
--- a/compiler/rustc_hir_analysis/src/outlives/mod.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs
@@ -5,10 +5,9 @@ use rustc_middle::ty::GenericArgKind;
 use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt, Upcast};
 use rustc_span::Span;
 
+pub(crate) mod dump;
 mod explicit;
 mod implicit_infer;
-/// Code to write unit test for outlives.
-pub mod test;
 mod utils;
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs
deleted file mode 100644
index e9b6c679bd5..00000000000
--- a/compiler/rustc_hir_analysis/src/outlives/test.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use rustc_middle::bug;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::{symbol::sym, ErrorGuaranteed};
-
-pub fn test_inferred_outlives(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
-    let mut res = Ok(());
-    for id in tcx.hir().items() {
-        // For unit testing: check for a special "rustc_outlives"
-        // attribute and report an error with various results if found.
-        if tcx.has_attr(id.owner_id, sym::rustc_outlives) {
-            let predicates = tcx.inferred_outlives_of(id.owner_id);
-            let mut pred: Vec<String> = predicates
-                .iter()
-                .map(|(out_pred, _)| match out_pred.kind().skip_binder() {
-                    ty::ClauseKind::RegionOutlives(p) => p.to_string(),
-                    ty::ClauseKind::TypeOutlives(p) => p.to_string(),
-                    err => bug!("unexpected clause {:?}", err),
-                })
-                .collect();
-            pred.sort();
-
-            let span = tcx.def_span(id.owner_id);
-            let mut err = tcx.dcx().struct_span_err(span, "rustc_outlives");
-            for p in pred {
-                err.note(p);
-            }
-            res = Err(err.emit());
-        }
-    }
-    res
-}
diff --git a/compiler/rustc_hir_analysis/src/variance/dump.rs b/compiler/rustc_hir_analysis/src/variance/dump.rs
new file mode 100644
index 00000000000..1a17dabb677
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/variance/dump.rs
@@ -0,0 +1,32 @@
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::CRATE_DEF_ID;
+use rustc_middle::ty::TyCtxt;
+use rustc_span::symbol::sym;
+
+pub(crate) fn variances(tcx: TyCtxt<'_>) {
+    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
+        for id in tcx.hir().items() {
+            let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
+
+            let variances = tcx.variances_of(id.owner_id);
+
+            tcx.dcx().emit_err(crate::errors::VariancesOf {
+                span: tcx.def_span(id.owner_id),
+                variances: format!("{variances:?}"),
+            });
+        }
+    }
+
+    for id in tcx.hir().items() {
+        if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
+            continue;
+        }
+
+        let variances = tcx.variances_of(id.owner_id);
+
+        tcx.dcx().emit_err(crate::errors::VariancesOf {
+            span: tcx.def_span(id.owner_id),
+            variances: format!("{variances:?}"),
+        });
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 1977451f39e..29f96e27b64 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -22,8 +22,7 @@ mod constraints;
 /// Code to solve constraints and write out the results.
 mod solve;
 
-/// Code to write unit tests of variance.
-pub mod test;
+pub(crate) mod dump;
 
 /// Code for transforming variances.
 mod xform;
diff --git a/compiler/rustc_hir_analysis/src/variance/test.rs b/compiler/rustc_hir_analysis/src/variance/test.rs
deleted file mode 100644
index c211e1af046..00000000000
--- a/compiler/rustc_hir_analysis/src/variance/test.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::CRATE_DEF_ID;
-use rustc_middle::ty::TyCtxt;
-use rustc_span::symbol::sym;
-use rustc_span::ErrorGuaranteed;
-
-use crate::errors;
-
-pub fn test_variance(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
-    let mut res = Ok(());
-    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
-        for id in tcx.hir().items() {
-            if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
-                let variances_of = tcx.variances_of(id.owner_id);
-
-                res = Err(tcx.dcx().emit_err(errors::VariancesOf {
-                    span: tcx.def_span(id.owner_id),
-                    variances_of: format!("{variances_of:?}"),
-                }));
-            }
-        }
-    }
-
-    // For unit testing: check for a special "rustc_variance"
-    // attribute and report an error with various results if found.
-    for id in tcx.hir().items() {
-        if tcx.has_attr(id.owner_id, sym::rustc_variance) {
-            let variances_of = tcx.variances_of(id.owner_id);
-
-            res = Err(tcx.dcx().emit_err(errors::VariancesOf {
-                span: tcx.def_span(id.owner_id),
-                variances_of: format!("{variances_of:?}"),
-            }));
-        }
-    }
-    res
-}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4cb325c3c0c..a8123fe994c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1593,6 +1593,8 @@ symbols! {
         rustc_do_not_const_check,
         rustc_doc_primitive,
         rustc_dummy,
+        rustc_dump_item_bounds,
+        rustc_dump_predicates,
         rustc_dump_user_args,
         rustc_dump_vtable,
         rustc_effective_visibility,
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index 37184393a73..9d79faadd61 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -47,16 +47,18 @@ impl ArmInlineAsmRegClass {
         _arch: InlineAsmArch,
     ) -> &'static [(InlineAsmType, Option<Symbol>)] {
         match self {
-            Self::reg => types! { _: I8, I16, I32, F32; },
-            Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; },
+            Self::reg => types! { _: I8, I16, I32, F16, F32; },
+            Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F16, F32; },
             Self::dreg_low16 | Self::dreg_low8 => types! {
-                vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
+                vfp2: I64, F64;
+                neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
             },
             Self::dreg => types! {
-                d32: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
+                d32: I64, F64;
+                neon: VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2);
             },
             Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! {
-                neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
+                neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4);
             },
         }
     }
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 5459b4c7b29..8a2bc3b9d48 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -26,7 +26,7 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::flags::get_completion;
 use crate::core::config::flags::Subcommand;
 use crate::core::config::TargetSelection;
-use crate::utils::exec::BootstrapCommand;
+use crate::utils::exec::{BootstrapCommand, OutputMode};
 use crate::utils::helpers::{
     self, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var,
     linker_args, linker_flags, output, t, target_supports_cranelift_backend, up_to_date,
@@ -156,7 +156,10 @@ You can skip linkcheck with --skip src/tools/linkchecker"
         let _guard =
             builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host);
         let _time = helpers::timeit(builder);
-        builder.run_delaying_failure(linkchecker.arg(builder.out.join(host.triple).join("doc")));
+        builder.run_tracked(
+            BootstrapCommand::from(linkchecker.arg(builder.out.join(host.triple).join("doc")))
+                .delay_failure(),
+        );
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -213,8 +216,11 @@ impl Step for HtmlCheck {
             builder,
         ));
 
-        builder.run_delaying_failure(
-            builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)),
+        builder.run_tracked(
+            BootstrapCommand::from(
+                builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)),
+            )
+            .delay_failure(),
         );
     }
 }
@@ -261,7 +267,7 @@ impl Step for Cargotest {
             .env("RUSTC", builder.rustc(compiler))
             .env("RUSTDOC", builder.rustdoc(compiler));
         add_rustdoc_cargo_linker_args(cmd, builder, compiler.host, LldThreads::No);
-        builder.run_delaying_failure(cmd);
+        builder.run_tracked(BootstrapCommand::from(cmd).delay_failure());
     }
 }
 
@@ -813,7 +819,7 @@ impl Step for RustdocTheme {
             .env("RUSTC_BOOTSTRAP", "1");
         cmd.args(linker_args(builder, self.compiler.host, LldThreads::No));
 
-        builder.run_delaying_failure(&mut cmd);
+        builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure());
     }
 }
 
@@ -1093,7 +1099,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
         }
 
         builder.info("tidy check");
-        builder.run_delaying_failure(&mut cmd);
+        builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure());
 
         builder.info("x.py completions check");
         let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"]
@@ -2179,7 +2185,8 @@ impl BookTest {
             compiler.host,
         );
         let _time = helpers::timeit(builder);
-        let toolstate = if builder.run_delaying_failure(&mut rustbook_cmd) {
+        let cmd = BootstrapCommand::from(&mut rustbook_cmd).delay_failure();
+        let toolstate = if builder.run_tracked(cmd).is_success() {
             ToolState::TestPass
         } else {
             ToolState::TestFail
@@ -2312,7 +2319,8 @@ impl Step for ErrorIndex {
         let guard =
             builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host);
         let _time = helpers::timeit(builder);
-        builder.run_quiet(&mut tool);
+        builder
+            .run_tracked(BootstrapCommand::from(&mut tool).output_mode(OutputMode::OnlyOnFailure));
         drop(guard);
         // The tests themselves need to link to std, so make sure it is
         // available.
@@ -2341,11 +2349,11 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
     let test_args = builder.config.test_args().join(" ");
     cmd.arg("--test-args").arg(test_args);
 
-    if builder.config.verbose_tests {
-        builder.run_delaying_failure(&mut cmd)
-    } else {
-        builder.run_quiet_delaying_failure(&mut cmd)
+    let mut cmd = BootstrapCommand::from(&mut cmd).delay_failure();
+    if !builder.config.verbose_tests {
+        cmd = cmd.quiet();
     }
+    builder.run_tracked(cmd).is_success()
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -2370,7 +2378,8 @@ impl Step for RustcGuide {
 
         let src = builder.src.join(relative_path);
         let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
-        let toolstate = if builder.run_delaying_failure(rustbook_cmd.arg("linkcheck").arg(&src)) {
+        let cmd = BootstrapCommand::from(rustbook_cmd.arg("linkcheck").arg(&src)).delay_failure();
+        let toolstate = if builder.run_tracked(cmd).is_success() {
             ToolState::TestPass
         } else {
             ToolState::TestFail
@@ -2984,7 +2993,7 @@ impl Step for Bootstrap {
             .current_dir(builder.src.join("src/bootstrap/"));
         // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible.
         // Use `python -m unittest` manually if you want to pass arguments.
-        builder.run_delaying_failure(&mut check_bootstrap);
+        builder.run_tracked(BootstrapCommand::from(&mut check_bootstrap).delay_failure());
 
         let mut cmd = Command::new(&builder.initial_cargo);
         cmd.arg("test")
@@ -3061,7 +3070,7 @@ impl Step for TierCheck {
             self.compiler.host,
             self.compiler.host,
         );
-        builder.run_delaying_failure(&mut cargo.into());
+        builder.run_tracked(BootstrapCommand::from(&mut cargo.into()).delay_failure());
     }
 }
 
@@ -3147,7 +3156,7 @@ impl Step for RustInstaller {
         cmd.env("CARGO", &builder.initial_cargo);
         cmd.env("RUSTC", &builder.initial_rustc);
         cmd.env("TMP_DIR", &tmpdir);
-        builder.run_delaying_failure(&mut cmd);
+        builder.run_tracked(BootstrapCommand::from(&mut cmd).delay_failure());
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 449d8c128ec..9b414b24d2f 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -23,7 +23,7 @@ use std::fmt::Display;
 use std::fs::{self, File};
 use std::io;
 use std::path::{Path, PathBuf};
-use std::process::{Command, Output, Stdio};
+use std::process::{Command, Stdio};
 use std::str;
 use std::sync::OnceLock;
 
@@ -41,7 +41,7 @@ use crate::core::builder::Kind;
 use crate::core::config::{flags, LldMode};
 use crate::core::config::{DryRun, Target};
 use crate::core::config::{LlvmLibunwind, TargetSelection};
-use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, OutputMode};
+use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
 use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};
 
 mod core;
@@ -585,8 +585,8 @@ impl Build {
             BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"]))
                 .allow_failure()
                 .output_mode(match self.is_verbose() {
-                    true => OutputMode::PrintAll,
-                    false => OutputMode::PrintOutput,
+                    true => OutputMode::All,
+                    false => OutputMode::OnlyOutput,
                 }),
         );
         if has_local_modifications {
@@ -958,73 +958,36 @@ impl Build {
         })
     }
 
-    /// Runs a command, printing out nice contextual information if it fails.
-    fn run(&self, cmd: &mut Command) {
-        self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(
-            match self.is_verbose() {
-                true => OutputMode::PrintAll,
-                false => OutputMode::PrintOutput,
-            },
-        ));
-    }
-
-    /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
-    pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
-        self.run_cmd(BootstrapCommand::from(cmd).delay_failure().output_mode(
-            match self.is_verbose() {
-                true => OutputMode::PrintAll,
-                false => OutputMode::PrintOutput,
-            },
-        ))
-    }
-
-    /// Runs a command, printing out nice contextual information if it fails.
-    fn run_quiet(&self, cmd: &mut Command) {
-        self.run_cmd(
-            BootstrapCommand::from(cmd).fail_fast().output_mode(OutputMode::SuppressOnSuccess),
-        );
-    }
-
-    /// Runs a command, printing out nice contextual information if it fails.
-    /// Exits if the command failed to execute at all, otherwise returns its
-    /// `status.success()`.
-    fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool {
-        self.run_cmd(
-            BootstrapCommand::from(cmd).delay_failure().output_mode(OutputMode::SuppressOnSuccess),
-        )
-    }
-
-    /// A centralized function for running commands that do not return output.
-    pub(crate) fn run_cmd<'a, C: Into<BootstrapCommand<'a>>>(&self, cmd: C) -> bool {
+    /// Execute a command and return its output.
+    fn run_tracked(&self, command: BootstrapCommand<'_>) -> CommandOutput {
         if self.config.dry_run() {
-            return true;
+            return CommandOutput::default();
         }
 
-        let command = cmd.into();
         self.verbose(|| println!("running: {command:?}"));
 
-        let (output, print_error) = match command.output_mode {
-            mode @ (OutputMode::PrintAll | OutputMode::PrintOutput) => (
-                command.command.status().map(|status| Output {
-                    status,
-                    stdout: Vec::new(),
-                    stderr: Vec::new(),
-                }),
-                matches!(mode, OutputMode::PrintAll),
+        let output_mode = command.output_mode.unwrap_or_else(|| match self.is_verbose() {
+            true => OutputMode::All,
+            false => OutputMode::OnlyOutput,
+        });
+        let (output, print_error): (io::Result<CommandOutput>, bool) = match output_mode {
+            mode @ (OutputMode::All | OutputMode::OnlyOutput) => (
+                command.command.status().map(|status| status.into()),
+                matches!(mode, OutputMode::All),
             ),
-            OutputMode::SuppressOnSuccess => (command.command.output(), true),
+            OutputMode::OnlyOnFailure => (command.command.output().map(|o| o.into()), true),
         };
 
         let output = match output {
             Ok(output) => output,
             Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)),
         };
-        let result = if !output.status.success() {
+        if !output.is_success() {
             if print_error {
                 println!(
                     "\n\nCommand did not execute successfully.\
-                    \nExpected success, got: {}",
-                    output.status,
+                \nExpected success, got: {}",
+                    output.status(),
                 );
 
                 if !self.is_verbose() {
@@ -1034,37 +997,45 @@ impl Build {
                 self.verbose(|| {
                     println!(
                         "\nSTDOUT ----\n{}\n\
-                        STDERR ----\n{}\n",
-                        String::from_utf8_lossy(&output.stdout),
-                        String::from_utf8_lossy(&output.stderr)
+                    STDERR ----\n{}\n",
+                        output.stdout(),
+                        output.stderr(),
                     )
                 });
             }
-            Err(())
-        } else {
-            Ok(())
-        };
 
-        match result {
-            Ok(_) => true,
-            Err(_) => {
-                match command.failure_behavior {
-                    BehaviorOnFailure::DelayFail => {
-                        if self.fail_fast {
-                            exit!(1);
-                        }
-
-                        let mut failures = self.delayed_failures.borrow_mut();
-                        failures.push(format!("{command:?}"));
-                    }
-                    BehaviorOnFailure::Exit => {
+            match command.failure_behavior {
+                BehaviorOnFailure::DelayFail => {
+                    if self.fail_fast {
                         exit!(1);
                     }
-                    BehaviorOnFailure::Ignore => {}
+
+                    let mut failures = self.delayed_failures.borrow_mut();
+                    failures.push(format!("{command:?}"));
+                }
+                BehaviorOnFailure::Exit => {
+                    exit!(1);
                 }
-                false
+                BehaviorOnFailure::Ignore => {}
             }
         }
+        output
+    }
+
+    /// Runs a command, printing out nice contextual information if it fails.
+    fn run(&self, cmd: &mut Command) {
+        self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(
+            match self.is_verbose() {
+                true => OutputMode::All,
+                false => OutputMode::OnlyOutput,
+            },
+        ));
+    }
+
+    /// A centralized function for running commands that do not return output.
+    pub(crate) fn run_cmd<'a, C: Into<BootstrapCommand<'a>>>(&self, cmd: C) -> bool {
+        let command = cmd.into();
+        self.run_tracked(command).is_success()
     }
 
     /// Check if verbosity is greater than the `level`
diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs
index 0aede2022ba..e8c588b75b3 100644
--- a/src/bootstrap/src/utils/exec.rs
+++ b/src/bootstrap/src/utils/exec.rs
@@ -1,4 +1,4 @@
-use std::process::Command;
+use std::process::{Command, ExitStatus, Output};
 
 /// What should be done when the command fails.
 #[derive(Debug, Copy, Clone)]
@@ -16,11 +16,11 @@ pub enum BehaviorOnFailure {
 pub enum OutputMode {
     /// Print both the output (by inheriting stdout/stderr) and also the command itself, if it
     /// fails.
-    PrintAll,
+    All,
     /// Print the output (by inheriting stdout/stderr).
-    PrintOutput,
+    OnlyOutput,
     /// Suppress the output if the command succeeds, otherwise print the output.
-    SuppressOnSuccess,
+    OnlyOnFailure,
 }
 
 /// Wrapper around `std::process::Command`.
@@ -28,7 +28,7 @@ pub enum OutputMode {
 pub struct BootstrapCommand<'a> {
     pub command: &'a mut Command,
     pub failure_behavior: BehaviorOnFailure,
-    pub output_mode: OutputMode,
+    pub output_mode: Option<OutputMode>,
 }
 
 impl<'a> BootstrapCommand<'a> {
@@ -44,17 +44,62 @@ impl<'a> BootstrapCommand<'a> {
         Self { failure_behavior: BehaviorOnFailure::Ignore, ..self }
     }
 
+    /// Do not print the output of the command, unless it fails.
+    pub fn quiet(self) -> Self {
+        self.output_mode(OutputMode::OnlyOnFailure)
+    }
+
     pub fn output_mode(self, output_mode: OutputMode) -> Self {
-        Self { output_mode, ..self }
+        Self { output_mode: Some(output_mode), ..self }
     }
 }
 
 impl<'a> From<&'a mut Command> for BootstrapCommand<'a> {
     fn from(command: &'a mut Command) -> Self {
-        Self {
-            command,
-            failure_behavior: BehaviorOnFailure::Exit,
-            output_mode: OutputMode::PrintAll,
-        }
+        Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None }
+    }
+}
+
+/// Represents the output of an executed process.
+#[allow(unused)]
+pub struct CommandOutput(Output);
+
+impl CommandOutput {
+    pub fn is_success(&self) -> bool {
+        self.0.status.success()
+    }
+
+    pub fn is_failure(&self) -> bool {
+        !self.is_success()
+    }
+
+    pub fn status(&self) -> ExitStatus {
+        self.0.status
+    }
+
+    pub fn stdout(&self) -> String {
+        String::from_utf8(self.0.stdout.clone()).expect("Cannot parse process stdout as UTF-8")
+    }
+
+    pub fn stderr(&self) -> String {
+        String::from_utf8(self.0.stderr.clone()).expect("Cannot parse process stderr as UTF-8")
+    }
+}
+
+impl Default for CommandOutput {
+    fn default() -> Self {
+        Self(Output { status: Default::default(), stdout: vec![], stderr: vec![] })
+    }
+}
+
+impl From<Output> for CommandOutput {
+    fn from(output: Output) -> Self {
+        Self(output)
+    }
+}
+
+impl From<ExitStatus> for CommandOutput {
+    fn from(status: ExitStatus) -> Self {
+        Self(Output { status, stdout: vec![], stderr: vec![] })
     }
 }
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
index 73255651abe..b15857c325a 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
@@ -62,7 +62,7 @@ LL |         }
 LL |         match s.len() {
 LL ~             10 => 2,
 LL |             20 => {
- ...
+...
 LL |                         if foo() {
 LL ~                             return 20;
 LL |                         }
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
index 0cce718a1ac..f25c0293754 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
@@ -212,7 +212,7 @@ help: check if the original Iterator contains an element instead of collecting t
    |
 LL ~             
 LL |
- ...
+...
 LL |                 // Do lint
 LL ~                 vec.iter().map(|k| k * k).any(|x| x == n);
    |
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index ce64861fa40..de048091cfb 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -215,7 +215,7 @@ help: move the declaration `x` here
    |
 LL ~     
 LL |     // types that should be considered insignificant
- ...
+...
 LL |     let y = Box::new(4);
 LL ~     let x = SignificantDrop;
    |
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index bf5a89d8b75..b49f199ba5a 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -518,7 +518,7 @@ help: remove `return`
    |
 LL ~             10
 LL |         },
- ...
+...
 LL |         },
 LL ~     }
    |
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index f4c101cf81c..487132683e9 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -387,7 +387,7 @@ pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
     });
 }
 
-pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
+pub fn read_dir<F: FnMut(&Path)>(dir: impl AsRef<Path>, mut callback: F) {
     for entry in fs_wrapper::read_dir(dir) {
         callback(&entry.unwrap().path());
     }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 970a424d998..c3a94d17cd9 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -52,7 +52,6 @@ run-make/foreign-rust-exceptions/Makefile
 run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
-run-make/inline-always-many-cgu/Makefile
 run-make/interdependent-c-libraries/Makefile
 run-make/intrinsic-unreachable/Makefile
 run-make/invalid-library/Makefile
diff --git a/tests/assembly/asm/arm-types.rs b/tests/assembly/asm/arm-types.rs
index 280b6d4a228..eeff1a070b4 100644
--- a/tests/assembly/asm/arm-types.rs
+++ b/tests/assembly/asm/arm-types.rs
@@ -1,10 +1,13 @@
+//@ revisions: base d32 neon
 //@ assembly-output: emit-asm
 //@ compile-flags: --target armv7-unknown-linux-gnueabihf
-//@ compile-flags: -C target-feature=+neon
 //@ compile-flags: -C opt-level=0
+//@[d32] compile-flags: -C target-feature=+d32
+//@[neon] compile-flags: -C target-feature=+neon --cfg d32
+//@[neon] filecheck-flags: --check-prefix d32
 //@ needs-llvm-components: arm
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, f16)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
@@ -38,6 +41,8 @@ pub struct i32x2(i32, i32);
 #[repr(simd)]
 pub struct i64x1(i64);
 #[repr(simd)]
+pub struct f16x4(f16, f16, f16, f16);
+#[repr(simd)]
 pub struct f32x2(f32, f32);
 #[repr(simd)]
 pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
@@ -48,11 +53,14 @@ pub struct i32x4(i32, i32, i32, i32);
 #[repr(simd)]
 pub struct i64x2(i64, i64);
 #[repr(simd)]
+pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16);
+#[repr(simd)]
 pub struct f32x4(f32, f32, f32, f32);
 
 impl Copy for i8 {}
 impl Copy for i16 {}
 impl Copy for i32 {}
+impl Copy for f16 {}
 impl Copy for f32 {}
 impl Copy for i64 {}
 impl Copy for f64 {}
@@ -61,11 +69,13 @@ impl Copy for i8x8 {}
 impl Copy for i16x4 {}
 impl Copy for i32x2 {}
 impl Copy for i64x1 {}
+impl Copy for f16x4 {}
 impl Copy for f32x2 {}
 impl Copy for i8x16 {}
 impl Copy for i16x8 {}
 impl Copy for i32x4 {}
 impl Copy for i64x2 {}
+impl Copy for f16x8 {}
 impl Copy for f32x4 {}
 
 extern "C" {
@@ -152,6 +162,12 @@ check!(reg_i16 i16 reg "mov");
 // CHECK: @NO_APP
 check!(reg_i32 i32 reg "mov");
 
+// CHECK-LABEL: reg_f16:
+// CHECK: @APP
+// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
+// CHECK: @NO_APP
+check!(reg_f16 f16 reg "mov");
+
 // CHECK-LABEL: reg_f32:
 // CHECK: @APP
 // CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
@@ -170,6 +186,12 @@ check!(reg_ptr ptr reg "mov");
 // CHECK: @NO_APP
 check!(sreg_i32 i32 sreg "vmov.f32");
 
+// CHECK-LABEL: sreg_f16:
+// CHECK: @APP
+// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+// CHECK: @NO_APP
+check!(sreg_f16 f16 sreg "vmov.f32");
+
 // CHECK-LABEL: sreg_f32:
 // CHECK: @APP
 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
@@ -188,52 +210,72 @@ check!(sreg_ptr ptr sreg "vmov.f32");
 // CHECK: @NO_APP
 check!(sreg_low16_i32 i32 sreg_low16 "vmov.f32");
 
-// CHECK-LABEL: sreg_low16_f32:
+// CHECK-LABEL: sreg_low16_f16:
 // CHECK: @APP
 // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
 // CHECK: @NO_APP
-check!(sreg_low16_f32 f32 sreg_low16 "vmov.f32");
+check!(sreg_low16_f16 f16 sreg_low16 "vmov.f32");
 
-// CHECK-LABEL: dreg_i64:
+// CHECK-LABEL: sreg_low16_f32:
 // CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
 // CHECK: @NO_APP
+check!(sreg_low16_f32 f32 sreg_low16 "vmov.f32");
+
+// d32-LABEL: dreg_i64:
+// d32: @APP
+// d32: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// d32: @NO_APP
+#[cfg(d32)]
 check!(dreg_i64 i64 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_f64:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// d32-LABEL: dreg_f64:
+// d32: @APP
+// d32: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// d32: @NO_APP
+#[cfg(d32)]
 check!(dreg_f64 f64 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_i8x8:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_i8x8:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_i8x8 i8x8 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_i16x4:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_i16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_i16x4 i16x4 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_i32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_i32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_i32x2 i32x2 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_i64x1:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_i64x1:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_i64x1 i64x1 dreg "vmov.f64");
 
-// CHECK-LABEL: dreg_f32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_f16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(dreg_f16x4 f16x4 dreg "vmov.f64");
+
+// neon-LABEL: dreg_f32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_f32x2 f32x2 dreg "vmov.f64");
 
 // CHECK-LABEL: dreg_low16_i64:
@@ -248,34 +290,46 @@ check!(dreg_low16_i64 i64 dreg_low16 "vmov.f64");
 // CHECK: @NO_APP
 check!(dreg_low16_f64 f64 dreg_low16 "vmov.f64");
 
-// CHECK-LABEL: dreg_low16_i8x8:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low16_i8x8:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low16_i8x8 i8x8 dreg_low16 "vmov.f64");
 
-// CHECK-LABEL: dreg_low16_i16x4:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low16_i16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low16_i16x4 i16x4 dreg_low16 "vmov.f64");
 
-// CHECK-LABEL: dreg_low16_i32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low16_i32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low16_i32x2 i32x2 dreg_low16 "vmov.f64");
 
-// CHECK-LABEL: dreg_low16_i64x1:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low16_i64x1:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low16_i64x1 i64x1 dreg_low16 "vmov.f64");
 
-// CHECK-LABEL: dreg_low16_f32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low16_f16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(dreg_low16_f16x4 f16x4 dreg_low16 "vmov.f64");
+
+// neon-LABEL: dreg_low16_f32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low16_f32x2 f32x2 dreg_low16 "vmov.f64");
 
 // CHECK-LABEL: dreg_low8_i64:
@@ -290,124 +344,172 @@ check!(dreg_low8_i64 i64 dreg_low8 "vmov.f64");
 // CHECK: @NO_APP
 check!(dreg_low8_f64 f64 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: dreg_low8_i8x8:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low8_i8x8:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low8_i8x8 i8x8 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: dreg_low8_i16x4:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low8_i16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low8_i16x4 i16x4 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: dreg_low8_i32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low8_i32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low8_i32x2 i32x2 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: dreg_low8_i64x1:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low8_i64x1:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low8_i64x1 i64x1 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: dreg_low8_f32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: dreg_low8_f16x4:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(dreg_low8_f16x4 f16x4 dreg_low8 "vmov.f64");
+
+// neon-LABEL: dreg_low8_f32x2:
+// neon: @APP
+// neon: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(dreg_low8_f32x2 f32x2 dreg_low8 "vmov.f64");
 
-// CHECK-LABEL: qreg_i8x16:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_i8x16:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_i8x16 i8x16 qreg "vmov");
 
-// CHECK-LABEL: qreg_i16x8:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_i16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_i16x8 i16x8 qreg "vmov");
 
-// CHECK-LABEL: qreg_i32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_i32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_i32x4 i32x4 qreg "vmov");
 
-// CHECK-LABEL: qreg_i64x2:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_i64x2:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_i64x2 i64x2 qreg "vmov");
 
-// CHECK-LABEL: qreg_f32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_f16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(qreg_f16x8 f16x8 qreg "vmov");
+
+// neon-LABEL: qreg_f32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_f32x4 f32x4 qreg "vmov");
 
-// CHECK-LABEL: qreg_low8_i8x16:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low8_i8x16:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low8_i8x16 i8x16 qreg_low8 "vmov");
 
-// CHECK-LABEL: qreg_low8_i16x8:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low8_i16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low8_i16x8 i16x8 qreg_low8 "vmov");
 
-// CHECK-LABEL: qreg_low8_i32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low8_i32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low8_i32x4 i32x4 qreg_low8 "vmov");
 
-// CHECK-LABEL: qreg_low8_i64x2:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low8_i64x2:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low8_i64x2 i64x2 qreg_low8 "vmov");
 
-// CHECK-LABEL: qreg_low8_f32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low8_f16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(qreg_low8_f16x8 f16x8 qreg_low8 "vmov");
+
+// neon-LABEL: qreg_low8_f32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low8_f32x4 f32x4 qreg_low8 "vmov");
 
-// CHECK-LABEL: qreg_low4_i8x16:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low4_i8x16:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low4_i8x16 i8x16 qreg_low4 "vmov");
 
-// CHECK-LABEL: qreg_low4_i16x8:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low4_i16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low4_i16x8 i16x8 qreg_low4 "vmov");
 
-// CHECK-LABEL: qreg_low4_i32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low4_i32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low4_i32x4 i32x4 qreg_low4 "vmov");
 
-// CHECK-LABEL: qreg_low4_i64x2:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low4_i64x2:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low4_i64x2 i64x2 qreg_low4 "vmov");
 
-// CHECK-LABEL: qreg_low4_f32x4:
-// CHECK: @APP
-// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: @NO_APP
+// neon-LABEL: qreg_low4_f16x8:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
+check!(qreg_low4_f16x8 f16x8 qreg_low4 "vmov");
+
+// neon-LABEL: qreg_low4_f32x4:
+// neon: @APP
+// neon: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// neon: @NO_APP
+#[cfg(neon)]
 check!(qreg_low4_f32x4 f32x4 qreg_low4 "vmov");
 
 // CHECK-LABEL: r0_i8:
@@ -428,6 +530,12 @@ check_reg!(r0_i16 i16 "r0" "mov");
 // CHECK: @NO_APP
 check_reg!(r0_i32 i32 "r0" "mov");
 
+// CHECK-LABEL: r0_f16:
+// CHECK: @APP
+// CHECK: mov r0, r0
+// CHECK: @NO_APP
+check_reg!(r0_f16 f16 "r0" "mov");
+
 // CHECK-LABEL: r0_f32:
 // CHECK: @APP
 // CHECK: mov r0, r0
@@ -446,6 +554,12 @@ check_reg!(r0_ptr ptr "r0" "mov");
 // CHECK: @NO_APP
 check_reg!(s0_i32 i32 "s0" "vmov.f32");
 
+// CHECK-LABEL: s0_f16:
+// CHECK: @APP
+// CHECK: vmov.f32 s0, s0
+// CHECK: @NO_APP
+check_reg!(s0_f16 f16 "s0" "vmov.f32");
+
 // CHECK-LABEL: s0_f32:
 // CHECK: @APP
 // CHECK: vmov.f32 s0, s0
@@ -458,74 +572,101 @@ check_reg!(s0_f32 f32 "s0" "vmov.f32");
 // CHECK: @NO_APP
 check_reg!(s0_ptr ptr "s0" "vmov.f32");
 
-// CHECK-LABEL: d0_i64:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// FIXME(#126797): "d0" should work with `i64` and `f64` even when `d32` is disabled.
+// d32-LABEL: d0_i64:
+// d32: @APP
+// d32: vmov.f64 d0, d0
+// d32: @NO_APP
+#[cfg(d32)]
 check_reg!(d0_i64 i64 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_f64:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// d32-LABEL: d0_f64:
+// d32: @APP
+// d32: vmov.f64 d0, d0
+// d32: @NO_APP
+#[cfg(d32)]
 check_reg!(d0_f64 f64 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_i8x8:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// neon-LABEL: d0_i8x8:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(d0_i8x8 i8x8 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_i16x4:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// neon-LABEL: d0_i16x4:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(d0_i16x4 i16x4 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_i32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// neon-LABEL: d0_i32x2:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(d0_i32x2 i32x2 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_i64x1:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// neon-LABEL: d0_i64x1:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(d0_i64x1 i64x1 "d0" "vmov.f64");
 
-// CHECK-LABEL: d0_f32x2:
-// CHECK: @APP
-// CHECK: vmov.f64 d0, d0
-// CHECK: @NO_APP
+// neon-LABEL: d0_f16x4:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
+check_reg!(d0_f16x4 f16x4 "d0" "vmov.f64");
+
+// neon-LABEL: d0_f32x2:
+// neon: @APP
+// neon: vmov.f64 d0, d0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(d0_f32x2 f32x2 "d0" "vmov.f64");
 
-// CHECK-LABEL: q0_i8x16:
-// CHECK: @APP
-// CHECK: vorr q0, q0, q0
-// CHECK: @NO_APP
+// neon-LABEL: q0_i8x16:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(q0_i8x16 i8x16 "q0" "vmov");
 
-// CHECK-LABEL: q0_i16x8:
-// CHECK: @APP
-// CHECK: vorr q0, q0, q0
-// CHECK: @NO_APP
+// neon-LABEL: q0_i16x8:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(q0_i16x8 i16x8 "q0" "vmov");
 
-// CHECK-LABEL: q0_i32x4:
-// CHECK: @APP
-// CHECK: vorr q0, q0, q0
-// CHECK: @NO_APP
+// neon-LABEL: q0_i32x4:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(q0_i32x4 i32x4 "q0" "vmov");
 
-// CHECK-LABEL: q0_i64x2:
-// CHECK: @APP
-// CHECK: vorr q0, q0, q0
-// CHECK: @NO_APP
+// neon-LABEL: q0_i64x2:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(q0_i64x2 i64x2 "q0" "vmov");
 
-// CHECK-LABEL: q0_f32x4:
-// CHECK: @APP
-// CHECK: vorr q0, q0, q0
-// CHECK: @NO_APP
+// neon-LABEL: q0_f16x8:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
+check_reg!(q0_f16x8 f16x8 "q0" "vmov");
+
+// neon-LABEL: q0_f32x4:
+// neon: @APP
+// neon: vorr q0, q0, q0
+// neon: @NO_APP
+#[cfg(neon)]
 check_reg!(q0_f32x4 f32x4 "q0" "vmov");
diff --git a/tests/run-make/inline-always-many-cgu/Makefile b/tests/run-make/inline-always-many-cgu/Makefile
deleted file mode 100644
index 9945821db28..00000000000
--- a/tests/run-make/inline-always-many-cgu/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2
-	if cat $(TMPDIR)/*.ll | $(CGREP) -e '\bcall\b'; then \
-		echo "found call instruction when one wasn't expected"; \
-		exit 1; \
-	fi
diff --git a/tests/run-make/inline-always-many-cgu/rmake.rs b/tests/run-make/inline-always-many-cgu/rmake.rs
new file mode 100644
index 00000000000..c55ea69f3b9
--- /dev/null
+++ b/tests/run-make/inline-always-many-cgu/rmake.rs
@@ -0,0 +1,18 @@
+use run_make_support::fs_wrapper::read_to_string;
+use run_make_support::regex::Regex;
+use run_make_support::{read_dir, rustc};
+
+use std::ffi::OsStr;
+
+fn main() {
+    rustc().input("foo.rs").emit("llvm-ir").codegen_units(2).run();
+    let re = Regex::new(r"\bcall\b").unwrap();
+    let mut nb_ll = 0;
+    read_dir(".", |path| {
+        if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) {
+            assert!(!re.is_match(&read_to_string(path)));
+            nb_ll += 1;
+        }
+    });
+    assert!(nb_ll > 0);
+}
diff --git a/tests/ui/attributes/dump-preds.rs b/tests/ui/attributes/dump-preds.rs
new file mode 100644
index 00000000000..1e15ff2f9bd
--- /dev/null
+++ b/tests/ui/attributes/dump-preds.rs
@@ -0,0 +1,20 @@
+//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)"
+
+#![feature(rustc_attrs)]
+
+#[rustc_dump_predicates]
+trait Trait<T>: Iterator<Item: Copy>
+//~^ ERROR rustc_dump_predicates
+where
+    String: From<T>
+{
+    #[rustc_dump_predicates]
+    #[rustc_dump_item_bounds]
+    type Assoc<P: Eq>: std::ops::Deref<Target = ()>
+    //~^ ERROR rustc_dump_predicates
+    //~| ERROR rustc_dump_item_bounds
+    where
+        Self::Assoc<()>: Copy;
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr
new file mode 100644
index 00000000000..26834376e76
--- /dev/null
+++ b/tests/ui/attributes/dump-preds.stderr
@@ -0,0 +1,39 @@
+error: rustc_dump_predicates
+  --> $DIR/dump-preds.rs:6:1
+   |
+LL | trait Trait<T>: Iterator<Item: Copy>
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<std::string::String as std::convert::From<T>>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<Self as Trait<T>>, polarity:Positive), bound_vars: [] }
+
+error: rustc_dump_predicates
+  --> $DIR/dump-preds.rs:13:5
+   |
+LL |     type Assoc<P: Eq>: std::ops::Deref<Target = ()>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<std::string::String as std::convert::From<T>>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<Self as Trait<T>>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<P as std::marker::Sized>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<P as std::cmp::Eq>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<()> as std::marker::Copy>, polarity:Positive), bound_vars: [] }
+
+error: rustc_dump_item_bounds
+  --> $DIR/dump-preds.rs:13:5
+   |
+LL |     type Assoc<P: Eq>: std::ops::Deref<Target = ()>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(Projection, AliasTy { args: [Self/#0, T/#1, P/#2], def_id: DefId(..) })], def_id: DefId(..) }, Term::Ty(())), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] }
+   = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] }
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index 856ec4a5b9e..fdcada468e0 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -17,7 +17,7 @@ help: add a dummy let to cause `fptr` to be fully captured
    |
 LL ~     thread::spawn(move || { let _ = &fptr; unsafe {
 LL |
- ...
+...
 LL |
 LL ~     } }).join().unwrap();
    |
@@ -39,7 +39,7 @@ help: add a dummy let to cause `fptr` to be fully captured
    |
 LL ~     thread::spawn(move || { let _ = &fptr; unsafe {
 LL |
- ...
+...
 LL |
 LL ~     } }).join().unwrap();
    |
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
index 344bc662ee7..138778ff5d7 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
@@ -109,7 +109,7 @@ help: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
    |
 LL ~     thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
 LL |
- ...
+...
 LL |
 LL ~     } }).join().unwrap();
    |
diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr
index 293c2a60d80..74525c9c88f 100644
--- a/tests/ui/imports/issue-59764.stderr
+++ b/tests/ui/imports/issue-59764.stderr
@@ -209,7 +209,7 @@ help: a macro with this name exists at the root of the crate
    |
 LL ~         issue_59764::{makro as foobar, 
 LL |
- ...
+...
 LL |
 LL ~             foo::{baz}
    |
diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/issues/issue-22644.stderr
index 7d8a0ff170a..c6d41cc856d 100644
--- a/tests/ui/issues/issue-22644.stderr
+++ b/tests/ui/issues/issue-22644.stderr
@@ -64,7 +64,7 @@ help: try comparing the cast value
    |
 LL ~     println!("{}", (a
 LL |
- ...
+...
 LL |
 LL ~                    usize)
    |
diff --git a/tests/ui/issues/issue-57271.stderr b/tests/ui/issues/issue-57271.stderr
index 10cbb34ef5d..a61419c61d7 100644
--- a/tests/ui/issues/issue-57271.stderr
+++ b/tests/ui/issues/issue-57271.stderr
@@ -17,7 +17,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~     Array(Box<TypeSignature>),
 LL |     TypeVariable(()),
- ...
+...
 LL |     Base(BaseType),
 LL ~     Object(Box<ObjectType>),
    |
diff --git a/tests/ui/let-else/let-else-if.stderr b/tests/ui/let-else/let-else-if.stderr
index c8058ec6692..7e2215c8c05 100644
--- a/tests/ui/let-else/let-else-if.stderr
+++ b/tests/ui/let-else/let-else-if.stderr
@@ -8,7 +8,7 @@ help: try placing this code inside a block
    |
 LL ~     let Some(_) = Some(()) else { if true {
 LL |
- ...
+...
 LL |         return;
 LL ~     } };
    |
diff --git a/tests/ui/loops/loop-else-break-with-value.stderr b/tests/ui/loops/loop-else-break-with-value.stderr
index 13d4c5faf73..ca18f0fdd7f 100644
--- a/tests/ui/loops/loop-else-break-with-value.stderr
+++ b/tests/ui/loops/loop-else-break-with-value.stderr
@@ -27,7 +27,7 @@ help: you might want to use `if let` to ignore the variant that isn't matched
    |
 LL ~     if let Some(1) = loop {
 LL |
- ...
+...
 LL |         return;
 LL ~     } { todo!() };
    |
diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr
index 3247513d42c..cf863ff8af1 100644
--- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr
+++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr
@@ -26,7 +26,7 @@ help: consider moving the expression out of the loop so it is only moved once
 LL ~     for foo in foos { let mut value = baz.push(foo);
 LL ~     for bar in &bars { if foo == *bar {
 LL |
- ...
+...
 LL |
 LL ~         value;
    |
@@ -69,7 +69,7 @@ help: consider moving the expression out of the loop so it is only moved once
 LL ~         let mut value = baz.push(foo);
 LL ~         for bar in &bars {
 LL |
- ...
+...
 LL |             if foo == *bar {
 LL ~                 value;
    |
diff --git a/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr b/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr
index d66ce695090..c8107997c2e 100644
--- a/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr
+++ b/tests/ui/parser/recover/recover-labeled-non-block-expr.stderr
@@ -54,7 +54,7 @@ help: consider enclosing expression in a block
    |
 LL ~     let _i = 'label: { match x {
 LL |         0 => 42,
- ...
+...
 LL |         _ => 1,
 LL ~     } };
    |
diff --git a/tests/ui/span/recursive-type-field.stderr b/tests/ui/span/recursive-type-field.stderr
index 30ba8cde463..323bbd89457 100644
--- a/tests/ui/span/recursive-type-field.stderr
+++ b/tests/ui/span/recursive-type-field.stderr
@@ -17,7 +17,7 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~     bar: Box<Bar<'a>>,
 LL |     b: Rc<Bar<'a>>,
- ...
+...
 LL | struct Bar<'a> {
 LL ~     y: (Box<Foo<'a>>, Box<Foo<'a>>),
    |
diff --git a/tests/ui/suggestions/issue-68049-2.stderr b/tests/ui/suggestions/issue-68049-2.stderr
index 449ecabeb7f..91def27bfcd 100644
--- a/tests/ui/suggestions/issue-68049-2.stderr
+++ b/tests/ui/suggestions/issue-68049-2.stderr
@@ -19,7 +19,7 @@ help: consider changing this to be a mutable reference in the `impl` method and
    |
 LL ~   fn example(&mut self, input: &i32);
 LL | }
- ...
+...
 LL | impl Hello for Test2 {
 LL ~   fn example(&mut self, input: &i32) {
    |
diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr
index ba6eacde68f..d22117165c1 100644
--- a/tests/ui/try-trait/try-operator-on-main.stderr
+++ b/tests/ui/try-trait/try-operator-on-main.stderr
@@ -12,7 +12,7 @@ help: consider adding return type
    |
 LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
 LL |     // error for a `Try` type on a non-`Try` fn
- ...
+...
 LL |     try_trait_generic::<()>();
 LL + 
 LL +     Ok(())
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
index c0fce5c2aaa..926e1c72f2f 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
@@ -14,7 +14,7 @@ help: consider introducing a named lifetime parameter
    |
 LL ~ fn main<'a>() {
 LL |     eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>,
- ...
+...
 LL |
 LL ~     let _: dyn Foo(&'a isize, &'a usize) -> &'a usize;
    |