about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock14
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs16
-rw-r--r--compiler/rustc_codegen_gcc/src/base.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs18
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs2
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs10
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs25
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs45
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs184
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs72
-rw-r--r--compiler/rustc_interface/messages.ftl2
-rw-r--r--compiler/rustc_interface/src/passes.rs3
-rw-r--r--compiler/rustc_llvm/Cargo.toml3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp5
-rw-r--r--compiler/rustc_metadata/messages.ftl7
-rw-r--r--compiler/rustc_metadata/src/creader.rs4
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs47
-rw-r--r--compiler/rustc_metadata/src/errors.rs10
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs1
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs8
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs9
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs3
-rw-r--r--compiler/rustc_session/src/config.rs9
-rw-r--r--compiler/rustc_session/src/config/cfg.rs11
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/asm/mod.rs5
-rw-r--r--compiler/rustc_target/src/asm/powerpc.rs12
-rw-r--r--compiler/rustc_target/src/spec/base/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/motor.rs34
-rw-r--r--compiler/rustc_target/src/spec/base/wasm.rs5
-rw-r--r--compiler/rustc_target/src/spec/mod.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs38
-rw-r--r--compiler/rustc_thread_pool/src/latch.rs8
-rw-r--r--compiler/rustc_windows_rc/Cargo.toml4
-rw-r--r--compiler/rustc_windows_rc/src/lib.rs34
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/src/alloc.rs4
-rw-r--r--library/alloc/src/collections/btree/node.rs5
-rw-r--r--library/alloc/src/raw_vec/mod.rs2
-rw-r--r--library/alloc/src/rc.rs9
-rw-r--r--library/alloc/src/sync.rs9
-rw-r--r--library/alloc/src/vec/mod.rs8
-rw-r--r--library/compiler-builtins/libm/src/math/support/float_traits.rs2
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/ascii/ascii_char.rs2
-rw-r--r--library/core/src/cell.rs4
-rw-r--r--library/core/src/intrinsics/mod.rs138
-rw-r--r--library/core/src/iter/adapters/flatten.rs2
-rw-r--r--library/core/src/num/f128.rs24
-rw-r--r--library/core/src/num/f16.rs24
-rw-r--r--library/core/src/num/f32.rs24
-rw-r--r--library/core/src/num/f64.rs24
-rw-r--r--library/core/src/num/int_macros.rs6
-rw-r--r--library/core/src/num/mod.rs4
-rw-r--r--library/core/src/num/uint_macros.rs4
-rw-r--r--library/core/src/option.rs8
-rw-r--r--library/core/src/panicking.rs83
-rw-r--r--library/core/src/result.rs4
-rw-r--r--library/core/src/slice/index.rs6
-rw-r--r--library/core/src/slice/mod.rs4
-rw-r--r--library/core/src/slice/sort/shared/smallsort.rs4
-rw-r--r--library/core/src/str/mod.rs4
-rw-r--r--library/core/src/ub_checks.rs5
-rw-r--r--library/coretests/tests/floats/mod.rs171
-rw-r--r--library/std/Cargo.toml5
-rw-r--r--library/std/src/io/mod.rs2
-rw-r--r--library/std/src/num/f128.rs16
-rw-r--r--library/std/src/num/f16.rs16
-rw-r--r--library/std/src/num/f32.rs16
-rw-r--r--library/std/src/num/f64.rs16
-rw-r--r--library/std/src/panicking.rs26
-rw-r--r--library/std/src/rt.rs4
-rw-r--r--library/std/src/thread/local.rs2
-rw-r--r--library/std_detect/src/detect/os/darwin/aarch64.rs22
-rw-r--r--library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs12
-rw-r--r--library/stdarch/crates/core_arch/src/wasm32/mod.rs16
-rw-r--r--library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml12
-rw-r--r--library/sysroot/Cargo.toml1
-rw-r--r--src/bootstrap/src/core/sanity.rs5
-rw-r--r--src/doc/rustc/src/codegen-options/index.md2
-rw-r--r--src/doc/rustc/src/linker-plugin-lto.md7
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/motor.md45
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md6
-rw-r--r--src/librustdoc/clean/cfg.rs78
-rw-r--r--src/librustdoc/display.rs86
-rw-r--r--src/librustdoc/html/format.rs348
-rw-r--r--src/librustdoc/html/static/js/main.js25
-rw-r--r--src/librustdoc/lib.rs7
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/directives.rs19
-rw-r--r--src/tools/compiletest/src/directives/directive_names.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs22
-rw-r--r--src/tools/miri/tests/pass/float.rs4
-rw-r--r--src/tools/miri/tests/pass/intrinsics/fmuladd_nondeterministic.rs4
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/rustdoc_json.rs6
-rw-r--r--tests/assembly-llvm/targets/targets-elf.rs3
-rw-r--r--tests/codegen-llvm/asm/powerpc-clobbers.rs8
-rw-r--r--tests/codegen-llvm/asm/readonly-not-pure.rs48
-rw-r--r--tests/codegen-llvm/intrinsic-no-unnamed-attr.rs4
-rw-r--r--tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs17
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml12
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs65
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs46
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml4
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs1
-rw-r--r--tests/run-make-cargo/panic-immediate-abort-works/rmake.rs39
-rw-r--r--tests/run-make/crate-loading/dep-2-reexport.rs (renamed from tests/run-make/crate-loading/multiple-dep-versions-3.rs)0
-rw-r--r--tests/run-make/crate-loading/dependency-1.rs (renamed from tests/run-make/crate-loading/multiple-dep-versions-1.rs)0
-rw-r--r--tests/run-make/crate-loading/dependency-2.rs (renamed from tests/run-make/crate-loading/multiple-dep-versions-2.rs)0
-rw-r--r--tests/run-make/crate-loading/rmake.rs9
-rw-r--r--tests/run-make/musl-default-linking/rmake.rs3
-rw-r--r--tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs28
-rw-r--r--tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs1
-rw-r--r--tests/rustdoc/reexport/private-mod-override-reexport.rs13
-rw-r--r--tests/ui/asm/powerpc/bad-reg.aix64.stderr162
-rw-r--r--tests/ui/asm/powerpc/bad-reg.powerpc.stderr176
-rw-r--r--tests/ui/asm/powerpc/bad-reg.powerpc64.stderr168
-rw-r--r--tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr162
-rw-r--r--tests/ui/asm/powerpc/bad-reg.rs30
-rw-r--r--tests/ui/check-cfg/cfg-crate-features.stderr2
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.cargo.stderr2
-rw-r--r--tests/ui/check-cfg/report-in-external-macros.rustc.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr6
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg4
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg4
-rw-r--r--tests/ui/diagnostic-flags/colored-session-opt-error.svg4
-rw-r--r--tests/ui/diagnostic-flags/terminal_urls.rs4
-rw-r--r--tests/ui/diagnostic-flags/terminal_urls.stderr11
-rw-r--r--tests/ui/diagnostic-flags/terminal_urls.svg48
-rw-r--r--tests/ui/diagnostic-flags/terminal_urls.windows.svg49
-rw-r--r--tests/ui/error-emitter/E0308-clarification.svg2
-rw-r--r--tests/ui/error-emitter/highlighting.svg2
-rw-r--r--tests/ui/error-emitter/highlighting.windows.svg2
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.svg2
-rw-r--r--tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg2
-rw-r--r--tests/ui/error-emitter/multiline-removal-suggestion.svg4
-rw-r--r--tests/ui/error-emitter/unicode-output.svg2
-rw-r--r--tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg4
-rw-r--r--tests/ui/intrinsics/intrinsic-fmuladd.rs4
-rw-r--r--tests/ui/intrinsics/reify-intrinsic.stderr2
-rw-r--r--tests/ui/iterators/issue-58952-filter-type-length.rs2
-rw-r--r--tests/ui/panic-runtime/auxiliary/needs-abort.rs2
-rw-r--r--tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs7
-rw-r--r--tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs18
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag1.rs2
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag1.stderr2
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag2.rs2
-rw-r--r--tests/ui/panic-runtime/bad-panic-flag2.stderr2
-rw-r--r--tests/ui/panic-runtime/immediate-abort-default-sysroot.rs15
-rw-r--r--tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr4
-rw-r--r--tests/ui/panic-runtime/need-abort-got-immediate-abort.rs21
-rw-r--r--tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr4
-rw-r--r--tests/ui/panic-runtime/need-immediate-abort-got-abort.rs20
-rw-r--r--tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr4
-rw-r--r--tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs20
-rw-r--r--tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr4
-rw-r--r--tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs21
-rw-r--r--tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr4
-rw-r--r--tests/ui/proc-macro/panic-abort.rs2
-rw-r--r--tests/ui/proc-macro/panic-abort.stderr2
-rw-r--r--tests/ui/suggestions/incorrect-variant-literal.svg2
-rw-r--r--tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs2
175 files changed, 2321 insertions, 1154 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c2e635b4cfe..3d4a1bf6a78 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -128,9 +128,9 @@ dependencies = [
 
 [[package]]
 name = "anstyle-svg"
-version = "0.1.10"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc03a770ef506fe1396c0e476120ac0e6523cf14b74218dd5f18cd6833326fa9"
+checksum = "26b9ec8c976eada1b0f9747a3d7cc4eae3bef10613e443746e7487f26c872fde"
 dependencies = [
  "anstyle",
  "anstyle-lossy",
@@ -1333,6 +1333,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "find-msvc-tools"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
+
+[[package]]
 name = "flate2"
 version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3556,7 +3562,7 @@ dependencies = [
  "ar_archive_writer",
  "bitflags",
  "bstr",
- "cc",
+ "find-msvc-tools",
  "itertools",
  "libc",
  "object 0.37.3",
@@ -4760,7 +4766,7 @@ dependencies = [
 name = "rustc_windows_rc"
 version = "0.0.0"
 dependencies = [
- "cc",
+ "find-msvc-tools",
 ]
 
 [[package]]
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 51089e5a1d3..82c59d5a3a2 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -63,8 +63,8 @@ pub fn inject(
 
     if sess.is_test_crate() {
         let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
-            (PanicStrategy::Abort, true) => PanicStrategy::Abort,
-            (PanicStrategy::Abort, false) => {
+            (PanicStrategy::Abort | PanicStrategy::ImmediateAbort, true) => panic_strategy,
+            (PanicStrategy::Abort | PanicStrategy::ImmediateAbort, false) => {
                 if panic_strategy == platform_panic_strategy {
                     // Silently allow compiling with panic=abort on these platforms,
                     // but with old behavior (abort if a test fails).
@@ -287,10 +287,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
     let ecx = &cx.ext_cx;
     let test_ident = Ident::new(sym::test, sp);
 
-    let runner_name = match cx.panic_strategy {
-        PanicStrategy::Unwind => "test_main_static",
-        PanicStrategy::Abort => "test_main_static_abort",
-    };
+    let runner_name =
+        if cx.panic_strategy.unwinds() { "test_main_static" } else { "test_main_static_abort" };
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 17e2e028b16..a14881c502c 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -698,8 +698,12 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
         InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
         InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
         InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
-        | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
+        InlineAsmRegClass::PowerPC(
+            PowerPCInlineAsmRegClass::cr
+            | PowerPCInlineAsmRegClass::ctr
+            | PowerPCInlineAsmRegClass::lr
+            | PowerPCInlineAsmRegClass::xer,
+        ) => {
             unreachable!("clobber-only")
         }
         InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -777,8 +781,12 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
         InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
             cx.type_vector(cx.type_i32(), 4)
         }
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
-        | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
+        InlineAsmRegClass::PowerPC(
+            PowerPCInlineAsmRegClass::cr
+            | PowerPCInlineAsmRegClass::ctr
+            | PowerPCInlineAsmRegClass::lr
+            | PowerPCInlineAsmRegClass::xer,
+        ) => {
             unreachable!("clobber-only")
         }
         InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs
index e9d72e457a0..e8672f49580 100644
--- a/compiler/rustc_codegen_gcc/src/base.rs
+++ b/compiler/rustc_codegen_gcc/src/base.rs
@@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::DebugInfo;
 use rustc_span::Symbol;
+use rustc_target::spec::RelocModel;
 #[cfg(feature = "master")]
 use rustc_target::spec::SymbolVisibility;
-use rustc_target::spec::{PanicStrategy, RelocModel};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
@@ -101,7 +101,7 @@ pub fn compile_codegen_unit(
         // Instantiate monomorphizations without filling out definitions yet...
         let context = new_context(tcx);
 
-        if tcx.sess.panic_strategy() == PanicStrategy::Unwind {
+        if tcx.sess.panic_strategy().unwinds() {
             context.add_command_line_option("-fexceptions");
             context.add_driver_option("-fexceptions");
         }
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 84fa56cf903..a915f5d6418 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -29,7 +29,6 @@ use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{Span, Symbol, sym};
 use rustc_target::callconv::{ArgAbi, PassMode};
-use rustc_target::spec::PanicStrategy;
 
 #[cfg(feature = "master")]
 use crate::abi::FnAbiGccExt;
@@ -1334,7 +1333,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
     _catch_func: RValue<'gcc>,
     dest: PlaceRef<'tcx, RValue<'gcc>>,
 ) {
-    if bx.sess().panic_strategy() == PanicStrategy::Abort {
+    if !bx.sess().panic_strategy().unwinds() {
         bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
         // Return 0 unconditionally from the intrinsic call;
         // we can never unwind.
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index b79176e9098..cc09fa5b69b 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -340,8 +340,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
         } else if options.contains(InlineAsmOptions::NOMEM) {
             attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
-        } else {
-            // LLVM doesn't have an attribute to represent ReadOnly + SideEffect
+        } else if options.contains(InlineAsmOptions::READONLY) {
+            attrs.push(llvm::MemoryEffects::ReadOnlyNotPure.create_attr(self.cx.llcx));
         }
         attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
 
@@ -662,7 +662,12 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
             PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
             PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
             PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
-            PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
+            PowerPC(
+                PowerPCInlineAsmRegClass::cr
+                | PowerPCInlineAsmRegClass::ctr
+                | PowerPCInlineAsmRegClass::lr
+                | PowerPCInlineAsmRegClass::xer,
+            ) => {
                 unreachable!("clobber-only")
             }
             RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -830,7 +835,12 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
         PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
         PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
         PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
-        PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
+        PowerPC(
+            PowerPCInlineAsmRegClass::cr
+            | PowerPCInlineAsmRegClass::ctr
+            | PowerPCInlineAsmRegClass::lr
+            | PowerPCInlineAsmRegClass::xer,
+        ) => {
             unreachable!("clobber-only")
         }
         RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index c4881f0aafc..1950b8288d1 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -204,6 +204,9 @@ pub(crate) fn target_machine_factory(
     optlvl: config::OptLevel,
     target_features: &[String],
 ) -> TargetMachineFactoryFn<LlvmCodegenBackend> {
+    // Self-profile timer for creating a _factory_.
+    let _prof_timer = sess.prof.generic_activity("target_machine_factory");
+
     let reloc_model = to_llvm_relocation_model(sess.relocation_model());
 
     let (opt_level, _) = to_llvm_opt_settings(optlvl);
@@ -259,6 +262,9 @@ pub(crate) fn target_machine_factory(
         .into_string()
         .unwrap_or_default();
     let command_line_args = quote_command_line_args(&sess.expanded_args);
+    // Self-profile counter for the number of bytes produced by command-line quoting.
+    // Values are summed, so the summary result is cumulative across all TM factories.
+    sess.prof.artifact_size("quoted_command_line_args", "-", command_line_args.len() as u64);
 
     let debuginfo_compression = sess.opts.debuginfo_compression.to_string();
     match sess.opts.debuginfo_compression {
@@ -281,7 +287,11 @@ pub(crate) fn target_machine_factory(
 
     let use_wasm_eh = wants_wasm_eh(sess);
 
+    let prof = SelfProfilerRef::clone(&sess.prof);
     Arc::new(move |config: TargetMachineFactoryConfig| {
+        // Self-profile timer for invoking a factory to create a target machine.
+        let _prof_timer = prof.generic_activity("target_machine_factory_inner");
+
         let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
             let path = path.unwrap_or_default();
             let path = path_mapping
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e7f4a357048..50398a32142 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -18,7 +18,6 @@ use rustc_middle::{bug, span_bug};
 use rustc_span::{Span, Symbol, sym};
 use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
 use rustc_target::callconv::PassMode;
-use rustc_target::spec::PanicStrategy;
 use tracing::debug;
 
 use crate::abi::FnAbiLlvmExt;
@@ -674,7 +673,7 @@ fn catch_unwind_intrinsic<'ll, 'tcx>(
     catch_func: &'ll Value,
     dest: PlaceRef<'tcx, &'ll Value>,
 ) {
-    if bx.sess().panic_strategy() == PanicStrategy::Abort {
+    if !bx.sess().panic_strategy().unwinds() {
         let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
         bx.call(try_func_ty, None, None, try_func, &[data], None, None);
         // Return 0 unconditionally from the intrinsic call;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 9a86e4373d8..fd972f371df 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -710,6 +710,7 @@ pub(crate) enum MemoryEffects {
     None,
     ReadOnly,
     InaccessibleMemOnly,
+    ReadOnlyNotPure,
 }
 
 /// LLVMOpcode
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 45c5c9aa551..3b920168e06 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -106,7 +106,7 @@ unsafe fn configure_llvm(sess: &Session) {
 
         if sess.target.os == "emscripten"
             && !sess.opts.unstable_opts.emscripten_wasm_eh
-            && sess.panic_strategy() == PanicStrategy::Unwind
+            && sess.panic_strategy().unwinds()
         {
             add("-enable-emscripten-cxx-exceptions", false);
         }
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 5462163f4ff..9c5a3d839ce 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -8,9 +8,7 @@ edition = "2024"
 ar_archive_writer = "0.5"
 bitflags = "2.4.1"
 bstr = "1.11.3"
-# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version
-# per crate", so if you change this, you need to also change it in `rustc_llvm` and `rustc_windows_rc`.
-cc = "=1.2.16"
+find-msvc-tools = "0.1.2"
 itertools = "0.12"
 pathdiff = "0.2.0"
 regex = "1.4"
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 48b01ea2df1..d6c304c1b14 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
 use std::process::{Output, Stdio};
 use std::{env, fmt, fs, io, mem, str};
 
-use cc::windows_registry;
+use find_msvc_tools;
 use itertools::Itertools;
 use regex::Regex;
 use rustc_arena::TypedArena;
@@ -47,8 +47,8 @@ use rustc_span::Symbol;
 use rustc_target::spec::crt_objects::CrtObjects;
 use rustc_target::spec::{
     BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault,
-    LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel,
-    SanitizerSet, SplitDebuginfo,
+    LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, RelocModel, RelroLevel, SanitizerSet,
+    SplitDebuginfo,
 };
 use tracing::{debug, info, warn};
 
@@ -877,9 +877,9 @@ fn link_natively(
                     // All Microsoft `link.exe` linking ror codes are
                     // four digit numbers in the range 1000 to 9999 inclusive
                     if is_msvc_link_exe && (code < 1000 || code > 9999) {
-                        let is_vs_installed = windows_registry::find_vs_version().is_ok();
+                        let is_vs_installed = find_msvc_tools::find_vs_version().is_ok();
                         let has_linker =
-                            windows_registry::find_tool(&sess.target.arch, "link.exe").is_some();
+                            find_msvc_tools::find_tool(&sess.target.arch, "link.exe").is_some();
 
                         sess.dcx().emit_note(errors::LinkExeUnexpectedError);
 
@@ -2512,10 +2512,10 @@ fn add_order_independent_options(
     if sess.target.os == "emscripten" {
         cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh {
             "-fwasm-exceptions"
-        } else if sess.panic_strategy() == PanicStrategy::Abort {
-            "-sDISABLE_EXCEPTION_CATCHING=1"
-        } else {
+        } else if sess.panic_strategy().unwinds() {
             "-sDISABLE_EXCEPTION_CATCHING=0"
+        } else {
+            "-sDISABLE_EXCEPTION_CATCHING=1"
         });
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index a2efd420a32..624ab1b5084 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -4,7 +4,7 @@ use std::io::prelude::*;
 use std::path::{Path, PathBuf};
 use std::{env, io, iter, mem, str};
 
-use cc::windows_registry;
+use find_msvc_tools;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::{
     find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
@@ -53,7 +53,7 @@ pub(crate) fn get_linker<'a>(
     self_contained: bool,
     target_cpu: &'a str,
 ) -> Box<dyn Linker + 'a> {
-    let msvc_tool = windows_registry::find_tool(&sess.target.arch, "link.exe");
+    let msvc_tool = find_msvc_tools::find_tool(&sess.target.arch, "link.exe");
 
     // If our linker looks like a batch script on Windows then to execute this
     // we'll need to spawn `cmd` explicitly. This is primarily done to handle
@@ -117,7 +117,6 @@ pub(crate) fn get_linker<'a>(
     if sess.target.is_like_msvc
         && let Some(ref tool) = msvc_tool
     {
-        cmd.args(tool.args());
         for (k, v) in tool.env() {
             if k == "PATH" {
                 new_path.extend(env::split_paths(v));
@@ -845,6 +844,11 @@ impl<'a> Linker for GccLinker<'a> {
                 self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error });
             }
             self.link_arg("--dynamic-list").link_arg(path);
+        } else if self.sess.target.is_like_wasm {
+            self.link_arg("--no-export-dynamic");
+            for (sym, _) in symbols {
+                self.link_arg("--export").link_arg(sym);
+            }
         } else {
             // Write an LD version script
             let res: io::Result<()> = try {
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index d2b275ad20a..70d796cda11 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -5,7 +5,7 @@ use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, PResult};
 use rustc_macros::{Decodable, Encodable};
 use rustc_session::parse::ParseSess;
-use rustc_span::{Ident, Span, Symbol};
+use rustc_span::{Ident, Span, Symbol, sym};
 
 use crate::errors;
 
@@ -69,15 +69,15 @@ impl MetaVarExpr {
         }
 
         let mut iter = args.iter();
-        let rslt = match ident.as_str() {
-            "concat" => parse_concat(&mut iter, psess, outer_span, ident.span)?,
-            "count" => parse_count(&mut iter, psess, ident.span)?,
-            "ignore" => {
+        let rslt = match ident.name {
+            sym::concat => parse_concat(&mut iter, psess, outer_span, ident.span)?,
+            sym::count => parse_count(&mut iter, psess, ident.span)?,
+            sym::ignore => {
                 eat_dollar(&mut iter, psess, ident.span)?;
                 MetaVarExpr::Ignore(parse_ident(&mut iter, psess, ident.span)?)
             }
-            "index" => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?),
-            "len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?),
+            sym::index => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?),
+            sym::len => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?),
             _ => {
                 let err = errors::MveUnrecognizedExpr {
                     span: ident.span,
@@ -119,14 +119,13 @@ fn check_trailing_tokens<'psess>(
     }
 
     // `None` for max indicates the arg count must be exact, `Some` indicates a range is accepted.
-    let (min_or_exact_args, max_args) = match ident.as_str() {
-        "concat" => panic!("concat takes unlimited tokens but didn't eat them all"),
-        "ignore" => (1, None),
+    let (min_or_exact_args, max_args) = match ident.name {
+        sym::concat => panic!("concat takes unlimited tokens but didn't eat them all"),
+        sym::ignore => (1, None),
         // 1 or 2 args
-        "count" => (1, Some(2)),
+        sym::count => (1, Some(2)),
         // 0 or 1 arg
-        "index" => (0, Some(1)),
-        "len" => (0, Some(1)),
+        sym::index | sym::len => (0, Some(1)),
         other => unreachable!("unknown MVEs should be rejected earlier (got `{other}`)"),
     };
 
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index 6a3f1f62c91..dddd62a4945 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -375,6 +375,19 @@ fn transcribe_metavar<'tx>(
         return Ok(());
     };
 
+    let MatchedSingle(pnr) = cur_matched else {
+        // We were unable to descend far enough. This is an error.
+        return Err(dcx.create_err(MacroVarStillRepeating { span: sp, ident }));
+    };
+
+    transcribe_pnr(tscx, sp, pnr)
+}
+
+fn transcribe_pnr<'tx>(
+    tscx: &mut TranscrCtx<'tx, '_>,
+    mut sp: Span,
+    pnr: &ParseNtResult,
+) -> PResult<'tx, ()> {
     // We wrap the tokens in invisible delimiters, unless they are already wrapped
     // in invisible delimiters with the same `MetaVarKind`. Because some proc
     // macros can't handle multiple layers of invisible delimiters of the same
@@ -404,33 +417,33 @@ fn transcribe_metavar<'tx>(
         )
     };
 
-    let tt = match cur_matched {
-        MatchedSingle(ParseNtResult::Tt(tt)) => {
+    let tt = match pnr {
+        ParseNtResult::Tt(tt) => {
             // `tt`s are emitted into the output stream directly as "raw tokens",
             // without wrapping them into groups. Other variables are emitted into
             // the output stream as groups with `Delimiter::Invisible` to maintain
             // parsing priorities.
             maybe_use_metavar_location(tscx.psess, &tscx.stack, sp, tt, &mut tscx.marker)
         }
-        MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => {
+        ParseNtResult::Ident(ident, is_raw) => {
             tscx.marker.mark_span(&mut sp);
             with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
             let kind = token::NtIdent(*ident, *is_raw);
             TokenTree::token_alone(kind, sp)
         }
-        MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
+        ParseNtResult::Lifetime(ident, is_raw) => {
             tscx.marker.mark_span(&mut sp);
             with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
             let kind = token::NtLifetime(*ident, *is_raw);
             TokenTree::token_alone(kind, sp)
         }
-        MatchedSingle(ParseNtResult::Item(item)) => {
+        ParseNtResult::Item(item) => {
             mk_delimited(item.span, MetaVarKind::Item, TokenStream::from_ast(item))
         }
-        MatchedSingle(ParseNtResult::Block(block)) => {
+        ParseNtResult::Block(block) => {
             mk_delimited(block.span, MetaVarKind::Block, TokenStream::from_ast(block))
         }
-        MatchedSingle(ParseNtResult::Stmt(stmt)) => {
+        ParseNtResult::Stmt(stmt) => {
             let stream = if let StmtKind::Empty = stmt.kind {
                 // FIXME: Properly collect tokens for empty statements.
                 TokenStream::token_alone(token::Semi, stmt.span)
@@ -439,10 +452,10 @@ fn transcribe_metavar<'tx>(
             };
             mk_delimited(stmt.span, MetaVarKind::Stmt, stream)
         }
-        MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => {
+        ParseNtResult::Pat(pat, pat_kind) => {
             mk_delimited(pat.span, MetaVarKind::Pat(*pat_kind), TokenStream::from_ast(pat))
         }
-        MatchedSingle(ParseNtResult::Expr(expr, kind)) => {
+        ParseNtResult::Expr(expr, kind) => {
             let (can_begin_literal_maybe_minus, can_begin_string_literal) = match &expr.kind {
                 ExprKind::Lit(_) => (true, true),
                 ExprKind::Unary(UnOp::Neg, e) if matches!(&e.kind, ExprKind::Lit(_)) => {
@@ -460,14 +473,14 @@ fn transcribe_metavar<'tx>(
                 TokenStream::from_ast(expr),
             )
         }
-        MatchedSingle(ParseNtResult::Literal(lit)) => {
+        ParseNtResult::Literal(lit) => {
             mk_delimited(lit.span, MetaVarKind::Literal, TokenStream::from_ast(lit))
         }
-        MatchedSingle(ParseNtResult::Ty(ty)) => {
+        ParseNtResult::Ty(ty) => {
             let is_path = matches!(&ty.kind, TyKind::Path(None, _path));
             mk_delimited(ty.span, MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty))
         }
-        MatchedSingle(ParseNtResult::Meta(attr_item)) => {
+        ParseNtResult::Meta(attr_item) => {
             let has_meta_form = attr_item.meta_kind().is_some();
             mk_delimited(
                 attr_item.span(),
@@ -475,16 +488,12 @@ fn transcribe_metavar<'tx>(
                 TokenStream::from_ast(attr_item),
             )
         }
-        MatchedSingle(ParseNtResult::Path(path)) => {
+        ParseNtResult::Path(path) => {
             mk_delimited(path.span, MetaVarKind::Path, TokenStream::from_ast(path))
         }
-        MatchedSingle(ParseNtResult::Vis(vis)) => {
+        ParseNtResult::Vis(vis) => {
             mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis))
         }
-        MatchedSeq(..) => {
-            // We were unable to descend far enough. This is an error.
-            return Err(dcx.create_err(MacroVarStillRepeating { span: sp, ident }));
-        }
     };
 
     tscx.result.push(tt);
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index aa2d27ab809..6faa67f6a90 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -64,83 +64,151 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
         // it's usually worth updating that intrinsic's documentation
         // to note that it's safe to call, since
         // safe extern fns are otherwise unprecedented.
-        sym::abort
+
+        // tidy-alphabetical-start
+        | sym::abort
+        | sym::add_with_overflow
+        | sym::aggregate_raw_ptr
+        | sym::align_of
         | sym::assert_inhabited
-        | sym::assert_zero_valid
         | sym::assert_mem_uninitialized_valid
+        | sym::assert_zero_valid
+        | sym::autodiff
+        | sym::bitreverse
+        | sym::black_box
         | sym::box_new
         | sym::breakpoint
-        | sym::size_of
-        | sym::align_of
-        | sym::needs_drop
+        | sym::bswap
         | sym::caller_location
-        | sym::add_with_overflow
-        | sym::sub_with_overflow
-        | sym::mul_with_overflow
         | sym::carrying_mul_add
-        | sym::wrapping_add
-        | sym::wrapping_sub
-        | sym::wrapping_mul
-        | sym::saturating_add
-        | sym::saturating_sub
-        | sym::rotate_left
-        | sym::rotate_right
-        | sym::ctpop
+        | sym::ceilf16
+        | sym::ceilf32
+        | sym::ceilf64
+        | sym::ceilf128
+        | sym::cold_path
+        | sym::const_eval_select
+        | sym::contract_check_ensures
+        | sym::contract_check_requires
+        | sym::contract_checks
+        | sym::cosf16
+        | sym::cosf32
+        | sym::cosf64
+        | sym::cosf128
         | sym::ctlz
+        | sym::ctpop
         | sym::cttz
-        | sym::bswap
-        | sym::bitreverse
-        | sym::three_way_compare
         | sym::discriminant_value
-        | sym::type_id
-        | sym::type_id_eq
-        | sym::select_unpredictable
-        | sym::cold_path
-        | sym::ptr_guaranteed_cmp
-        | sym::minnumf16
-        | sym::minnumf32
-        | sym::minnumf64
-        | sym::minnumf128
-        | sym::minimumf16
-        | sym::minimumf32
-        | sym::minimumf64
-        | sym::minimumf128
-        | sym::maxnumf16
-        | sym::maxnumf32
-        | sym::maxnumf64
-        | sym::maxnumf128
+        | sym::exp2f16
+        | sym::exp2f32
+        | sym::exp2f64
+        | sym::exp2f128
+        | sym::expf16
+        | sym::expf32
+        | sym::expf64
+        | sym::expf128
+        | sym::fadd_algebraic
+        | sym::fdiv_algebraic
+        | sym::floorf16
+        | sym::floorf32
+        | sym::floorf64
+        | sym::floorf128
+        | sym::fmaf16
+        | sym::fmaf32
+        | sym::fmaf64
+        | sym::fmaf128
+        | sym::fmul_algebraic
+        | sym::fmuladdf16
+        | sym::fmuladdf32
+        | sym::fmuladdf64
+        | sym::fmuladdf128
+        | sym::forget
+        | sym::frem_algebraic
+        | sym::fsub_algebraic
+        | sym::is_val_statically_known
+        | sym::log2f16
+        | sym::log2f32
+        | sym::log2f64
+        | sym::log2f128
+        | sym::log10f16
+        | sym::log10f32
+        | sym::log10f64
+        | sym::log10f128
+        | sym::logf16
+        | sym::logf32
+        | sym::logf64
+        | sym::logf128
         | sym::maximumf16
         | sym::maximumf32
         | sym::maximumf64
         | sym::maximumf128
-        | sym::rustc_peek
-        | sym::type_name
-        | sym::forget
-        | sym::black_box
-        | sym::variant_count
-        | sym::is_val_statically_known
+        | sym::maxnumf16
+        | sym::maxnumf32
+        | sym::maxnumf64
+        | sym::maxnumf128
+        | sym::minimumf16
+        | sym::minimumf32
+        | sym::minimumf64
+        | sym::minimumf128
+        | sym::minnumf16
+        | sym::minnumf32
+        | sym::minnumf64
+        | sym::minnumf128
+        | sym::mul_with_overflow
+        | sym::needs_drop
+        | sym::powf16
+        | sym::powf32
+        | sym::powf64
+        | sym::powf128
+        | sym::powif16
+        | sym::powif32
+        | sym::powif64
+        | sym::powif128
+        | sym::prefetch_read_data
+        | sym::prefetch_read_instruction
+        | sym::prefetch_write_data
+        | sym::prefetch_write_instruction
+        | sym::ptr_guaranteed_cmp
         | sym::ptr_mask
-        | sym::aggregate_raw_ptr
         | sym::ptr_metadata
-        | sym::ub_checks
-        | sym::contract_checks
-        | sym::contract_check_requires
-        | sym::contract_check_ensures
-        | sym::fadd_algebraic
-        | sym::fsub_algebraic
-        | sym::fmul_algebraic
-        | sym::fdiv_algebraic
-        | sym::frem_algebraic
+        | sym::rotate_left
+        | sym::rotate_right
         | sym::round_ties_even_f16
         | sym::round_ties_even_f32
         | sym::round_ties_even_f64
         | sym::round_ties_even_f128
-        | sym::autodiff
-        | sym::prefetch_read_data
-        | sym::prefetch_write_data
-        | sym::prefetch_read_instruction
-        | sym::prefetch_write_instruction
-        | sym::const_eval_select => hir::Safety::Safe,
+        | sym::roundf16
+        | sym::roundf32
+        | sym::roundf64
+        | sym::roundf128
+        | sym::rustc_peek
+        | sym::saturating_add
+        | sym::saturating_sub
+        | sym::select_unpredictable
+        | sym::sinf16
+        | sym::sinf32
+        | sym::sinf64
+        | sym::sinf128
+        | sym::size_of
+        | sym::sqrtf16
+        | sym::sqrtf32
+        | sym::sqrtf64
+        | sym::sqrtf128
+        | sym::sub_with_overflow
+        | sym::three_way_compare
+        | sym::truncf16
+        | sym::truncf32
+        | sym::truncf64
+        | sym::truncf128
+        | sym::type_id
+        | sym::type_id_eq
+        | sym::type_name
+        | sym::ub_checks
+        | sym::variant_count
+        | sym::wrapping_add
+        | sym::wrapping_mul
+        | sym::wrapping_sub
+        // tidy-alphabetical-end
+        => hir::Safety::Safe,
         _ => hir::Safety::Unsafe,
     };
 
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index f735c0a4160..46accb76a18 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -47,7 +47,7 @@ You can read more about trait objects in the Trait Objects section of the Refere
 https://doc.rust-lang.org/reference/types.html#trait-objects";
 
 fn is_number(text: &str) -> bool {
-    text.chars().all(|c: char| c.is_digit(10))
+    text.chars().all(|c: char| c.is_ascii_digit())
 }
 
 /// Information about the expected type at the top level of type checking a pattern.
@@ -262,8 +262,9 @@ enum InheritedRefMatchRule {
         /// pattern matches a given type:
         /// - If the underlying type is not a reference, a reference pattern may eat the inherited reference;
         /// - If the underlying type is a reference, a reference pattern matches if it can eat either one
-        ///    of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the
-        ///    underlying type is `&mut` or the inherited reference is `&mut`.
+        ///   of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the
+        ///   underlying type is `&mut` or the inherited reference is `&mut`.
+        ///
         /// If `false`, a reference pattern is only matched against the underlying type.
         /// This is `false` for stable Rust and `true` for both the `ref_pat_eat_one_layer_2024` and
         /// `ref_pat_eat_one_layer_2024_structural` feature gates.
@@ -1069,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     if !self.tcx.features().mut_ref() {
                         feature_err(
-                            &self.tcx.sess,
+                            self.tcx.sess,
                             sym::mut_ref,
                             pat.span.until(ident.span),
                             "binding cannot be both mutable and by-reference",
@@ -1487,31 +1488,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         opt_def_id: Option<hir::def_id::DefId>,
         ident: Ident,
     ) -> bool {
-        match opt_def_id {
-            Some(def_id) => match self.tcx.hir_get_if_local(def_id) {
-                Some(hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Const(_, _, _, body_id),
-                    ..
-                })) => match self.tcx.hir_node(body_id.hir_id) {
-                    hir::Node::Expr(expr) => {
-                        if hir::is_range_literal(expr) {
-                            let span = self.tcx.hir_span(body_id.hir_id);
-                            if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) {
-                                e.span_suggestion_verbose(
-                                    ident.span,
-                                    "you may want to move the range into the match block",
-                                    snip,
-                                    Applicability::MachineApplicable,
-                                );
-                                return true;
-                            }
-                        }
-                    }
-                    _ => (),
-                },
-                _ => (),
-            },
-            _ => (),
+        if let Some(def_id) = opt_def_id
+            && let Some(hir::Node::Item(hir::Item {
+                kind: hir::ItemKind::Const(_, _, _, body_id),
+                ..
+            })) = self.tcx.hir_get_if_local(def_id)
+            && let hir::Node::Expr(expr) = self.tcx.hir_node(body_id.hir_id)
+            && hir::is_range_literal(expr)
+        {
+            let span = self.tcx.hir_span(body_id.hir_id);
+            if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) {
+                e.span_suggestion_verbose(
+                    ident.span,
+                    "you may want to move the range into the match block",
+                    snip,
+                    Applicability::MachineApplicable,
+                );
+                return true;
+            }
         }
         false
     }
@@ -1529,7 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(span) = self.tcx.hir_res_span(pat_res) {
             e.span_label(span, format!("{} defined here", res.descr()));
-            if let [hir::PathSegment { ident, .. }] = &*segments {
+            if let [hir::PathSegment { ident, .. }] = segments {
                 e.span_label(
                     pat_span,
                     format!(
@@ -1557,17 +1551,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             _ => (None, None),
                         };
 
-                        let is_range = match type_def_id.and_then(|id| self.tcx.as_lang_item(id)) {
+                        let is_range = matches!(
+                            type_def_id.and_then(|id| self.tcx.as_lang_item(id)),
                             Some(
                                 LangItem::Range
-                                | LangItem::RangeFrom
-                                | LangItem::RangeTo
-                                | LangItem::RangeFull
-                                | LangItem::RangeInclusiveStruct
-                                | LangItem::RangeToInclusive,
-                            ) => true,
-                            _ => false,
-                        };
+                                    | LangItem::RangeFrom
+                                    | LangItem::RangeTo
+                                    | LangItem::RangeFull
+                                    | LangItem::RangeInclusiveStruct
+                                    | LangItem::RangeToInclusive,
+                            )
+                        );
                         if is_range {
                             if !self.maybe_suggest_range_literal(&mut e, item_def_id, *ident) {
                                 let msg = "constants only support matching by type, \
diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl
index 6f6666f8c76..1f5c5e74d97 100644
--- a/compiler/rustc_interface/messages.ftl
+++ b/compiler/rustc_interface/messages.ftl
@@ -47,7 +47,7 @@ interface_out_dir_error =
     failed to find or create the directory specified by `--out-dir`
 
 interface_proc_macro_crate_panic_abort =
-    building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
+    building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic
 
 interface_temps_dir_error =
     failed to find or create the directory specified by `--temps-dir`
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 6cefe887530..761a5c80918 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -42,7 +42,6 @@ use rustc_span::{
     DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, SourceFileHash, SourceFileHashAlgorithm, Span,
     Symbol, sym,
 };
-use rustc_target::spec::PanicStrategy;
 use rustc_trait_selection::{solve, traits};
 use tracing::{info, instrument};
 
@@ -282,7 +281,7 @@ fn configure_and_expand(
         feature_err(sess, sym::export_stable, DUMMY_SP, "`sdylib` crate type is unstable").emit();
     }
 
-    if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort {
+    if is_proc_macro_crate && !sess.panic_strategy().unwinds() {
         sess.dcx().emit_warn(errors::ProcMacroCratePanicAbort);
     }
 
diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 0dfd1b13df5..ad93c745381 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -10,8 +10,7 @@ libc = "0.2.73"
 
 [build-dependencies]
 # tidy-alphabetical-start
-# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version
-# per crate", so if you change this, you need to also change it in `rustc_codegen_ssa` and `rustc_windows_rc`.
+# `cc` updates often break things, so we pin it here.
 cc = "=1.2.16"
 # tidy-alphabetical-end
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 64151962321..414274f24fb 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -553,6 +553,7 @@ enum class LLVMRustMemoryEffects {
   None,
   ReadOnly,
   InaccessibleMemOnly,
+  ReadOnlyNotPure,
 };
 
 extern "C" LLVMAttributeRef
@@ -568,6 +569,10 @@ LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
   case LLVMRustMemoryEffects::InaccessibleMemOnly:
     return wrap(Attribute::getWithMemoryEffects(
         *unwrap(C), MemoryEffects::inaccessibleMemOnly()));
+  case LLVMRustMemoryEffects::ReadOnlyNotPure:
+    return wrap(Attribute::getWithMemoryEffects(
+        *unwrap(C),
+        MemoryEffects::readOnly() | MemoryEffects::inaccessibleMemOnly()));
   default:
     report_fatal_error("bad MemoryEffects.");
   }
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index e104be2c466..e624bfc5b8b 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -98,6 +98,13 @@ metadata_full_metadata_not_found =
 metadata_global_alloc_required =
     no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
 
+metadata_incompatible_with_immediate_abort =
+    the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+metadata_incompatible_with_immediate_abort_core =
+    the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
+    .help = consider building the standard library from source with `cargo build -Zbuild-std`
+
 metadata_incompatible_panic_in_drop_strategy =
     the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 9e23da88f5e..7650acbd292 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -1027,6 +1027,10 @@ impl CStore {
         let name = match desired_strategy {
             PanicStrategy::Unwind => sym::panic_unwind,
             PanicStrategy::Abort => sym::panic_abort,
+            PanicStrategy::ImmediateAbort => {
+                // Immediate-aborting panics don't use a runtime.
+                return;
+            }
         };
         info!("panic runtime not found -- loading {}", name);
 
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index fb9c2e23b71..8054a48d37a 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -61,11 +61,13 @@ use rustc_session::config::CrateType;
 use rustc_session::cstore::CrateDepKind;
 use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
 use rustc_span::sym;
+use rustc_target::spec::PanicStrategy;
 use tracing::info;
 
 use crate::creader::CStore;
 use crate::errors::{
-    BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
+    BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy,
+    IncompatibleWithImmediateAbort, IncompatibleWithImmediateAbortCore, LibRequired,
     NonStaticCrateDep, RequiredPanicStrategy, RlibRequired, RustcDriverHelp, RustcLibRequired,
     TwoPanicRuntimes,
 };
@@ -402,15 +404,43 @@ fn activate_injected_dep(
 /// there's only going to be one panic runtime in the output.
 fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
     let sess = &tcx.sess;
+    let list: Vec<_> = list
+        .iter_enumerated()
+        .filter_map(
+            |(cnum, linkage)| if *linkage == Linkage::NotLinked { None } else { Some(cnum) },
+        )
+        .collect();
     if list.is_empty() {
         return;
     }
-    let mut panic_runtime = None;
-    for (cnum, linkage) in list.iter_enumerated() {
-        if let Linkage::NotLinked = *linkage {
-            continue;
+    let desired_strategy = sess.panic_strategy();
+
+    // If we are panic=immediate-abort, make sure everything in the dependency tree has also been
+    // compiled with immediate-abort.
+    if list
+        .iter()
+        .any(|cnum| tcx.required_panic_strategy(*cnum) == Some(PanicStrategy::ImmediateAbort))
+    {
+        let mut invalid_crates = Vec::new();
+        for cnum in list.iter().copied() {
+            if tcx.required_panic_strategy(cnum) != Some(PanicStrategy::ImmediateAbort) {
+                invalid_crates.push(cnum);
+                // If core is incompatible, it's very likely that we'd emit an error for every
+                // sysroot crate, so instead of doing that emit a single fatal error that suggests
+                // using build-std.
+                if tcx.crate_name(cnum) == sym::core {
+                    sess.dcx().emit_fatal(IncompatibleWithImmediateAbortCore);
+                }
+            }
         }
+        for cnum in invalid_crates {
+            sess.dcx()
+                .emit_err(IncompatibleWithImmediateAbort { crate_name: tcx.crate_name(cnum) });
+        }
+    }
 
+    let mut panic_runtime = None;
+    for cnum in list.iter().copied() {
         if tcx.is_panic_runtime(cnum) {
             if let Some((prev, _)) = panic_runtime {
                 let prev_name = tcx.crate_name(prev);
@@ -430,8 +460,6 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
     // only one, but we perform validation here that all the panic strategy
     // compilation modes for the whole DAG are valid.
     if let Some((runtime_cnum, found_strategy)) = panic_runtime {
-        let desired_strategy = sess.panic_strategy();
-
         // First up, validate that our selected panic runtime is indeed exactly
         // our same strategy.
         if found_strategy != desired_strategy {
@@ -445,10 +473,7 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
         // strategy. If the dep isn't linked, we ignore it, and if our strategy
         // is abort then it's compatible with everything. Otherwise all crates'
         // panic strategy must match our own.
-        for (cnum, linkage) in list.iter_enumerated() {
-            if let Linkage::NotLinked = *linkage {
-                continue;
-            }
+        for cnum in list.iter().copied() {
             if cnum == runtime_cnum || tcx.is_compiler_builtins(cnum) {
                 continue;
             }
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index e5a4fd48353..abfd078f746 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -76,6 +76,16 @@ pub struct RequiredPanicStrategy {
 }
 
 #[derive(Diagnostic)]
+#[diag(metadata_incompatible_with_immediate_abort)]
+pub struct IncompatibleWithImmediateAbort {
+    pub crate_name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(metadata_incompatible_with_immediate_abort_core)]
+pub struct IncompatibleWithImmediateAbortCore;
+
+#[derive(Diagnostic)]
 #[diag(metadata_incompatible_panic_in_drop_strategy)]
 pub struct IncompatiblePanicInDropStrategy {
     pub crate_name: Symbol,
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index 93264f02cc2..a0e4c288c4a 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -98,5 +98,6 @@ pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
             lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
         }
         PanicStrategy::Unwind => true,
+        PanicStrategy::ImmediateAbort => false,
     }
 }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index c477e65f5d6..47b45c58b9f 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -16,7 +16,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension};
 use rustc_session::config::OptLevel;
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
 use rustc_target::callconv::FnAbi;
-use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, PanicStrategy, Target, X86Abi};
+use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
 use tracing::debug;
 use {rustc_abi as abi, rustc_hir as hir};
 
@@ -1198,7 +1198,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
         //
         // Note that this is true regardless ABI specified on the function -- a `extern "C-unwind"`
         // function defined in Rust is also required to abort.
-        if tcx.sess.panic_strategy() == PanicStrategy::Abort && !tcx.is_foreign_item(did) {
+        if !tcx.sess.panic_strategy().unwinds() && !tcx.is_foreign_item(did) {
             return false;
         }
 
@@ -1206,7 +1206,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
         //
         // This is not part of `codegen_fn_attrs` as it can differ between crates
         // and therefore cannot be computed in core.
-        if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort
+        if !tcx.sess.opts.unstable_opts.panic_in_drop.unwinds()
             && tcx.is_lang_item(did, LangItem::DropInPlace)
         {
             return false;
@@ -1245,7 +1245,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
         | RiscvInterruptS
         | RustInvalid
         | Unadjusted => false,
-        Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
+        Rust | RustCall | RustCold => tcx.sess.panic_strategy().unwinds(),
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index c1cd2788348..c5cd06f170c 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -86,7 +86,6 @@ use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::source_map::dummy_spanned;
 use rustc_span::symbol::sym;
 use rustc_span::{DUMMY_SP, Span};
-use rustc_target::spec::PanicStrategy;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::infer::TyCtxtInferExt as _;
 use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
@@ -1149,7 +1148,7 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, typing_env: ty::Typing
 
 fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
     // Nothing can unwind when landing pads are off.
-    if tcx.sess.panic_strategy() == PanicStrategy::Abort {
+    if !tcx.sess.panic_strategy().unwinds() {
         return false;
     }
 
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index abbff1c48dd..7c66783548e 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -101,12 +101,15 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
 }
 
 fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrategy> {
+    let local_strategy = tcx.sess.panic_strategy();
+
     if tcx.is_panic_runtime(LOCAL_CRATE) {
-        return Some(tcx.sess.panic_strategy());
+        return Some(local_strategy);
     }
 
-    if tcx.sess.panic_strategy() == PanicStrategy::Abort {
-        return Some(PanicStrategy::Abort);
+    match local_strategy {
+        PanicStrategy::Abort | PanicStrategy::ImmediateAbort => return Some(local_strategy),
+        _ => {}
     }
 
     for def_id in tcx.hir_body_owners() {
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 5b6d7ffb511..b53c1f6d202 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -1,7 +1,6 @@
 use rustc_index::bit_set::DenseBitSet;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
-use rustc_target::spec::PanicStrategy;
 use tracing::debug;
 
 use crate::patch::MirPatch;
@@ -13,7 +12,7 @@ pub(super) struct RemoveNoopLandingPads;
 
 impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.panic_strategy() != PanicStrategy::Abort
+        sess.panic_strategy().unwinds()
     }
 
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 795cb2b2cfe..81ada79dd43 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -29,7 +29,8 @@ use rustc_span::{
     SourceFileHashAlgorithm, Symbol, sym,
 };
 use rustc_target::spec::{
-    FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
+    FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
+    Target, TargetTuple,
 };
 use tracing::debug;
 
@@ -2799,6 +2800,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
         }
     }
 
+    if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
+        early_dcx.early_fatal(
+            "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
+        )
+    }
+
     let crate_name = matches.opt_str("crate-name");
     let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
     // Parse any `-l` flags, which link to native libraries.
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
index 7e970461ab7..f3d91ce4a5d 100644
--- a/compiler/rustc_session/src/config/cfg.rs
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -125,7 +125,9 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
                 None | Some(_),
             ) => disallow(cfg, "-Z sanitizer=cfi"),
             (sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"),
-            (sym::panic, Some(sym::abort | sym::unwind)) => disallow(cfg, "-C panic"),
+            (sym::panic, Some(sym::abort | sym::unwind | sym::immediate_abort)) => {
+                disallow(cfg, "-C panic")
+            }
             (sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"),
             (sym::unix, None)
             | (sym::windows, None)
@@ -203,7 +205,14 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
         ins_none!(sym::overflow_checks);
     }
 
+    // We insert a cfg for the name of session's panic strategy.
+    // Since the ImmediateAbort strategy is new, it also sets cfg(panic="abort"), so that code
+    // which is trying to detect whether unwinding is enabled by checking for cfg(panic="abort")
+    // does not need to be updated.
     ins_sym!(sym::panic, sess.panic_strategy().desc_symbol());
+    if sess.panic_strategy() == PanicStrategy::ImmediateAbort {
+        ins_sym!(sym::panic, PanicStrategy::Abort.desc_symbol());
+    }
 
     // JUSTIFICATION: before wrapper fn is available
     #[allow(rustc::bad_opt_access)]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 69facde6936..3b9d8117786 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -802,7 +802,7 @@ mod desc {
     pub(crate) const parse_threads: &str = parse_number;
     pub(crate) const parse_time_passes_format: &str = "`text` (default) or `json`";
     pub(crate) const parse_passes: &str = "a space-separated list of passes, or `all`";
-    pub(crate) const parse_panic_strategy: &str = "either `unwind` or `abort`";
+    pub(crate) const parse_panic_strategy: &str = "either `unwind`, `abort`, or `immediate-abort`";
     pub(crate) const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
     pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)";
     pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
@@ -1165,6 +1165,7 @@ pub mod parse {
         match v {
             Some("unwind") => *slot = Some(PanicStrategy::Unwind),
             Some("abort") => *slot = Some(PanicStrategy::Abort),
+            Some("immediate-abort") => *slot = Some(PanicStrategy::ImmediateAbort),
             _ => return false,
         }
         true
@@ -1174,6 +1175,7 @@ pub mod parse {
         match v {
             Some("unwind") => *slot = PanicStrategy::Unwind,
             Some("abort") => *slot = PanicStrategy::Abort,
+            Some("immediate-abort") => *slot = PanicStrategy::ImmediateAbort,
             _ => return false,
         }
         true
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index d0dd2cdac0c..25b46241c52 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -777,9 +777,11 @@ impl Session {
         // Otherwise, we can defer to the `-C force-unwind-tables=<yes/no>`
         // value, if it is provided, or disable them, if not.
         self.target.requires_uwtable
-            || self.opts.cg.force_unwind_tables.unwrap_or(
-                self.panic_strategy() == PanicStrategy::Unwind || self.target.default_uwtable,
-            )
+            || self
+                .opts
+                .cg
+                .force_unwind_tables
+                .unwrap_or(self.panic_strategy().unwinds() || self.target.default_uwtable)
     }
 
     /// Returns the number of query threads that should be used for this
@@ -1229,7 +1231,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     }
 
     // KCFI requires panic=abort
-    if sess.is_sanitizer_kcfi_enabled() && sess.panic_strategy() != PanicStrategy::Abort {
+    if sess.is_sanitizer_kcfi_enabled() && sess.panic_strategy().unwinds() {
         sess.dcx().emit_err(errors::SanitizerKcfiRequiresPanicAbort);
     }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4fef65f46b1..4e48c96afd6 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -794,6 +794,7 @@ symbols! {
         ctlz,
         ctlz_nonzero,
         ctpop,
+        ctr,
         cttz,
         cttz_nonzero,
         custom_attribute,
@@ -1195,6 +1196,7 @@ symbols! {
         if_let_rescope,
         if_while_or_patterns,
         ignore,
+        immediate_abort: "immediate-abort",
         impl_header_lifetime_elision,
         impl_lint_pass,
         impl_trait_in_assoc_type,
@@ -1333,6 +1335,7 @@ symbols! {
         loongarch_target_feature,
         loop_break_value,
         loop_match,
+        lr,
         lt,
         m68k_target_feature,
         macro_at_most_once_rep,
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index e06f881e4b1..0601613567e 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -1260,11 +1260,12 @@ impl InlineAsmClobberAbi {
                     v8, v9, v10, v11, v12, v13, v14,
                     v15, v16, v17, v18, v19,
 
-                    // cr0-cr1, cr5-cr7, xer
+                    // cr0-cr1, cr5-cr7, ctr, lr, xer
                     cr0, cr1,
                     cr5, cr6, cr7,
+                    ctr,
+                    lr,
                     xer,
-                    // lr and ctr are reserved
                 }
             },
             InlineAsmClobberAbi::S390x => clobbered_regs! {
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs
index f3934afa6d9..2348a0fd202 100644
--- a/compiler/rustc_target/src/asm/powerpc.rs
+++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -13,6 +13,8 @@ def_reg_class! {
         freg,
         vreg,
         cr,
+        ctr,
+        lr,
         xer,
     }
 }
@@ -56,7 +58,7 @@ impl PowerPCInlineAsmRegClass {
                 altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4);
                 vsx: F32, F64, VecI64(2), VecF64(2);
             },
-            Self::cr | Self::xer => &[],
+            Self::cr | Self::ctr | Self::lr | Self::xer => &[],
         }
     }
 }
@@ -195,6 +197,8 @@ def_regs! {
         cr5: cr = ["cr5"],
         cr6: cr = ["cr6"],
         cr7: cr = ["cr7"],
+        ctr: ctr = ["ctr"],
+        lr: lr = ["lr"],
         xer: xer = ["xer"],
         #error = ["r1", "1", "sp"] =>
             "the stack pointer cannot be used as an operand for inline asm",
@@ -206,10 +210,6 @@ def_regs! {
             "r30 is used internally by LLVM and cannot be used as an operand for inline asm",
         #error = ["r31", "31", "fp"] =>
             "the frame pointer cannot be used as an operand for inline asm",
-        #error = ["lr"] =>
-            "the link register cannot be used as an operand for inline asm",
-        #error = ["ctr"] =>
-            "the counter register cannot be used as an operand for inline asm",
         #error = ["vrsave"] =>
             "the vrsave register cannot be used as an operand for inline asm",
     }
@@ -247,6 +247,8 @@ impl PowerPCInlineAsmReg {
             (v24, "24"), (v25, "25"), (v26, "26"), (v27, "27"), (v28, "28"), (v29, "29"), (v30, "30"), (v31, "31");
             (cr, "cr");
             (cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7");
+            (ctr, "ctr");
+            (lr, "lr");
             (xer, "xer");
         }
     }
diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs
index be15da7329d..6ab8597a4ec 100644
--- a/compiler/rustc_target/src/spec/base/mod.rs
+++ b/compiler/rustc_target/src/spec/base/mod.rs
@@ -21,6 +21,7 @@ pub(crate) mod linux_uclibc;
 pub(crate) mod linux_wasm;
 pub(crate) mod lynxos178;
 pub(crate) mod managarm_mlibc;
+pub(crate) mod motor;
 pub(crate) mod msvc;
 pub(crate) mod netbsd;
 pub(crate) mod nto_qnx;
diff --git a/compiler/rustc_target/src/spec/base/motor.rs b/compiler/rustc_target/src/spec/base/motor.rs
new file mode 100644
index 00000000000..18485b2cef2
--- /dev/null
+++ b/compiler/rustc_target/src/spec/base/motor.rs
@@ -0,0 +1,34 @@
+use crate::spec::{
+    Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions,
+};
+
+pub(crate) fn opts() -> TargetOptions {
+    let pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &[
+            "-e",
+            "motor_start",
+            "--no-undefined",
+            "--error-unresolved-symbols",
+            "--no-undefined-version",
+            "-u",
+            "__rust_abort",
+        ],
+    );
+    TargetOptions {
+        os: "motor".into(),
+        executables: true,
+        // TLS is false below because if true, the compiler assumes
+        // we handle TLS at the ELF loading level, which we don't.
+        // We use "OS level" TLS (see thread/local.rs in stdlib).
+        has_thread_local: false,
+        frame_pointer: FramePointer::NonLeaf,
+        linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
+        main_needs_argc_argv: true,
+        panic_strategy: PanicStrategy::Abort,
+        pre_link_args,
+        stack_probes: StackProbeType::Inline,
+        supports_stack_protector: true,
+        ..Default::default()
+    }
+}
diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs
index 88e7af5e669..7ede45766ea 100644
--- a/compiler/rustc_target/src/spec/base/wasm.rs
+++ b/compiler/rustc_target/src/spec/base/wasm.rs
@@ -81,11 +81,6 @@ pub(crate) fn options() -> TargetOptions {
         // threaded model which will legalize atomics to normal operations.
         singlethread: true,
 
-        // Symbol visibility takes care of this for the WebAssembly.
-        // Additionally the only known linker, LLD, doesn't support the script
-        // arguments just yet
-        limit_rdylib_exports: false,
-
         // we use the LLD shipped with the Rust toolchain by default
         linker: Some("rust-lld".into()),
         linker_flavor: LinkerFlavor::WasmLld(Cc::No),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f705af52bd8..4a82a8bd888 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -834,6 +834,7 @@ crate::target_spec_enum! {
     pub enum PanicStrategy {
         Unwind = "unwind",
         Abort = "abort",
+        ImmediateAbort = "immediate-abort",
     }
 
     parse_error_type = "panic strategy";
@@ -852,8 +853,13 @@ impl PanicStrategy {
         match *self {
             PanicStrategy::Unwind => sym::unwind,
             PanicStrategy::Abort => sym::abort,
+            PanicStrategy::ImmediateAbort => sym::immediate_abort,
         }
     }
+
+    pub fn unwinds(self) -> bool {
+        matches!(self, PanicStrategy::Unwind)
+    }
 }
 
 crate::target_spec_enum! {
@@ -1642,6 +1648,7 @@ supported_targets! {
     ("aarch64-unknown-hermit", aarch64_unknown_hermit),
     ("riscv64gc-unknown-hermit", riscv64gc_unknown_hermit),
     ("x86_64-unknown-hermit", x86_64_unknown_hermit),
+    ("x86_64-unknown-motor", x86_64_unknown_motor),
 
     ("x86_64-unikraft-linux-musl", x86_64_unikraft_linux_musl),
 
diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
index d42e097b0fd..38c3c7dfaa1 100644
--- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs
@@ -5,8 +5,6 @@ pub(crate) fn target() -> Target {
     base.cpu = "mips64r2".into();
     base.features = "+mips64r2,+xgot".into();
     base.max_atomic_width = Some(64);
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
     Target {
         // LLVM doesn't recognize "muslabi64" yet.
         llvm_target: "mips64el-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs
new file mode 100644
index 00000000000..0fd43357a76
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_motor.rs
@@ -0,0 +1,38 @@
+use crate::spec::{
+    CodeModel, LinkSelfContainedDefault, LldFlavor, RelocModel, RelroLevel, Target, base,
+};
+
+pub(crate) fn target() -> Target {
+    let mut base = base::motor::opts();
+    base.cpu = "x86-64".into();
+    base.max_atomic_width = Some(64);
+    base.code_model = Some(CodeModel::Small);
+
+    // We want fully static relocatable binaries. It was surprisingly
+    // difficult to make it happen reliably, especially various
+    // linker-related options below. Mostly trial and error.
+    base.position_independent_executables = true;
+    base.relro_level = RelroLevel::Full;
+    base.static_position_independent_executables = true;
+    base.relocation_model = RelocModel::Pic;
+    base.lld_flavor_json = LldFlavor::Ld;
+    base.link_self_contained = LinkSelfContainedDefault::True;
+    base.dynamic_linking = false;
+    base.crt_static_default = true;
+    base.crt_static_respected = true;
+
+    Target {
+        llvm_target: "x86_64-unknown-none-elf".into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("Motor OS".into()),
+            tier: Some(3),
+            host_tools: None,
+            std: None,
+        },
+        pointer_width: 64,
+        data_layout:
+            "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
+        arch: "x86_64".into(),
+        options: base,
+    }
+}
diff --git a/compiler/rustc_thread_pool/src/latch.rs b/compiler/rustc_thread_pool/src/latch.rs
index 18d654d9f78..58dabaf35c0 100644
--- a/compiler/rustc_thread_pool/src/latch.rs
+++ b/compiler/rustc_thread_pool/src/latch.rs
@@ -388,13 +388,17 @@ impl Latch for CountLatch {
     #[inline]
     unsafe fn set(this: *const Self) {
         if unsafe { (*this).counter.fetch_sub(1, Ordering::SeqCst) == 1 } {
-            // NOTE: Once we call `set` on the internal `latch`,
+            // SAFETY: Once we call `set` on the internal `latch`,
             // the target may proceed and invalidate `this`!
             match unsafe { &(*this).kind } {
                 CountLatchKind::Stealing { latch, registry, worker_index } => {
                     let registry = Arc::clone(registry);
+                    let worker_index = *worker_index;
+                    // SAFETY: We don't use any references from `this` after this call.
                     if unsafe { CoreLatch::set(latch) } {
-                        registry.notify_worker_latch_is_set(*worker_index);
+                        // We **must not** access any part of `this` anymore, which
+                        // is why we read and shadowed these fields beforehand.
+                        registry.notify_worker_latch_is_set(worker_index);
                     }
                 }
                 CountLatchKind::Blocking { latch } => unsafe { LockLatch::set(latch) },
diff --git a/compiler/rustc_windows_rc/Cargo.toml b/compiler/rustc_windows_rc/Cargo.toml
index 080acd35c38..13f716897fa 100644
--- a/compiler/rustc_windows_rc/Cargo.toml
+++ b/compiler/rustc_windows_rc/Cargo.toml
@@ -5,7 +5,5 @@ edition = "2024"
 
 [dependencies]
 #tidy-alphabetical-start
-# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version
-# per crate", so if you change this, you need to also change it in `rustc_llvm` and `rustc_codegen_ssa`.
-cc = "=1.2.16"
+find-msvc-tools = "0.1.2"
 #tidy-alphabetical-end
diff --git a/compiler/rustc_windows_rc/src/lib.rs b/compiler/rustc_windows_rc/src/lib.rs
index 5e95557501e..15afaf7b94b 100644
--- a/compiler/rustc_windows_rc/src/lib.rs
+++ b/compiler/rustc_windows_rc/src/lib.rs
@@ -2,9 +2,7 @@
 //!
 //! Uses values from the `CFG_VERSION` and `CFG_RELEASE` environment variables
 //! to set the product and file version information in the Windows resource file.
-use std::{env, ffi, fs, path, process};
-
-use cc::windows_registry;
+use std::{env, fs, path, process};
 
 /// The template for the Windows resource file.
 const RESOURCE_TEMPLATE: &str = include_str!("../rustc.rc.in");
@@ -38,7 +36,10 @@ pub fn compile_windows_resource_file(
     let resource_compiler = if let Ok(path) = env::var("RUSTC_WINDOWS_RC") {
         path.into()
     } else {
-        find_resource_compiler(&env::var("CARGO_CFG_TARGET_ARCH").unwrap()).expect("found rc.exe")
+        find_msvc_tools::find_tool(&env::var("CARGO_CFG_TARGET_ARCH").unwrap(), "rc.exe")
+            .expect("found rc.exe")
+            .path()
+            .to_owned()
     };
 
     let rc_path = resources_dir.join(file_stem.with_extension("rc"));
@@ -134,28 +135,3 @@ fn parse_version(version: &str) -> Option<ResourceVersion> {
         Some(ResourceVersion { major, minor, patch, build: 0 })
     }
 }
-
-/// Find the Windows SDK resource compiler `rc.exe` for the given architecture or target triple.
-/// Returns `None` if the tool could not be found.
-fn find_resource_compiler(arch_or_target: &str) -> Option<path::PathBuf> {
-    find_windows_sdk_tool(arch_or_target, "rc.exe")
-}
-
-/// Find a Windows SDK tool for the given architecture or target triple.
-/// Returns `None` if the tool could not be found.
-fn find_windows_sdk_tool(arch_or_target: &str, tool_name: &str) -> Option<path::PathBuf> {
-    // windows_registry::find_tool can only find MSVC tools, not Windows SDK tools, but
-    // cc does include the Windows SDK tools in the PATH environment of MSVC tools.
-
-    let msvc_linker = windows_registry::find_tool(arch_or_target, "link.exe")?;
-    let path = &msvc_linker.env().iter().find(|(k, _)| k == "PATH")?.1;
-    find_tool_in_path(tool_name, path)
-}
-
-/// Find a tool in the directories in a given PATH-like string.
-fn find_tool_in_path<P: AsRef<ffi::OsStr>>(tool_name: &str, path: P) -> Option<path::PathBuf> {
-    env::split_paths(path.as_ref()).find_map(|p| {
-        let tool_path = p.join(tool_name);
-        if tool_path.try_exists().unwrap_or(false) { Some(tool_path) } else { None }
-    })
-}
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 9ba7c5bd28a..fb1f8c86dbf 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -22,8 +22,6 @@ compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features
 compiler-builtins-mem = ['compiler_builtins/mem']
 compiler-builtins-c = ["compiler_builtins/c"]
 compiler-builtins-no-f16-f128 = ["compiler_builtins/no-f16-f128"]
-# Make panics and failed asserts immediately abort without formatting any message
-panic_immediate_abort = ["core/panic_immediate_abort"]
 # Choose algorithms that are optimized for binary size instead of runtime performance
 optimize_for_size = ["core/optimize_for_size"]
 
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 76630a746dd..65c8206e9d4 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -408,12 +408,12 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
         }
     }
 
-    #[cfg(not(feature = "panic_immediate_abort"))]
+    #[cfg(not(panic = "immediate-abort"))]
     {
         core::intrinsics::const_eval_select((layout,), ct_error, rt_error)
     }
 
-    #[cfg(feature = "panic_immediate_abort")]
+    #[cfg(panic = "immediate-abort")]
     ct_error(layout)
 }
 
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index b233e1740b7..2b8103c8b77 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -117,10 +117,11 @@ impl<K, V> InternalNode<K, V> {
     /// initialized and valid edge. This function does not set up
     /// such an edge.
     unsafe fn new<A: Allocator + Clone>(alloc: A) -> Box<Self, A> {
+        let mut node = Box::<Self, _>::new_uninit_in(alloc);
         unsafe {
-            let mut node = Box::<Self, _>::new_uninit_in(alloc);
-            // We only need to initialize the data; the edges are MaybeUninit.
+            // SAFETY: argument points to the `node.data` `LeafNode`
             LeafNode::init(&raw mut (*node.as_mut_ptr()).data);
+            // SAFETY: `node.data` was just initialized and `node.edges` is MaybeUninit.
             node.assume_init()
         }
     }
diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs
index b0027e964e4..b7c153b825d 100644
--- a/library/alloc/src/raw_vec/mod.rs
+++ b/library/alloc/src/raw_vec/mod.rs
@@ -23,7 +23,7 @@ mod tests;
 // ensure that the code generation related to these panics is minimal as there's
 // only one location which panics rather than a bunch throughout the module.
 #[cfg(not(no_global_oom_handling))]
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
 #[track_caller]
 fn capacity_overflow() -> ! {
     panic!("capacity overflow");
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index fcb466778a3..aed3357afbf 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -480,8 +480,6 @@ impl<T> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let mut five = Rc::<u32>::new_uninit();
@@ -572,7 +570,6 @@ impl<T> Rc<T> {
     ///
     /// ```
     /// #![feature(allocator_api)]
-    /// #![feature(get_mut_unchecked)]
     ///
     /// use std::rc::Rc;
     ///
@@ -1014,8 +1011,6 @@ impl<T> Rc<[T]> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
@@ -1181,8 +1176,6 @@ impl<T, A: Allocator> Rc<mem::MaybeUninit<T>, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let mut five = Rc::<u32>::new_uninit();
@@ -1218,8 +1211,6 @@ impl<T, A: Allocator> Rc<[mem::MaybeUninit<T>], A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 32396cccb8f..a466b74944c 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -480,8 +480,6 @@ impl<T> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let mut five = Arc::<u32>::new_uninit();
@@ -586,7 +584,6 @@ impl<T> Arc<T> {
     ///
     /// ```
     /// #![feature(allocator_api)]
-    /// #![feature(get_mut_unchecked)]
     ///
     /// use std::sync::Arc;
     ///
@@ -1156,8 +1153,6 @@ impl<T> Arc<[T]> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
@@ -1326,8 +1321,6 @@ impl<T, A: Allocator> Arc<mem::MaybeUninit<T>, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let mut five = Arc::<u32>::new_uninit();
@@ -1364,8 +1357,6 @@ impl<T, A: Allocator> Arc<[mem::MaybeUninit<T>], A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(get_mut_unchecked)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 10c7ee4f6c8..ebdb86f98a8 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2020,7 +2020,7 @@ impl<T, A: Allocator> Vec<T, A> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn swap_remove(&mut self, index: usize) -> T {
         #[cold]
-        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+        #[cfg_attr(not(panic = "immediate-abort"), inline(never))]
         #[track_caller]
         #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
@@ -2102,7 +2102,7 @@ impl<T, A: Allocator> Vec<T, A> {
     #[must_use = "if you don't need a reference to the value, use `Vec::insert` instead"]
     pub fn insert_mut(&mut self, index: usize, element: T) -> &mut T {
         #[cold]
-        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+        #[cfg_attr(not(panic = "immediate-abort"), inline(never))]
         #[track_caller]
         #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
@@ -2166,7 +2166,7 @@ impl<T, A: Allocator> Vec<T, A> {
     #[rustc_confusables("delete", "take")]
     pub fn remove(&mut self, index: usize) -> T {
         #[cold]
-        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+        #[cfg_attr(not(panic = "immediate-abort"), inline(never))]
         #[track_caller]
         #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
@@ -2955,7 +2955,7 @@ impl<T, A: Allocator> Vec<T, A> {
         A: Clone,
     {
         #[cold]
-        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+        #[cfg_attr(not(panic = "immediate-abort"), inline(never))]
         #[track_caller]
         #[optimize(size)]
         fn assert_failed(at: usize, len: usize) -> ! {
diff --git a/library/compiler-builtins/libm/src/math/support/float_traits.rs b/library/compiler-builtins/libm/src/math/support/float_traits.rs
index fb790e69615..b5ee6413d55 100644
--- a/library/compiler-builtins/libm/src/math/support/float_traits.rs
+++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs
@@ -289,7 +289,7 @@ macro_rules! float_impl {
                 cfg_if! {
                     // fma is not yet available in `core`
                     if #[cfg(intrinsics_enabled)] {
-                        unsafe{ core::intrinsics::$fma_intrinsic(self, y, z) }
+                        core::intrinsics::$fma_intrinsic(self, y, z)
                     } else {
                         super::super::$fma_fn(self, y, z)
                     }
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index 3e34e03a61e..d094172b076 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -16,7 +16,7 @@ test = false
 bench = false
 
 [features]
-# Make panics and failed asserts immediately abort without formatting any message
+# Issue a compile error that says to use -Cpanic=immediate-abort
 panic_immediate_abort = []
 # Choose algorithms that are optimized for binary size instead of runtime performance
 optimize_for_size = []
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index 178af2c0e3b..d77fafed203 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -515,7 +515,7 @@ impl AsciiChar {
     #[track_caller]
     pub const unsafe fn digit_unchecked(d: u8) -> Self {
         assert_unsafe_precondition!(
-            check_language_ub,
+            check_library_ub,
             "`ascii::Char::digit_unchecked` input cannot exceed 9.",
             (d: u8 = d) => d < 10
         );
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 9b53b75ebee..7d4a66640b1 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -778,7 +778,7 @@ impl Display for BorrowMutError {
 }
 
 // This ensures the panicking code is outlined from `borrow_mut` for `RefCell`.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
 #[track_caller]
 #[cold]
 const fn panic_already_borrowed(err: BorrowMutError) -> ! {
@@ -790,7 +790,7 @@ const fn panic_already_borrowed(err: BorrowMutError) -> ! {
 }
 
 // This ensures the panicking code is outlined from `borrow` for `RefCell`.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
 #[track_caller]
 #[cold]
 const fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index bffffbc29c1..a174ced5a2a 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -1022,28 +1022,28 @@ pub unsafe fn unaligned_volatile_store<T>(dst: *mut T, val: T);
 /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sqrtf16(x: f16) -> f16;
+pub fn sqrtf16(x: f16) -> f16;
 /// Returns the square root of an `f32`
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sqrtf32(x: f32) -> f32;
+pub fn sqrtf32(x: f32) -> f32;
 /// Returns the square root of an `f64`
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sqrtf64(x: f64) -> f64;
+pub fn sqrtf64(x: f64) -> f64;
 /// Returns the square root of an `f128`
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sqrtf128(x: f128) -> f128;
+pub fn sqrtf128(x: f128) -> f128;
 
 /// Raises an `f16` to an integer power.
 ///
@@ -1051,28 +1051,28 @@ pub unsafe fn sqrtf128(x: f128) -> f128;
 /// [`f16::powi`](../../std/primitive.f16.html#method.powi)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powif16(a: f16, x: i32) -> f16;
+pub fn powif16(a: f16, x: i32) -> f16;
 /// Raises an `f32` to an integer power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::powi`](../../std/primitive.f32.html#method.powi)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powif32(a: f32, x: i32) -> f32;
+pub fn powif32(a: f32, x: i32) -> f32;
 /// Raises an `f64` to an integer power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::powi`](../../std/primitive.f64.html#method.powi)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powif64(a: f64, x: i32) -> f64;
+pub fn powif64(a: f64, x: i32) -> f64;
 /// Raises an `f128` to an integer power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::powi`](../../std/primitive.f128.html#method.powi)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powif128(a: f128, x: i32) -> f128;
+pub fn powif128(a: f128, x: i32) -> f128;
 
 /// Returns the sine of an `f16`.
 ///
@@ -1080,28 +1080,28 @@ pub unsafe fn powif128(a: f128, x: i32) -> f128;
 /// [`f16::sin`](../../std/primitive.f16.html#method.sin)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sinf16(x: f16) -> f16;
+pub fn sinf16(x: f16) -> f16;
 /// Returns the sine of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::sin`](../../std/primitive.f32.html#method.sin)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sinf32(x: f32) -> f32;
+pub fn sinf32(x: f32) -> f32;
 /// Returns the sine of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::sin`](../../std/primitive.f64.html#method.sin)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sinf64(x: f64) -> f64;
+pub fn sinf64(x: f64) -> f64;
 /// Returns the sine of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::sin`](../../std/primitive.f128.html#method.sin)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn sinf128(x: f128) -> f128;
+pub fn sinf128(x: f128) -> f128;
 
 /// Returns the cosine of an `f16`.
 ///
@@ -1109,28 +1109,28 @@ pub unsafe fn sinf128(x: f128) -> f128;
 /// [`f16::cos`](../../std/primitive.f16.html#method.cos)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn cosf16(x: f16) -> f16;
+pub fn cosf16(x: f16) -> f16;
 /// Returns the cosine of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::cos`](../../std/primitive.f32.html#method.cos)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn cosf32(x: f32) -> f32;
+pub fn cosf32(x: f32) -> f32;
 /// Returns the cosine of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::cos`](../../std/primitive.f64.html#method.cos)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn cosf64(x: f64) -> f64;
+pub fn cosf64(x: f64) -> f64;
 /// Returns the cosine of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::cos`](../../std/primitive.f128.html#method.cos)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn cosf128(x: f128) -> f128;
+pub fn cosf128(x: f128) -> f128;
 
 /// Raises an `f16` to an `f16` power.
 ///
@@ -1138,28 +1138,28 @@ pub unsafe fn cosf128(x: f128) -> f128;
 /// [`f16::powf`](../../std/primitive.f16.html#method.powf)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powf16(a: f16, x: f16) -> f16;
+pub fn powf16(a: f16, x: f16) -> f16;
 /// Raises an `f32` to an `f32` power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::powf`](../../std/primitive.f32.html#method.powf)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powf32(a: f32, x: f32) -> f32;
+pub fn powf32(a: f32, x: f32) -> f32;
 /// Raises an `f64` to an `f64` power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::powf`](../../std/primitive.f64.html#method.powf)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powf64(a: f64, x: f64) -> f64;
+pub fn powf64(a: f64, x: f64) -> f64;
 /// Raises an `f128` to an `f128` power.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::powf`](../../std/primitive.f128.html#method.powf)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn powf128(a: f128, x: f128) -> f128;
+pub fn powf128(a: f128, x: f128) -> f128;
 
 /// Returns the exponential of an `f16`.
 ///
@@ -1167,28 +1167,28 @@ pub unsafe fn powf128(a: f128, x: f128) -> f128;
 /// [`f16::exp`](../../std/primitive.f16.html#method.exp)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn expf16(x: f16) -> f16;
+pub fn expf16(x: f16) -> f16;
 /// Returns the exponential of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::exp`](../../std/primitive.f32.html#method.exp)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn expf32(x: f32) -> f32;
+pub fn expf32(x: f32) -> f32;
 /// Returns the exponential of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::exp`](../../std/primitive.f64.html#method.exp)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn expf64(x: f64) -> f64;
+pub fn expf64(x: f64) -> f64;
 /// Returns the exponential of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::exp`](../../std/primitive.f128.html#method.exp)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn expf128(x: f128) -> f128;
+pub fn expf128(x: f128) -> f128;
 
 /// Returns 2 raised to the power of an `f16`.
 ///
@@ -1196,28 +1196,28 @@ pub unsafe fn expf128(x: f128) -> f128;
 /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn exp2f16(x: f16) -> f16;
+pub fn exp2f16(x: f16) -> f16;
 /// Returns 2 raised to the power of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn exp2f32(x: f32) -> f32;
+pub fn exp2f32(x: f32) -> f32;
 /// Returns 2 raised to the power of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn exp2f64(x: f64) -> f64;
+pub fn exp2f64(x: f64) -> f64;
 /// Returns 2 raised to the power of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn exp2f128(x: f128) -> f128;
+pub fn exp2f128(x: f128) -> f128;
 
 /// Returns the natural logarithm of an `f16`.
 ///
@@ -1225,28 +1225,28 @@ pub unsafe fn exp2f128(x: f128) -> f128;
 /// [`f16::ln`](../../std/primitive.f16.html#method.ln)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn logf16(x: f16) -> f16;
+pub fn logf16(x: f16) -> f16;
 /// Returns the natural logarithm of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::ln`](../../std/primitive.f32.html#method.ln)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn logf32(x: f32) -> f32;
+pub fn logf32(x: f32) -> f32;
 /// Returns the natural logarithm of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::ln`](../../std/primitive.f64.html#method.ln)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn logf64(x: f64) -> f64;
+pub fn logf64(x: f64) -> f64;
 /// Returns the natural logarithm of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::ln`](../../std/primitive.f128.html#method.ln)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn logf128(x: f128) -> f128;
+pub fn logf128(x: f128) -> f128;
 
 /// Returns the base 10 logarithm of an `f16`.
 ///
@@ -1254,28 +1254,28 @@ pub unsafe fn logf128(x: f128) -> f128;
 /// [`f16::log10`](../../std/primitive.f16.html#method.log10)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log10f16(x: f16) -> f16;
+pub fn log10f16(x: f16) -> f16;
 /// Returns the base 10 logarithm of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::log10`](../../std/primitive.f32.html#method.log10)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log10f32(x: f32) -> f32;
+pub fn log10f32(x: f32) -> f32;
 /// Returns the base 10 logarithm of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::log10`](../../std/primitive.f64.html#method.log10)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log10f64(x: f64) -> f64;
+pub fn log10f64(x: f64) -> f64;
 /// Returns the base 10 logarithm of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::log10`](../../std/primitive.f128.html#method.log10)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log10f128(x: f128) -> f128;
+pub fn log10f128(x: f128) -> f128;
 
 /// Returns the base 2 logarithm of an `f16`.
 ///
@@ -1283,28 +1283,28 @@ pub unsafe fn log10f128(x: f128) -> f128;
 /// [`f16::log2`](../../std/primitive.f16.html#method.log2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log2f16(x: f16) -> f16;
+pub fn log2f16(x: f16) -> f16;
 /// Returns the base 2 logarithm of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::log2`](../../std/primitive.f32.html#method.log2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log2f32(x: f32) -> f32;
+pub fn log2f32(x: f32) -> f32;
 /// Returns the base 2 logarithm of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::log2`](../../std/primitive.f64.html#method.log2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log2f64(x: f64) -> f64;
+pub fn log2f64(x: f64) -> f64;
 /// Returns the base 2 logarithm of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::log2`](../../std/primitive.f128.html#method.log2)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn log2f128(x: f128) -> f128;
+pub fn log2f128(x: f128) -> f128;
 
 /// Returns `a * b + c` for `f16` values.
 ///
@@ -1312,28 +1312,28 @@ pub unsafe fn log2f128(x: f128) -> f128;
 /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmaf16(a: f16, b: f16, c: f16) -> f16;
+pub fn fmaf16(a: f16, b: f16, c: f16) -> f16;
 /// Returns `a * b + c` for `f32` values.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmaf32(a: f32, b: f32, c: f32) -> f32;
+pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
 /// Returns `a * b + c` for `f64` values.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmaf64(a: f64, b: f64, c: f64) -> f64;
+pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
 /// Returns `a * b + c` for `f128` values.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmaf128(a: f128, b: f128, c: f128) -> f128;
+pub fn fmaf128(a: f128, b: f128, c: f128) -> f128;
 
 /// Returns `a * b + c` for `f16` values, non-deterministically executing
 /// either a fused multiply-add or two operations with rounding of the
@@ -1347,7 +1347,7 @@ pub unsafe fn fmaf128(a: f128, b: f128, c: f128) -> f128;
 /// example.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmuladdf16(a: f16, b: f16, c: f16) -> f16;
+pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16;
 /// Returns `a * b + c` for `f32` values, non-deterministically executing
 /// either a fused multiply-add or two operations with rounding of the
 /// intermediate result.
@@ -1360,7 +1360,7 @@ pub unsafe fn fmuladdf16(a: f16, b: f16, c: f16) -> f16;
 /// example.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmuladdf32(a: f32, b: f32, c: f32) -> f32;
+pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32;
 /// Returns `a * b + c` for `f64` values, non-deterministically executing
 /// either a fused multiply-add or two operations with rounding of the
 /// intermediate result.
@@ -1373,7 +1373,7 @@ pub unsafe fn fmuladdf32(a: f32, b: f32, c: f32) -> f32;
 /// example.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmuladdf64(a: f64, b: f64, c: f64) -> f64;
+pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64;
 /// Returns `a * b + c` for `f128` values, non-deterministically executing
 /// either a fused multiply-add or two operations with rounding of the
 /// intermediate result.
@@ -1386,7 +1386,7 @@ pub unsafe fn fmuladdf64(a: f64, b: f64, c: f64) -> f64;
 /// example.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
+pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
 
 /// Returns the largest integer less than or equal to an `f16`.
 ///
@@ -1395,7 +1395,7 @@ pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn floorf16(x: f16) -> f16;
+pub const fn floorf16(x: f16) -> f16;
 /// Returns the largest integer less than or equal to an `f32`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1403,7 +1403,7 @@ pub const unsafe fn floorf16(x: f16) -> f16;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn floorf32(x: f32) -> f32;
+pub const fn floorf32(x: f32) -> f32;
 /// Returns the largest integer less than or equal to an `f64`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1411,7 +1411,7 @@ pub const unsafe fn floorf32(x: f32) -> f32;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn floorf64(x: f64) -> f64;
+pub const fn floorf64(x: f64) -> f64;
 /// Returns the largest integer less than or equal to an `f128`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1419,7 +1419,7 @@ pub const unsafe fn floorf64(x: f64) -> f64;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn floorf128(x: f128) -> f128;
+pub const fn floorf128(x: f128) -> f128;
 
 /// Returns the smallest integer greater than or equal to an `f16`.
 ///
@@ -1428,7 +1428,7 @@ pub const unsafe fn floorf128(x: f128) -> f128;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn ceilf16(x: f16) -> f16;
+pub const fn ceilf16(x: f16) -> f16;
 /// Returns the smallest integer greater than or equal to an `f32`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1436,7 +1436,7 @@ pub const unsafe fn ceilf16(x: f16) -> f16;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn ceilf32(x: f32) -> f32;
+pub const fn ceilf32(x: f32) -> f32;
 /// Returns the smallest integer greater than or equal to an `f64`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1444,7 +1444,7 @@ pub const unsafe fn ceilf32(x: f32) -> f32;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn ceilf64(x: f64) -> f64;
+pub const fn ceilf64(x: f64) -> f64;
 /// Returns the smallest integer greater than or equal to an `f128`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1452,7 +1452,7 @@ pub const unsafe fn ceilf64(x: f64) -> f64;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn ceilf128(x: f128) -> f128;
+pub const fn ceilf128(x: f128) -> f128;
 
 /// Returns the integer part of an `f16`.
 ///
@@ -1461,7 +1461,7 @@ pub const unsafe fn ceilf128(x: f128) -> f128;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn truncf16(x: f16) -> f16;
+pub const fn truncf16(x: f16) -> f16;
 /// Returns the integer part of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1469,7 +1469,7 @@ pub const unsafe fn truncf16(x: f16) -> f16;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn truncf32(x: f32) -> f32;
+pub const fn truncf32(x: f32) -> f32;
 /// Returns the integer part of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1477,7 +1477,7 @@ pub const unsafe fn truncf32(x: f32) -> f32;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn truncf64(x: f64) -> f64;
+pub const fn truncf64(x: f64) -> f64;
 /// Returns the integer part of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
@@ -1485,7 +1485,7 @@ pub const unsafe fn truncf64(x: f64) -> f64;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn truncf128(x: f128) -> f128;
+pub const fn truncf128(x: f128) -> f128;
 
 /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
 /// least significant digit.
@@ -1534,7 +1534,7 @@ pub const fn round_ties_even_f128(x: f128) -> f128;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn roundf16(x: f16) -> f16;
+pub const fn roundf16(x: f16) -> f16;
 /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
@@ -1542,7 +1542,7 @@ pub const unsafe fn roundf16(x: f16) -> f16;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn roundf32(x: f32) -> f32;
+pub const fn roundf32(x: f32) -> f32;
 /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
@@ -1550,7 +1550,7 @@ pub const unsafe fn roundf32(x: f32) -> f32;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn roundf64(x: f64) -> f64;
+pub const fn roundf64(x: f64) -> f64;
 /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
@@ -1558,10 +1558,10 @@ pub const unsafe fn roundf64(x: f64) -> f64;
 #[rustc_intrinsic_const_stable_indirect]
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub const unsafe fn roundf128(x: f128) -> f128;
+pub const fn roundf128(x: f128) -> f128;
 
 /// Float addition that allows optimizations based on algebraic rules.
-/// May assume inputs are finite.
+/// Requires that inputs and output of the operation are finite, causing UB otherwise.
 ///
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
@@ -1569,7 +1569,7 @@ pub const unsafe fn roundf128(x: f128) -> f128;
 pub unsafe fn fadd_fast<T: Copy>(a: T, b: T) -> T;
 
 /// Float subtraction that allows optimizations based on algebraic rules.
-/// May assume inputs are finite.
+/// Requires that inputs and output of the operation are finite, causing UB otherwise.
 ///
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
@@ -1577,7 +1577,7 @@ pub unsafe fn fadd_fast<T: Copy>(a: T, b: T) -> T;
 pub unsafe fn fsub_fast<T: Copy>(a: T, b: T) -> T;
 
 /// Float multiplication that allows optimizations based on algebraic rules.
-/// May assume inputs are finite.
+/// Requires that inputs and output of the operation are finite, causing UB otherwise.
 ///
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
@@ -1585,7 +1585,7 @@ pub unsafe fn fsub_fast<T: Copy>(a: T, b: T) -> T;
 pub unsafe fn fmul_fast<T: Copy>(a: T, b: T) -> T;
 
 /// Float division that allows optimizations based on algebraic rules.
-/// May assume inputs are finite.
+/// Requires that inputs and output of the operation are finite, causing UB otherwise.
 ///
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
@@ -1593,7 +1593,7 @@ pub unsafe fn fmul_fast<T: Copy>(a: T, b: T) -> T;
 pub unsafe fn fdiv_fast<T: Copy>(a: T, b: T) -> T;
 
 /// Float remainder that allows optimizations based on algebraic rules.
-/// May assume inputs are finite.
+/// Requires that inputs and output of the operation are finite, causing UB otherwise.
 ///
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index a820045521b..c50f07ff6bb 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -779,7 +779,7 @@ impl<T> OneShot for result::IterMut<'_, T> {}
 impl<T> OneShot for Empty<T> {}
 impl<T> OneShot for array::IntoIter<T, 0> {}
 
-// These adaptors never increase the number of items.
+// These adapters never increase the number of items.
 // (There are more possible, but for now this matches BoundedSize above.)
 impl<I: OneShot> OneShot for Cloned<I> {}
 impl<I: OneShot> OneShot for Copied<I> {}
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 66c892aadd0..b0c9e9ef05e 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -1196,7 +1196,8 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
         let mut left = self.to_bits() as i128;
         let mut right = other.to_bits() as i128;
 
@@ -1459,8 +1460,7 @@ impl f128 {
     #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn floor(self) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::floorf128(self) }
+        intrinsics::floorf128(self)
     }
 
     /// Returns the smallest integer greater than or equal to `self`.
@@ -1488,8 +1488,7 @@ impl f128 {
     #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn ceil(self) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::ceilf128(self) }
+        intrinsics::ceilf128(self)
     }
 
     /// Returns the nearest integer to `self`. If a value is half-way between two
@@ -1523,8 +1522,7 @@ impl f128 {
     #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn round(self) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::roundf128(self) }
+        intrinsics::roundf128(self)
     }
 
     /// Returns the nearest integer to a number. Rounds half-way cases to the number
@@ -1587,8 +1585,7 @@ impl f128 {
     #[rustc_const_unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn trunc(self) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::truncf128(self) }
+        intrinsics::truncf128(self)
     }
 
     /// Returns the fractional part of `self`.
@@ -1664,8 +1661,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn mul_add(self, a: f128, b: f128) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::fmaf128(self, a, b) }
+        intrinsics::fmaf128(self, a, b)
     }
 
     /// Calculates Euclidean division, the matching method for `rem_euclid`.
@@ -1780,8 +1776,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn powi(self, n: i32) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::powif128(self, n) }
+        intrinsics::powif128(self, n)
     }
 
     /// Returns the square root of a number.
@@ -1816,7 +1811,6 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sqrt(self) -> f128 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::sqrtf128(self) }
+        intrinsics::sqrtf128(self)
     }
 }
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 81220065e72..56db92f91fc 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -1175,7 +1175,8 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
         let mut left = self.to_bits() as i16;
         let mut right = other.to_bits() as i16;
 
@@ -1434,8 +1435,7 @@ impl f16 {
     #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn floor(self) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::floorf16(self) }
+        intrinsics::floorf16(self)
     }
 
     /// Returns the smallest integer greater than or equal to `self`.
@@ -1463,8 +1463,7 @@ impl f16 {
     #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn ceil(self) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::ceilf16(self) }
+        intrinsics::ceilf16(self)
     }
 
     /// Returns the nearest integer to `self`. If a value is half-way between two
@@ -1498,8 +1497,7 @@ impl f16 {
     #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn round(self) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::roundf16(self) }
+        intrinsics::roundf16(self)
     }
 
     /// Returns the nearest integer to a number. Rounds half-way cases to the number
@@ -1562,8 +1560,7 @@ impl f16 {
     #[rustc_const_unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn trunc(self) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::truncf16(self) }
+        intrinsics::truncf16(self)
     }
 
     /// Returns the fractional part of `self`.
@@ -1639,8 +1636,7 @@ impl f16 {
     #[doc(alias = "fmaf16", alias = "fusedMultiplyAdd")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn mul_add(self, a: f16, b: f16) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::fmaf16(self, a, b) }
+        intrinsics::fmaf16(self, a, b)
     }
 
     /// Calculates Euclidean division, the matching method for `rem_euclid`.
@@ -1755,8 +1751,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn powi(self, n: i32) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::powif16(self, n) }
+        intrinsics::powif16(self, n)
     }
 
     /// Returns the square root of a number.
@@ -1791,8 +1786,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sqrt(self) -> f16 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::sqrtf16(self) }
+        intrinsics::sqrtf16(self)
     }
 
     /// Returns the cube root of a number.
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index cefcf1d1fe2..57be4d8d30a 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1353,9 +1353,10 @@ impl f32 {
     /// }
     /// ```
     #[stable(feature = "total_cmp", since = "1.62.0")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     #[must_use]
     #[inline]
-    pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
+    pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
         let mut left = self.to_bits() as i32;
         let mut right = other.to_bits() as i32;
 
@@ -1603,8 +1604,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn floor(x: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::floorf32(x) }
+        intrinsics::floorf32(x)
     }
 
     /// Experimental version of `ceil` in `core`. See [`f32::ceil`] for details.
@@ -1632,8 +1632,7 @@ pub mod math {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
     pub const fn ceil(x: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::ceilf32(x) }
+        intrinsics::ceilf32(x)
     }
 
     /// Experimental version of `round` in `core`. See [`f32::round`] for details.
@@ -1666,8 +1665,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn round(x: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::roundf32(x) }
+        intrinsics::roundf32(x)
     }
 
     /// Experimental version of `round_ties_even` in `core`. See [`f32::round_ties_even`] for
@@ -1729,8 +1727,7 @@ pub mod math {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
     pub const fn trunc(x: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::truncf32(x) }
+        intrinsics::truncf32(x)
     }
 
     /// Experimental version of `fract` in `core`. See [`f32::fract`] for details.
@@ -1804,8 +1801,7 @@ pub mod math {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
     pub fn mul_add(x: f32, y: f32, z: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::fmaf32(x, y, z) }
+        intrinsics::fmaf32(x, y, z)
     }
 
     /// Experimental version of `div_euclid` in `core`. See [`f32::div_euclid`] for details.
@@ -1896,8 +1892,7 @@ pub mod math {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
     pub fn powi(x: f32, n: i32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::powif32(x, n) }
+        intrinsics::powif32(x, n)
     }
 
     /// Experimental version of `sqrt` in `core`. See [`f32::sqrt`] for details.
@@ -1927,8 +1922,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sqrt(x: f32) -> f32 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::sqrtf32(x) }
+        intrinsics::sqrtf32(x)
     }
 
     /// Experimental version of `abs_sub` in `core`. See [`f32::abs_sub`] for details.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 9dd1141e703..748956ae980 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1351,9 +1351,10 @@ impl f64 {
     /// }
     /// ```
     #[stable(feature = "total_cmp", since = "1.62.0")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     #[must_use]
     #[inline]
-    pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
+    pub const fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
         let mut left = self.to_bits() as i64;
         let mut right = other.to_bits() as i64;
 
@@ -1601,8 +1602,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn floor(x: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::floorf64(x) }
+        intrinsics::floorf64(x)
     }
 
     /// Experimental version of `ceil` in `core`. See [`f64::ceil`] for details.
@@ -1630,8 +1630,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn ceil(x: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::ceilf64(x) }
+        intrinsics::ceilf64(x)
     }
 
     /// Experimental version of `round` in `core`. See [`f64::round`] for details.
@@ -1664,8 +1663,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn round(x: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::roundf64(x) }
+        intrinsics::roundf64(x)
     }
 
     /// Experimental version of `round_ties_even` in `core`. See [`f64::round_ties_even`] for
@@ -1727,8 +1725,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub const fn trunc(x: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::truncf64(x) }
+        intrinsics::truncf64(x)
     }
 
     /// Experimental version of `fract` in `core`. See [`f64::fract`] for details.
@@ -1802,8 +1799,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn mul_add(x: f64, a: f64, b: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::fmaf64(x, a, b) }
+        intrinsics::fmaf64(x, a, b)
     }
 
     /// Experimental version of `div_euclid` in `core`. See [`f64::div_euclid`] for details.
@@ -1894,8 +1890,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn powi(x: f64, n: i32) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::powif64(x, n) }
+        intrinsics::powif64(x, n)
     }
 
     /// Experimental version of `sqrt` in `core`. See [`f64::sqrt`] for details.
@@ -1925,8 +1920,7 @@ pub mod math {
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sqrt(x: f64) -> f64 {
-        // SAFETY: intrinsic with no preconditions
-        unsafe { intrinsics::sqrtf64(x) }
+        intrinsics::sqrtf64(x)
     }
 
     /// Experimental version of `abs_sub` in `core`. See [`f64::abs_sub`] for details.
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 64a3dd3e8bc..0d80c40fb23 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1460,8 +1460,8 @@ macro_rules! int_impl {
         #[inline]
         pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
             assert_unsafe_precondition!(
-                check_language_ub,
-                concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out non-zero bits"),
+                check_library_ub,
+                concat!(stringify!($SelfT), "::unchecked_exact_shl cannot shift out bits that would change the value of the first bit"),
                 (
                     zeros: u32 = self.leading_zeros(),
                     ones: u32 = self.leading_ones(),
@@ -1638,7 +1638,7 @@ macro_rules! int_impl {
         #[inline]
         pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
             assert_unsafe_precondition!(
-                check_language_ub,
+                check_library_ub,
                 concat!(stringify!($SelfT), "::unchecked_exact_shr cannot shift out non-zero bits"),
                 (
                     zeros: u32 = self.trailing_zeros(),
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 54d5a63633c..c75ee11d15e 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -1387,8 +1387,8 @@ pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8])
     radix <= 16 && digits.len() <= size_of::<T>() * 2 - is_signed_ty as usize
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[cold]
 #[track_caller]
 const fn from_ascii_radix_panic(radix: u32) -> ! {
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index bf72ec83197..d68c7be9865 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1865,7 +1865,7 @@ macro_rules! uint_impl {
         #[inline]
         pub const unsafe fn unchecked_exact_shl(self, rhs: u32) -> $SelfT {
             assert_unsafe_precondition!(
-                check_language_ub,
+                check_library_ub,
                 concat!(stringify!($SelfT), "::exact_shl_unchecked cannot shift out non-zero bits"),
                 (
                     zeros: u32 = self.leading_zeros(),
@@ -2037,7 +2037,7 @@ macro_rules! uint_impl {
         #[inline]
         pub const unsafe fn unchecked_exact_shr(self, rhs: u32) -> $SelfT {
             assert_unsafe_precondition!(
-                check_language_ub,
+                check_library_ub,
                 concat!(stringify!($SelfT), "::exact_shr_unchecked cannot shift out non-zero bits"),
                 (
                     zeros: u32 = self.trailing_zeros(),
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 886d581b0a6..430ee3470ac 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -2161,8 +2161,8 @@ impl<T, E> Option<Result<T, E>> {
     }
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[cold]
 #[track_caller]
 const fn unwrap_failed() -> ! {
@@ -2170,8 +2170,8 @@ const fn unwrap_failed() -> ! {
 }
 
 // This is a separate function to reduce the code size of .expect() itself.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[cold]
 #[track_caller]
 const fn expect_failed(msg: &str) -> ! {
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 804a12ee477..3f30038dbc0 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -33,7 +33,10 @@ use crate::intrinsics::const_eval_select;
 use crate::panic::{Location, PanicInfo};
 
 #[cfg(feature = "panic_immediate_abort")]
-const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C panic=abort");
+compile_error!(
+    "panic_immediate_abort is now a real panic strategy! \
+    Enable it with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
+);
 
 // First we define the two main entry points that all panics go through.
 // In the end both are just convenience wrappers around `panic_impl`.
@@ -44,16 +47,16 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C
 /// site as much as possible (so that `panic!()` has as low an impact
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
-// If panic_immediate_abort, inline the abort call,
+// If panic=immediate-abort, inline the abort call,
 // otherwise avoid inlining because of it is cold path.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[lang = "panic_fmt"] // needed for const-evaluated panics
 #[rustc_do_not_const_check] // hooked by const-eval
 #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
 pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         super::intrinsics::abort()
     }
 
@@ -78,8 +81,8 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
 /// Like `panic_fmt`, but for non-unwinding panics.
 ///
 /// Has to be a separate function so that it can carry the `rustc_nounwind` attribute.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 // This attribute has the key side-effect that if the panic handler ignores `can_unwind`
 // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
@@ -94,7 +97,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
             // We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
             panic_fmt(fmt)
         } else #[track_caller] {
-            if cfg!(feature = "panic_immediate_abort") {
+            if cfg!(panic = "immediate-abort") {
                 super::intrinsics::abort()
             }
 
@@ -123,10 +126,10 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
 // above.
 
 /// The underlying implementation of core's `panic!` macro when no formatting is used.
-// Never inline unless panic_immediate_abort to avoid code
+// Never inline unless panic=immediate-abort to avoid code
 // bloat at the call sites as much as possible.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
 #[lang = "panic"] // used by lints and miri for panics
@@ -158,10 +161,10 @@ macro_rules! panic_const {
         $(
             /// This is a panic called with a message that's a result of a MIR-produced Assert.
             //
-            // never inline unless panic_immediate_abort to avoid code
+            // never inline unless panic=immediate-abort to avoid code
             // bloat at the call sites as much as possible
-            #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-            #[cfg_attr(feature = "panic_immediate_abort", inline)]
+            #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+            #[cfg_attr(panic = "immediate-abort", inline)]
             #[track_caller]
             #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
             #[lang = stringify!($lang)]
@@ -216,8 +219,8 @@ pub mod panic_const {
 
 /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller.
 /// If you want `#[track_caller]` for nicer errors, call `panic_nounwind_fmt` directly.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics
 #[rustc_nounwind]
 #[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
@@ -226,8 +229,8 @@ pub const fn panic_nounwind(expr: &'static str) -> ! {
 }
 
 /// Like `panic_nounwind`, but also inhibits showing a backtrace.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[rustc_nounwind]
 pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! {
     panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true);
@@ -259,25 +262,25 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
     panic_fmt(format_args!("{}", *x));
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
 fn panic_bounds_check(index: usize, len: usize) -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         super::intrinsics::abort()
     }
 
     panic!("index out of bounds: the len is {len} but the index is {index}")
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref
 #[rustc_nounwind] // `CheckAlignment` MIR pass requires this function to never unwind
 fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         super::intrinsics::abort()
     }
 
@@ -289,13 +292,13 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
     )
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref
 #[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind
 fn panic_null_pointer_dereference() -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         super::intrinsics::abort()
     }
 
@@ -305,13 +308,13 @@ fn panic_null_pointer_dereference() -> ! {
     )
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[lang = "panic_invalid_enum_construction"] // needed by codegen for panic on invalid enum construction.
 #[rustc_nounwind] // `CheckEnums` MIR pass requires this function to never unwind
 fn panic_invalid_enum_construction(source: u128) -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         super::intrinsics::abort()
     }
 
@@ -328,8 +331,8 @@ fn panic_invalid_enum_construction(source: u128) -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
 fn panic_cannot_unwind() -> ! {
@@ -344,8 +347,8 @@ fn panic_cannot_unwind() -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
 fn panic_in_cleanup() -> ! {
@@ -377,8 +380,8 @@ pub enum AssertKind {
 }
 
 /// Internal function for `assert_eq!` and `assert_ne!` macros
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[doc(hidden)]
 pub fn assert_failed<T, U>(
@@ -395,8 +398,8 @@ where
 }
 
 /// Internal function for `assert_match!`
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[doc(hidden)]
 pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
@@ -415,8 +418,8 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
 }
 
 /// Non-generic version of the above functions, to avoid code bloat.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 fn assert_failed_inner(
     kind: AssertKind,
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 5c1f64bfe14..c69762a7285 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1847,7 +1847,7 @@ impl<T, E> Result<Result<T, E>, E> {
 }
 
 // This is a separate function to reduce the code size of the methods
-#[cfg(not(feature = "panic_immediate_abort"))]
+#[cfg(not(panic = "immediate-abort"))]
 #[inline(never)]
 #[cold]
 #[track_caller]
@@ -1859,7 +1859,7 @@ fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
 // that gets immediately thrown away, since vtables don't get cleaned up
 // by dead code elimination if a trait object is constructed even if it goes
 // unused
-#[cfg(feature = "panic_immediate_abort")]
+#[cfg(panic = "immediate-abort")]
 #[inline]
 #[cold]
 #[track_caller]
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index a8147d745f3..de220e7e38a 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -31,8 +31,8 @@ where
     }
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
     if start > len {
@@ -233,7 +233,7 @@ unsafe impl<T> const SliceIndex<[T]> for usize {
     #[track_caller]
     unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
         assert_unsafe_precondition!(
-            check_language_ub,
+            check_language_ub, // okay because of the `assume` below
             "slice::get_unchecked requires that the index is within the slice",
             (this: usize = self, len: usize = slice.len()) => this < len
         );
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index dfbb3628350..f7f5ee819b2 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3858,8 +3858,8 @@ impl<T> [T] {
     {
         // The panic code path was put into a cold function to not bloat the
         // call site.
-        #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-        #[cfg_attr(feature = "panic_immediate_abort", inline)]
+        #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+        #[cfg_attr(panic = "immediate-abort", inline)]
         #[track_caller]
         const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
             const_panic!(
diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs
index 400daba16c1..e555fce4408 100644
--- a/library/core/src/slice/sort/shared/smallsort.rs
+++ b/library/core/src/slice/sort/shared/smallsort.rs
@@ -840,8 +840,8 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
     }
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 fn panic_on_ord_violation() -> ! {
     // This is indicative of a logic bug in the user-provided comparison function or Ord
     // implementation. They are expected to implement a total order as explained in the Ord
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 04fdaa8143e..2e473d348b0 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -64,12 +64,12 @@ pub use validations::{next_code_point, utf8_char_width};
 #[cold]
 #[track_caller]
 #[rustc_allow_const_fn_unstable(const_eval_select)]
-#[cfg(not(feature = "panic_immediate_abort"))]
+#[cfg(not(panic = "immediate-abort"))]
 const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
     crate::intrinsics::const_eval_select((s, begin, end), slice_error_fail_ct, slice_error_fail_rt)
 }
 
-#[cfg(feature = "panic_immediate_abort")]
+#[cfg(panic = "immediate-abort")]
 const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
     slice_error_fail_ct(s, begin, end)
 }
diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs
index b809294cfce..514ff93c982 100644
--- a/library/core/src/ub_checks.rs
+++ b/library/core/src/ub_checks.rs
@@ -21,8 +21,9 @@ use crate::intrinsics::{self, const_eval_select};
 /// slow down const-eval/Miri and we'll get the panic message instead of the interpreter's nice
 /// diagnostic, but our ability to detect UB is unchanged.
 /// But if `check_language_ub` is used when the check is actually for library UB, the check is
-/// omitted in const-eval/Miri and thus if we eventually execute language UB which relies on the
-/// library UB, the backtrace Miri reports may be far removed from original cause.
+/// omitted in const-eval/Miri and thus UB might occur undetected. Even if we eventually execute
+/// language UB which relies on the library UB, the backtrace Miri reports may be far removed from
+/// original cause.
 ///
 /// These checks are behind a condition which is evaluated at codegen time, not expansion time like
 /// [`debug_assert`]. This means that a standard library built with optimizations and debug
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index 31515561c63..d2b57223094 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -1246,104 +1246,103 @@ float_test! {
 float_test! {
     name: total_cmp,
     attrs: {
-        const: #[cfg(false)],
         f16: #[cfg(all(not(miri), target_has_reliable_f16_math))],
         f128: #[cfg(all(not(miri), target_has_reliable_f128_math))],
     },
     test<Float> {
         use core::cmp::Ordering;
 
-        fn quiet_bit_mask() -> <Float as TestableFloat>::Int {
+        const fn quiet_bit_mask() -> <Float as TestableFloat>::Int {
             1 << (Float::MANTISSA_DIGITS - 2)
         }
 
-        fn q_nan() -> Float {
+        const fn q_nan() -> Float {
             Float::from_bits(Float::NAN.to_bits() | quiet_bit_mask())
         }
 
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-q_nan(), &-q_nan()));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-Float::INFINITY, &-Float::INFINITY));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-Float::MAX, &-Float::MAX));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-2.5, &-2.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-1.0, &-1.0));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-1.5, &-1.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-0.5, &-0.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-Float::MIN_POSITIVE, &-Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-Float::TINY, &-Float::TINY));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&-0.0, &-0.0));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&0.0, &0.0));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&Float::TINY, &Float::TINY));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&Float::MIN_POSITIVE, &Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&0.5, &0.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&1.0, &1.0));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&1.5, &1.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&2.5, &2.5));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&Float::MAX, &Float::MAX));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&Float::INFINITY, &Float::INFINITY));
-        assert_eq!(Ordering::Equal, Float::total_cmp(&q_nan(), &q_nan()));
-
-        assert_eq!(Ordering::Less, Float::total_cmp(&-Float::INFINITY, &-Float::MAX));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-Float::MAX, &-2.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-2.5, &-1.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-1.5, &-1.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-1.0, &-0.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-0.5, &-Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-Float::MIN_POSITIVE, &-Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::TINY));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-Float::TINY, &-0.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-0.0, &0.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&0.0, &Float::TINY));
-        assert_eq!(Ordering::Less, Float::total_cmp(&Float::TINY, &Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Less, Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, Float::total_cmp(&Float::MIN_POSITIVE, &0.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&0.5, &1.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&1.0, &1.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&1.5, &2.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&2.5, &Float::MAX));
-        assert_eq!(Ordering::Less, Float::total_cmp(&Float::MAX, &Float::INFINITY));
-
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-Float::MAX, &-Float::INFINITY));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-2.5, &-Float::MAX));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-1.5, &-2.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-1.0, &-1.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-0.5, &-1.0));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-Float::MIN_POSITIVE, &-0.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-Float::TINY, &-Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&-0.0, &-Float::TINY));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&0.0, &-0.0));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&Float::TINY, &0.0));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::TINY));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&Float::MIN_POSITIVE, &Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&0.5, &Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&1.0, &0.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&1.5, &1.0));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&2.5, &1.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&Float::MAX, &2.5));
-        assert_eq!(Ordering::Greater, Float::total_cmp(&Float::INFINITY, &Float::MAX));
-
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-Float::INFINITY));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-Float::MAX));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-2.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-1.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-1.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-0.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-Float::TINY));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &-0.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &0.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &Float::TINY));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &Float::MAX_SUBNORMAL));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &Float::MIN_POSITIVE));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &0.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &1.0));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &1.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &2.5));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &Float::MAX));
-        assert_eq!(Ordering::Less, Float::total_cmp(&-q_nan(), &Float::INFINITY));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-q_nan()), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-Float::INFINITY, &-Float::INFINITY), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-Float::MAX, &-Float::MAX), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-2.5, &-2.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-1.0, &-1.0), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-1.5, &-1.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-0.5, &-0.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-Float::MIN_POSITIVE, &-Float::MIN_POSITIVE), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::MAX_SUBNORMAL), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-Float::TINY, &-Float::TINY), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&-0.0, &-0.0), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&0.0, &0.0), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&Float::TINY, &Float::TINY), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::MAX_SUBNORMAL), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&Float::MIN_POSITIVE, &Float::MIN_POSITIVE), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&0.5, &0.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&1.0, &1.0), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&1.5, &1.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&2.5, &2.5), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&Float::MAX, &Float::MAX), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&Float::INFINITY, &Float::INFINITY), Ordering::Equal));
+        assert!(matches!(Float::total_cmp(&q_nan(), &q_nan()), Ordering::Equal));
+
+        assert!(matches!(Float::total_cmp(&-Float::INFINITY, &-Float::MAX), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-Float::MAX, &-2.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-2.5, &-1.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-1.5, &-1.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-1.0, &-0.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-0.5, &-Float::MIN_POSITIVE), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-Float::MIN_POSITIVE, &-Float::MAX_SUBNORMAL), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::TINY), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-Float::TINY, &-0.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-0.0, &0.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&0.0, &Float::TINY), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&Float::TINY, &Float::MAX_SUBNORMAL), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::MIN_POSITIVE), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&Float::MIN_POSITIVE, &0.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&0.5, &1.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&1.0, &1.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&1.5, &2.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&2.5, &Float::MAX), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&Float::MAX, &Float::INFINITY), Ordering::Less));
+
+        assert!(matches!(Float::total_cmp(&-Float::MAX, &-Float::INFINITY), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-2.5, &-Float::MAX), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-1.5, &-2.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-1.0, &-1.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-0.5, &-1.0), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-Float::MIN_POSITIVE, &-0.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-Float::MAX_SUBNORMAL, &-Float::MIN_POSITIVE), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-Float::TINY, &-Float::MAX_SUBNORMAL), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&-0.0, &-Float::TINY), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&0.0, &-0.0), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&Float::TINY, &0.0), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&Float::MAX_SUBNORMAL, &Float::TINY), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&Float::MIN_POSITIVE, &Float::MAX_SUBNORMAL), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&0.5, &Float::MIN_POSITIVE), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&1.0, &0.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&1.5, &1.0), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&2.5, &1.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&Float::MAX, &2.5), Ordering::Greater));
+        assert!(matches!(Float::total_cmp(&Float::INFINITY, &Float::MAX), Ordering::Greater));
+
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-Float::INFINITY), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-Float::MAX), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-2.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-1.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-1.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-0.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-Float::MIN_POSITIVE), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-Float::MAX_SUBNORMAL), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-Float::TINY), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &-0.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &0.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &Float::TINY), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &Float::MAX_SUBNORMAL), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &Float::MIN_POSITIVE), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &0.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &1.0), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &1.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &2.5), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &Float::MAX), Ordering::Less));
+        assert!(matches!(Float::total_cmp(&-q_nan(), &Float::INFINITY), Ordering::Less));
 
     }
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index d28a7f0b460..958cafb8f3d 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -106,11 +106,6 @@ compiler-builtins-no-f16-f128 = ["alloc/compiler-builtins-no-f16-f128"]
 llvm-libunwind = ["unwind/llvm-libunwind"]
 system-llvm-libunwind = ["unwind/system-llvm-libunwind"]
 
-# Make panics and failed asserts immediately abort without formatting any message
-panic_immediate_abort = [
-    "core/panic_immediate_abort",
-    "alloc/panic_immediate_abort",
-]
 # Choose algorithms that are optimized for binary size instead of runtime performance
 optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"]
 
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index ff0e29e04c2..a45edd08e8c 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1081,7 +1081,7 @@ pub trait Read {
         default_read_buf_exact(self, cursor)
     }
 
-    /// Creates a "by reference" adaptor for this instance of `Read`.
+    /// Creates a "by reference" adapter for this instance of `Read`.
     ///
     /// The returned adapter also implements `Read` and will simply borrow this
     /// current reader.
diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs
index b83692390b6..5d206c4b7da 100644
--- a/library/std/src/num/f128.rs
+++ b/library/std/src/num/f128.rs
@@ -44,7 +44,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn powf(self, n: f128) -> f128 {
-        unsafe { intrinsics::powf128(self, n) }
+        intrinsics::powf128(self, n)
     }
 
     /// Returns `e^(self)`, (the exponential function).
@@ -76,7 +76,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn exp(self) -> f128 {
-        unsafe { intrinsics::expf128(self) }
+        intrinsics::expf128(self)
     }
 
     /// Returns `2^(self)`.
@@ -106,7 +106,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn exp2(self) -> f128 {
-        unsafe { intrinsics::exp2f128(self) }
+        intrinsics::exp2f128(self)
     }
 
     /// Returns the natural logarithm of the number.
@@ -151,7 +151,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn ln(self) -> f128 {
-        unsafe { intrinsics::logf128(self) }
+        intrinsics::logf128(self)
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -241,7 +241,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn log2(self) -> f128 {
-        unsafe { intrinsics::log2f128(self) }
+        intrinsics::log2f128(self)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -284,7 +284,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn log10(self) -> f128 {
-        unsafe { intrinsics::log10f128(self) }
+        intrinsics::log10f128(self)
     }
 
     /// Returns the cube root of a number.
@@ -385,7 +385,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sin(self) -> f128 {
-        unsafe { intrinsics::sinf128(self) }
+        intrinsics::sinf128(self)
     }
 
     /// Computes the cosine of a number (in radians).
@@ -414,7 +414,7 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn cos(self) -> f128 {
-        unsafe { intrinsics::cosf128(self) }
+        intrinsics::cosf128(self)
     }
 
     /// Computes the tangent of a number (in radians).
diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs
index 5599528717c..2565ef0f9f2 100644
--- a/library/std/src/num/f16.rs
+++ b/library/std/src/num/f16.rs
@@ -44,7 +44,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn powf(self, n: f16) -> f16 {
-        unsafe { intrinsics::powf16(self, n) }
+        intrinsics::powf16(self, n)
     }
 
     /// Returns `e^(self)`, (the exponential function).
@@ -76,7 +76,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn exp(self) -> f16 {
-        unsafe { intrinsics::expf16(self) }
+        intrinsics::expf16(self)
     }
 
     /// Returns `2^(self)`.
@@ -106,7 +106,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn exp2(self) -> f16 {
-        unsafe { intrinsics::exp2f16(self) }
+        intrinsics::exp2f16(self)
     }
 
     /// Returns the natural logarithm of the number.
@@ -151,7 +151,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn ln(self) -> f16 {
-        unsafe { intrinsics::logf16(self) }
+        intrinsics::logf16(self)
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -241,7 +241,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn log2(self) -> f16 {
-        unsafe { intrinsics::log2f16(self) }
+        intrinsics::log2f16(self)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -284,7 +284,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn log10(self) -> f16 {
-        unsafe { intrinsics::log10f16(self) }
+        intrinsics::log10f16(self)
     }
 
     /// Compute the distance between the origin and a point (`x`, `y`) on the
@@ -350,7 +350,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn sin(self) -> f16 {
-        unsafe { intrinsics::sinf16(self) }
+        intrinsics::sinf16(self)
     }
 
     /// Computes the cosine of a number (in radians).
@@ -379,7 +379,7 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     pub fn cos(self) -> f16 {
-        unsafe { intrinsics::cosf16(self) }
+        intrinsics::cosf16(self)
     }
 
     /// Computes the tangent of a number (in radians).
diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs
index 0247080a8d6..ac1d889cc37 100644
--- a/library/std/src/num/f32.rs
+++ b/library/std/src/num/f32.rs
@@ -338,7 +338,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powf(self, n: f32) -> f32 {
-        unsafe { intrinsics::powf32(self, n) }
+        intrinsics::powf32(self, n)
     }
 
     /// Returns the square root of a number.
@@ -395,7 +395,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp(self) -> f32 {
-        unsafe { intrinsics::expf32(self) }
+        intrinsics::expf32(self)
     }
 
     /// Returns `2^(self)`.
@@ -420,7 +420,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp2(self) -> f32 {
-        unsafe { intrinsics::exp2f32(self) }
+        intrinsics::exp2f32(self)
     }
 
     /// Returns the natural logarithm of the number.
@@ -455,7 +455,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f32 {
-        unsafe { intrinsics::logf32(self) }
+        intrinsics::logf32(self)
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -525,7 +525,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f32 {
-        unsafe { intrinsics::log2f32(self) }
+        intrinsics::log2f32(self)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -558,7 +558,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f32 {
-        unsafe { intrinsics::log10f32(self) }
+        intrinsics::log10f32(self)
     }
 
     /// The positive difference of two numbers.
@@ -683,7 +683,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin(self) -> f32 {
-        unsafe { intrinsics::sinf32(self) }
+        intrinsics::sinf32(self)
     }
 
     /// Computes the cosine of a number (in radians).
@@ -707,7 +707,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cos(self) -> f32 {
-        unsafe { intrinsics::cosf32(self) }
+        intrinsics::cosf32(self)
     }
 
     /// Computes the tangent of a number (in radians).
diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs
index 1cfd3909d96..55c8593a0c0 100644
--- a/library/std/src/num/f64.rs
+++ b/library/std/src/num/f64.rs
@@ -338,7 +338,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powf(self, n: f64) -> f64 {
-        unsafe { intrinsics::powf64(self, n) }
+        intrinsics::powf64(self, n)
     }
 
     /// Returns the square root of a number.
@@ -395,7 +395,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp(self) -> f64 {
-        unsafe { intrinsics::expf64(self) }
+        intrinsics::expf64(self)
     }
 
     /// Returns `2^(self)`.
@@ -420,7 +420,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp2(self) -> f64 {
-        unsafe { intrinsics::exp2f64(self) }
+        intrinsics::exp2f64(self)
     }
 
     /// Returns the natural logarithm of the number.
@@ -455,7 +455,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f64 {
-        unsafe { intrinsics::logf64(self) }
+        intrinsics::logf64(self)
     }
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
@@ -525,7 +525,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f64 {
-        unsafe { intrinsics::log2f64(self) }
+        intrinsics::log2f64(self)
     }
 
     /// Returns the base 10 logarithm of the number.
@@ -558,7 +558,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f64 {
-        unsafe { intrinsics::log10f64(self) }
+        intrinsics::log10f64(self)
     }
 
     /// The positive difference of two numbers.
@@ -683,7 +683,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin(self) -> f64 {
-        unsafe { intrinsics::sinf64(self) }
+        intrinsics::sinf64(self)
     }
 
     /// Computes the cosine of a number (in radians).
@@ -707,7 +707,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cos(self) -> f64 {
-        unsafe { intrinsics::cosf64(self) }
+        intrinsics::cosf64(self)
     }
 
     /// Computes the tangent of a number (in radians).
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 8b7282c51d1..b7be869c4eb 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -331,7 +331,7 @@ fn default_hook(info: &PanicHookInfo<'_>) {
 
 #[cfg(not(test))]
 #[doc(hidden)]
-#[cfg(feature = "panic_immediate_abort")]
+#[cfg(panic = "immediate-abort")]
 #[unstable(feature = "update_panic_count", issue = "none")]
 pub mod panic_count {
     /// A reason for forcing an immediate abort on panic.
@@ -371,7 +371,7 @@ pub mod panic_count {
 
 #[cfg(not(test))]
 #[doc(hidden)]
-#[cfg(not(feature = "panic_immediate_abort"))]
+#[cfg(not(panic = "immediate-abort"))]
 #[unstable(feature = "update_panic_count", issue = "none")]
 pub mod panic_count {
     use crate::cell::Cell;
@@ -499,13 +499,13 @@ pub mod panic_count {
 pub use realstd::rt::panic_count;
 
 /// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
-#[cfg(feature = "panic_immediate_abort")]
+#[cfg(panic = "immediate-abort")]
 pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
     Ok(f())
 }
 
 /// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
-#[cfg(not(feature = "panic_immediate_abort"))]
+#[cfg(not(panic = "immediate-abort"))]
 pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
     union Data<F, R> {
         f: ManuallyDrop<F>,
@@ -720,14 +720,14 @@ pub fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
 #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")]
 #[cfg_attr(not(any(test, doctest)), lang = "begin_panic")]
 // lang item for CTFE panic support
-// never inline unless panic_immediate_abort to avoid code
+// never inline unless panic=immediate-abort to avoid code
 // bloat at the call sites as much as possible
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
+#[cfg_attr(panic = "immediate-abort", inline)]
 #[track_caller]
 #[rustc_do_not_const_check] // hooked by const-eval
 pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
-    if cfg!(feature = "panic_immediate_abort") {
+    if cfg!(panic = "immediate-abort") {
         intrinsics::abort()
     }
 
@@ -861,7 +861,7 @@ fn panic_with_hook(
 
 /// This is the entry point for `resume_unwind`.
 /// It just forwards the payload to the panic runtime.
-#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(panic = "immediate-abort", inline)]
 pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
     panic_count::increase(false);
 
@@ -890,16 +890,14 @@ pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
 /// on which to slap yer breakpoints.
 #[inline(never)]
 #[cfg_attr(not(test), rustc_std_internal_symbol)]
-#[cfg(not(feature = "panic_immediate_abort"))]
+#[cfg(not(panic = "immediate-abort"))]
 fn rust_panic(msg: &mut dyn PanicPayload) -> ! {
     let code = unsafe { __rust_start_panic(msg) };
     rtabort!("failed to initiate panic, error {code}")
 }
 
 #[cfg_attr(not(test), rustc_std_internal_symbol)]
-#[cfg(feature = "panic_immediate_abort")]
+#[cfg(panic = "immediate-abort")]
 fn rust_panic(_: &mut dyn PanicPayload) -> ! {
-    unsafe {
-        crate::intrinsics::abort();
-    }
+    crate::intrinsics::abort();
 }
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 8d95cc1fb57..2717b7b469c 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -39,11 +39,11 @@ fn __rust_abort() {
 // - nothing (so this macro is a no-op)
 macro_rules! rtprintpanic {
     ($($t:tt)*) => {
-        #[cfg(not(feature = "panic_immediate_abort"))]
+        #[cfg(not(panic = "immediate-abort"))]
         if let Some(mut out) = crate::sys::stdio::panic_output() {
             let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));
         }
-        #[cfg(feature = "panic_immediate_abort")]
+        #[cfg(panic = "immediate-abort")]
         {
             let _ = format_args!($($t)*);
         }
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 797feeb2bbb..0a6f2e5d508 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -230,7 +230,7 @@ impl fmt::Display for AccessError {
 impl Error for AccessError {}
 
 // This ensures the panicking code is outlined from `with` for `LocalKey`.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
 #[track_caller]
 #[cold]
 fn panic_access_error(err: AccessError) -> ! {
diff --git a/library/std_detect/src/detect/os/darwin/aarch64.rs b/library/std_detect/src/detect/os/darwin/aarch64.rs
index f5409361d93..8c9fd9647b8 100644
--- a/library/std_detect/src/detect/os/darwin/aarch64.rs
+++ b/library/std_detect/src/detect/os/darwin/aarch64.rs
@@ -37,24 +37,25 @@ pub(crate) fn detect_features() -> cache::Initializer {
     // Armv8.0 features not using the standard identifiers
     let fp = _sysctlbyname(c"hw.optional.floatingpoint");
     let asimd = _sysctlbyname(c"hw.optional.AdvSIMD");
-    let crc = _sysctlbyname(c"hw.optional.armv8_crc32");
+    let crc_old = _sysctlbyname(c"hw.optional.armv8_crc32");
 
     // Armv8 and Armv9 features using the standard identifiers
     let aes = _sysctlbyname(c"hw.optional.arm.FEAT_AES");
     let bf16 = _sysctlbyname(c"hw.optional.arm.FEAT_BF16");
     let bti = _sysctlbyname(c"hw.optional.arm.FEAT_BTI");
+    let crc = _sysctlbyname(c"hw.optional.arm.FEAT_CRC32");
     let cssc = _sysctlbyname(c"hw.optional.arm.FEAT_CSSC");
     let dit = _sysctlbyname(c"hw.optional.arm.FEAT_DIT");
+    let dotprod = _sysctlbyname(c"hw.optional.arm.FEAT_DotProd");
     let dpb = _sysctlbyname(c"hw.optional.arm.FEAT_DPB");
     let dpb2 = _sysctlbyname(c"hw.optional.arm.FEAT_DPB2");
-    let dotprod = _sysctlbyname(c"hw.optional.arm.FEAT_DotProd");
     let ecv = _sysctlbyname(c"hw.optional.arm.FEAT_ECV");
     let fcma = _sysctlbyname(c"hw.optional.arm.FEAT_FCMA");
     let fhm = _sysctlbyname(c"hw.optional.arm.FEAT_FHM");
-    let fp16 = _sysctlbyname(c"hw.optional.arm.FEAT_FP16");
-    let frintts = _sysctlbyname(c"hw.optional.arm.FEAT_FRINTTS");
     let flagm = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM");
     let flagm2 = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM2");
+    let fp16 = _sysctlbyname(c"hw.optional.arm.FEAT_FP16");
+    let frintts = _sysctlbyname(c"hw.optional.arm.FEAT_FRINTTS");
     let hbc = _sysctlbyname(c"hw.optional.arm.FEAT_HBC");
     let i8mm = _sysctlbyname(c"hw.optional.arm.FEAT_I8MM");
     let jsconv = _sysctlbyname(c"hw.optional.arm.FEAT_JSCVT");
@@ -62,6 +63,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
     let rcpc2 = _sysctlbyname(c"hw.optional.arm.FEAT_LRCPC2");
     let lse = _sysctlbyname(c"hw.optional.arm.FEAT_LSE");
     let lse2 = _sysctlbyname(c"hw.optional.arm.FEAT_LSE2");
+    let mte = _sysctlbyname(c"hw.optional.arm.FEAT_MTE");
+    let mte2 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE2");
     let pauth = _sysctlbyname(c"hw.optional.arm.FEAT_PAuth");
     let pmull = _sysctlbyname(c"hw.optional.arm.FEAT_PMULL");
     let rdm = _sysctlbyname(c"hw.optional.arm.FEAT_RDM");
@@ -72,6 +75,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
     let sha512 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA512");
     let sme = _sysctlbyname(c"hw.optional.arm.FEAT_SME");
     let sme2 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2");
+    let sme2p1 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2p1");
     let sme_f64f64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F64F64");
     let sme_i16i64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_I16I64");
     let ssbs = _sysctlbyname(c"hw.optional.arm.FEAT_SSBS");
@@ -87,6 +91,12 @@ pub(crate) fn detect_features() -> cache::Initializer {
     let ebf16 = _sysctlbyname(c"hw.optional.arm.FEAT_EBF16");
     let fpac = _sysctlbyname(c"hw.optional.arm.FEAT_FPAC");
     let fpaccombine = _sysctlbyname(c"hw.optional.arm.FEAT_FPACCOMBINE");
+    let mte_async = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_ASYNC");
+    let mte_canonical_tags = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_CANONICAL_TAGS");
+    let mte_no_address_tags = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_NO_ADDRESS_TAGS");
+    let mte_store_only = _sysctlbyname(c"hw.optional.arm.FEAT_MTE_STORE_ONLY");
+    let mte3 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE3");
+    let mte4 = _sysctlbyname(c"hw.optional.arm.FEAT_MTE4");
     let pacimp = _sysctlbyname(c"hw.optional.arm.FEAT_PACIMP");
     let pauth2 = _sysctlbyname(c"hw.optional.arm.FEAT_PAuth2");
     let rpres = _sysctlbyname(c"hw.optional.arm.FEAT_RPRES");
@@ -111,7 +121,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
     enable_feature(Feature::asimd, asimd);
     enable_feature(Feature::bf16, bf16);
     enable_feature(Feature::bti, bti);
-    enable_feature(Feature::crc, crc);
+    enable_feature(Feature::crc, crc_old || crc);
     enable_feature(Feature::cssc, cssc);
     enable_feature(Feature::dit, dit);
     enable_feature(Feature::dotprod, dotprod);
@@ -130,6 +140,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
     enable_feature(Feature::jsconv, jsconv);
     enable_feature(Feature::lse, lse);
     enable_feature(Feature::lse2, lse2);
+    enable_feature(Feature::mte, mte && mte2);
     enable_feature(Feature::paca, pauth);
     enable_feature(Feature::pacg, pauth);
     enable_feature(Feature::pmull, aes && pmull);
@@ -141,6 +152,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
     enable_feature(Feature::sha3, sha512 && sha3 && asimd);
     enable_feature(Feature::sme, sme);
     enable_feature(Feature::sme2, sme2);
+    enable_feature(Feature::sme2p1, sme2p1);
     enable_feature(Feature::sme_f64f64, sme_f64f64);
     enable_feature(Feature::sme_i16i64, sme_i16i64);
     enable_feature(Feature::ssbs, ssbs);
diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
index 855261aaecf..63af53a8e74 100644
--- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
+++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs
@@ -10306,7 +10306,7 @@ pub fn vfmad_lane_f64<const LANE: i32>(a: f64, b: f64, c: float64x1_t) -> f64 {
 #[unstable(feature = "stdarch_neon_f16", issue = "136306")]
 #[cfg(not(target_arch = "arm64ec"))]
 pub fn vfmah_f16(a: f16, b: f16, c: f16) -> f16 {
-    unsafe { fmaf16(b, c, a) }
+    fmaf16(b, c, a)
 }
 #[doc = "Floating-point fused multiply-add to accumulator"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vfmah_lane_f16)"]
@@ -22448,7 +22448,7 @@ pub fn vrndaq_f64(a: float64x2_t) -> float64x2_t {
 #[cfg(not(target_arch = "arm64ec"))]
 #[cfg_attr(test, assert_instr(frinta))]
 pub fn vrndah_f16(a: f16) -> f16 {
-    unsafe { roundf16(a) }
+    roundf16(a)
 }
 #[doc = "Floating-point round to integral, to nearest with ties to away"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndh_f16)"]
@@ -22458,7 +22458,7 @@ pub fn vrndah_f16(a: f16) -> f16 {
 #[cfg(not(target_arch = "arm64ec"))]
 #[cfg_attr(test, assert_instr(frintz))]
 pub fn vrndh_f16(a: f16) -> f16 {
-    unsafe { truncf16(a) }
+    truncf16(a)
 }
 #[doc = "Floating-point round to integral, using current rounding mode"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f16)"]
@@ -22639,7 +22639,7 @@ pub fn vrndmq_f64(a: float64x2_t) -> float64x2_t {
 #[cfg(not(target_arch = "arm64ec"))]
 #[cfg_attr(test, assert_instr(frintm))]
 pub fn vrndmh_f16(a: f16) -> f16 {
-    unsafe { floorf16(a) }
+    floorf16(a)
 }
 #[doc = "Floating-point round to integral, to nearest with ties to even"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f64)"]
@@ -22770,7 +22770,7 @@ pub fn vrndpq_f64(a: float64x2_t) -> float64x2_t {
 #[cfg(not(target_arch = "arm64ec"))]
 #[cfg_attr(test, assert_instr(frintp))]
 pub fn vrndph_f16(a: f16) -> f16 {
-    unsafe { ceilf16(a) }
+    ceilf16(a)
 }
 #[doc = "Floating-point round to integral exact, using current rounding mode"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f16)"]
@@ -24268,7 +24268,7 @@ pub fn vsqrtq_f64(a: float64x2_t) -> float64x2_t {
 #[cfg(not(target_arch = "arm64ec"))]
 #[cfg_attr(test, assert_instr(fsqrt))]
 pub fn vsqrth_f16(a: f16) -> f16 {
-    unsafe { sqrtf16(a) }
+    sqrtf16(a)
 }
 #[doc = "Shift Right and Insert (immediate)"]
 #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s8)"]
diff --git a/library/stdarch/crates/core_arch/src/wasm32/mod.rs b/library/stdarch/crates/core_arch/src/wasm32/mod.rs
index 60049c73295..01bf0a71658 100644
--- a/library/stdarch/crates/core_arch/src/wasm32/mod.rs
+++ b/library/stdarch/crates/core_arch/src/wasm32/mod.rs
@@ -43,7 +43,7 @@ pub fn unreachable() -> ! {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f32_ceil(a: f32) -> f32 {
-    unsafe { crate::intrinsics::ceilf32(a) }
+    crate::intrinsics::ceilf32(a)
 }
 
 /// Generates the [`f32.floor`] instruction, returning the largest integer less than or equal to `a`.
@@ -57,7 +57,7 @@ pub fn f32_ceil(a: f32) -> f32 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f32_floor(a: f32) -> f32 {
-    unsafe { crate::intrinsics::floorf32(a) }
+    crate::intrinsics::floorf32(a)
 }
 
 /// Generates the [`f32.trunc`] instruction, roundinging to the nearest integer towards zero.
@@ -71,7 +71,7 @@ pub fn f32_floor(a: f32) -> f32 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f32_trunc(a: f32) -> f32 {
-    unsafe { crate::intrinsics::truncf32(a) }
+    crate::intrinsics::truncf32(a)
 }
 
 /// Generates the [`f32.nearest`] instruction, roundinging to the nearest integer. Rounds half-way
@@ -100,7 +100,7 @@ pub fn f32_nearest(a: f32) -> f32 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f32_sqrt(a: f32) -> f32 {
-    unsafe { crate::intrinsics::sqrtf32(a) }
+    crate::intrinsics::sqrtf32(a)
 }
 
 /// Generates the [`f64.ceil`] instruction, returning the smallest integer greater than or equal to `a`.
@@ -114,7 +114,7 @@ pub fn f32_sqrt(a: f32) -> f32 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f64_ceil(a: f64) -> f64 {
-    unsafe { crate::intrinsics::ceilf64(a) }
+    crate::intrinsics::ceilf64(a)
 }
 
 /// Generates the [`f64.floor`] instruction, returning the largest integer less than or equal to `a`.
@@ -128,7 +128,7 @@ pub fn f64_ceil(a: f64) -> f64 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f64_floor(a: f64) -> f64 {
-    unsafe { crate::intrinsics::floorf64(a) }
+    crate::intrinsics::floorf64(a)
 }
 
 /// Generates the [`f64.trunc`] instruction, roundinging to the nearest integer towards zero.
@@ -142,7 +142,7 @@ pub fn f64_floor(a: f64) -> f64 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f64_trunc(a: f64) -> f64 {
-    unsafe { crate::intrinsics::truncf64(a) }
+    crate::intrinsics::truncf64(a)
 }
 
 /// Generates the [`f64.nearest`] instruction, roundinging to the nearest integer. Rounds half-way
@@ -171,7 +171,7 @@ pub fn f64_nearest(a: f64) -> f64 {
 #[must_use = "method returns a new number and does not mutate the original value"]
 #[unstable(feature = "wasm_numeric_instr", issue = "133908")]
 pub fn f64_sqrt(a: f64) -> f64 {
-    unsafe { crate::intrinsics::sqrtf64(a) }
+    crate::intrinsics::sqrtf64(a)
 }
 
 unsafe extern "C-unwind" {
diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
index ccdcea980e1..34b330e1b85 100644
--- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
+++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml
@@ -3108,7 +3108,7 @@ intrinsics:
     types:
       - [f16, 'h_']
     compose:
-      - FnCall: [roundf16, [a], [], true]
+      - FnCall: [roundf16, [a], []]
 
   - name: "vrndn{neon_type.no}"
     doc: "Floating-point round to integral, to nearest with ties to even"
@@ -3208,7 +3208,7 @@ intrinsics:
     types:
       - [f16, 'h_']
     compose:
-      - FnCall: [floorf16, [a], [], true]
+      - FnCall: [floorf16, [a], []]
 
 
 
@@ -3257,7 +3257,7 @@ intrinsics:
     types:
       - [f16, 'h_']
     compose:
-      - FnCall: [ceilf16, [a], [], true]
+      - FnCall: [ceilf16, [a], []]
 
   - name: "vrnd{neon_type.no}"
     doc: "Floating-point round to integral, toward zero"
@@ -3304,7 +3304,7 @@ intrinsics:
     types:
       - [f16, 'h_']
     compose:
-      - FnCall: [truncf16, [a], [], true]
+      - FnCall: [truncf16, [a], []]
 
 
   - name: "vrndi{neon_type.no}"
@@ -8499,7 +8499,7 @@ intrinsics:
     types:
       - [f16, 'h_']
     compose:
-      - FnCall: [sqrtf16, [a], [], true]
+      - FnCall: [sqrtf16, [a], []]
 
   - name: "vrsqrts{type[0]}"
     doc: "Floating-point reciprocal square root step"
@@ -10464,7 +10464,7 @@ intrinsics:
     types:
       - ["f16", "h_f16"]
     compose:
-      - FnCall: [fmaf16, [b, c, a], [], true]
+      - FnCall: [fmaf16, [b, c, a], []]
 
 
   - name: "vfmah_lane{type[2]}"
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
index 7b4aeed94e9..ee4aec61872 100644
--- a/library/sysroot/Cargo.toml
+++ b/library/sysroot/Cargo.toml
@@ -31,7 +31,6 @@ llvm-libunwind = ["std/llvm-libunwind"]
 system-llvm-libunwind = ["std/system-llvm-libunwind"]
 optimize_for_size = ["std/optimize_for_size"]
 panic-unwind = ["std/panic-unwind"]
-panic_immediate_abort = ["std/panic_immediate_abort"]
 profiler = ["dep:profiler_builtins"]
 std_detect_file_io = ["std/std_detect_file_io"]
 std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 68202500d97..91d80c96e42 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -38,6 +38,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
     "aarch64_be-unknown-hermit",
     "aarch64_be-unknown-none-softfloat",
+    "x86_64-unknown-motor",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@@ -239,6 +240,10 @@ than building it.
             continue;
         }
 
+        if target.contains("motor") {
+            continue;
+        }
+
         // skip check for cross-targets
         if skip_target_sanity && target != &build.host_target {
             continue;
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 445b10188e3..0e340de4daa 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -471,11 +471,13 @@ If not specified, overflow checks are enabled if
 This option lets you control what happens when the code panics.
 
 * `abort`: terminate the process upon panic
+* `immediate-abort`: terminate the process upon panic, and do not call any panic hooks
 * `unwind`: unwind the stack upon panic
 
 If not specified, the default depends on the target.
 
 If any crate in the crate graph uses `abort`, the final binary (`bin`, `dylib`, `cdylib`, `staticlib`) must also use `abort`.
+If any crate in the crate graph uses `immediate-abort`, every crate in the graph must use `immediate-abort`.
 If `std` is used as a `dylib` with `unwind`, the final binary must also use `unwind`.
 
 ## passes
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index ab95aa2e5a1..32e712a48d7 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -144,7 +144,7 @@ def minor_version(version):
 INSTALL_TOOLCHAIN = ["rustup", "toolchain", "install", "--profile", "minimal"]
 subprocess.run(INSTALL_TOOLCHAIN + ["nightly"])
 
-LOWER_BOUND = 73
+LOWER_BOUND = 87
 NIGHTLY_VERSION = minor_version(subprocess.run(
     ["rustc", "+nightly", "--version"],
     capture_output=True,
@@ -201,6 +201,9 @@ The following table shows known good combinations of toolchain versions.
 | 1.65 - 1.69  |      15       |
 | 1.70 - 1.72  |      16       |
 | 1.73 - 1.77  |      17       |
-| 1.78         |      18       |
+| 1.78 - 1.81  |      18       |
+| 1.82 - 1.86  |      19       |
+| 1.87 - 1.90  |      20       |
+| 1.91 - 1.92  |      21       |
 
 Note that the compatibility policy for this feature might change in the future.
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index e5e46f72637..99c8e365f5c 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -431,6 +431,7 @@ target | std | host | notes
 `x86_64-unknown-l4re-uclibc` | ? |  |
 [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * |  | 64-bit Linux with no libc
 [`x86_64-unknown-managarm-mlibc`](platform-support/managarm.md) | ? |   | x86_64 Managarm
+[`x86_64-unknown-motor`[(platform-support/motor.md) | ? |  | x86_64 Motor OS
 [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
 [`x86_64-unknown-trusty`](platform-support/trusty.md) | ✓ |  |
 `x86_64-uwp-windows-gnu` | ✓ |  |
diff --git a/src/doc/rustc/src/platform-support/motor.md b/src/doc/rustc/src/platform-support/motor.md
new file mode 100644
index 00000000000..e7aa7b23f3a
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/motor.md
@@ -0,0 +1,45 @@
+# `x86_64-unknown-motor`
+
+**Tier: 3**
+
+[Motor OS](https://github.com/moturus/motor-os) is a new operating system
+for virtualized environments.
+
+## Target maintainers
+
+[@lasiotus](https://github.com/lasiotus)
+
+## Requirements
+
+This target is cross-compiled. There are no special requirements for the host.
+
+Motor OS uses the ELF file format.
+
+## Building the target
+
+The target can be built by enabling it for a `rustc` build, for example:
+
+```toml
+[build]
+build-stage = 2
+target = ["x86_64-unknown-motor"]
+```
+
+## Building Rust programs
+
+Rust standard library is fully supported/implemented, but is not yet part of
+the official Rust repo, so an out-of-tree building process should be
+followed, as described in the
+[build doc](https://github.com/moturus/motor-os/blob/main/docs/build.md).
+
+## Testing
+
+Cross-compiled Rust binaries and test artifacts can be executed in Motor OS VMs,
+as described in e.g.
+[Hello Motor OS](https://github.com/moturus/motor-os/blob/main/docs/recipes/hello-motor-os.md)
+example.
+
+## Cross-compilation toolchains and C code
+
+C code can be compiled as part of Rust cargo projects. However, there is
+no libc support.
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index d9566c9f55c..9434868dc08 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -36,6 +36,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `freg`         | `f[0-31]`                          | `f`                  |
 | PowerPC      | `vreg`         | `v[0-31]`                          | `v`                  |
 | PowerPC      | `cr`           | `cr[0-7]`, `cr`                    | Only clobbers        |
+| PowerPC      | `ctr`          | `ctr`                              | Only clobbers        |
+| PowerPC      | `lr`           | `lr`                               | Only clobbers        |
 | PowerPC      | `xer`          | `xer`                              | Only clobbers        |
 | wasm32       | `local`        | None\*                             | `r`                  |
 | BPF          | `reg`          | `r[0-10]`                          | `r`                  |
@@ -78,6 +80,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `vreg`                          | `altivec`      | `i8x16`, `i16x8`, `i32x4`, `f32x4`      |
 | PowerPC      | `vreg`                          | `vsx`          | `f32`, `f64`, `i64x2`, `f64x2`          |
 | PowerPC      | `cr`                            | N/A            | Only clobbers                           |
+| PowerPC      | `ctr`                           | N/A            | Only clobbers                           |
+| PowerPC      | `lr`                            | N/A            | Only clobbers                           |
 | PowerPC      | `xer`                           | N/A            | Only clobbers                           |
 | wasm32       | `local`                         | None           | `i8` `i16` `i32` `i64` `f32` `f64`      |
 | BPF          | `reg`                           | None           | `i8` `i16` `i32` `i64`                  |
@@ -150,8 +154,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | MIPS         | `$ra`                                   | Return address cannot be used as inputs or outputs.                                                                                                                                 |
 | Hexagon      | `lr`                                    | This is the link register which cannot be used as an input or output.                                                                                                               |
 | PowerPC      | `r2`, `r13`                             | These are system reserved registers.                                                                                                                                                |
-| PowerPC      | `lr`                                    | The link register cannot be used as an input or output.                                                                                                                             |
-| PowerPC      | `ctr`                                   | The counter register cannot be used as an input or output.                                                                                                                          |
 | PowerPC      | `vrsave`                                | The vrsave register cannot be used as an input or output.                                                                                                                           |
 | AVR          | `r0`, `r1`, `r1r0`                      | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs.  If modified, they must be restored to their original values before the end of the block. |
 |MSP430        | `r0`, `r2`, `r3`                        | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to.                          |
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index e204e1788ba..8feca1367fc 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -3,16 +3,16 @@
 // FIXME: Once the portability lint RFC is implemented (see tracking issue #41619),
 // switch to use those structures instead.
 
-use std::fmt::{self, Write};
-use std::{mem, ops};
+use std::{fmt, mem, ops};
 
+use itertools::Either;
 use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_session::parse::ParseSess;
 use rustc_span::Span;
 use rustc_span::symbol::{Symbol, sym};
 
-use crate::display::Joined as _;
+use crate::display::{Joined as _, MaybeDisplay, Wrapped};
 use crate::html::escape::Escape;
 
 #[cfg(test)]
@@ -376,27 +376,20 @@ impl Format {
             Format::LongPlain => false,
         }
     }
+
+    fn escape(self, s: &str) -> impl fmt::Display {
+        if self.is_html() { Either::Left(Escape(s)) } else { Either::Right(s) }
+    }
 }
 
 /// Pretty-print wrapper for a `Cfg`. Also indicates what form of rendering should be used.
 struct Display<'a>(&'a Cfg, Format);
 
-fn write_with_opt_paren<T: fmt::Display>(
-    fmt: &mut fmt::Formatter<'_>,
-    has_paren: bool,
-    obj: T,
-) -> fmt::Result {
-    if has_paren {
-        fmt.write_char('(')?;
-    }
-    obj.fmt(fmt)?;
-    if has_paren {
-        fmt.write_char(')')?;
+impl Display<'_> {
+    fn code_wrappers(&self) -> Wrapped<&'static str> {
+        if self.1.is_html() { Wrapped::with("<code>", "</code>") } else { Wrapped::with("`", "`") }
     }
-    Ok(())
-}
 
-impl Display<'_> {
     fn display_sub_cfgs(
         &self,
         fmt: &mut fmt::Formatter<'_>,
@@ -427,20 +420,17 @@ impl Display<'_> {
             sub_cfgs
                 .iter()
                 .map(|sub_cfg| {
-                    fmt::from_fn(move |fmt| {
-                        if let Cfg::Cfg(_, Some(feat)) = sub_cfg
-                            && short_longhand
-                        {
-                            if self.1.is_html() {
-                                write!(fmt, "<code>{feat}</code>")?;
-                            } else {
-                                write!(fmt, "`{feat}`")?;
-                            }
-                        } else {
-                            write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?;
-                        }
-                        Ok(())
-                    })
+                    if let Cfg::Cfg(_, Some(feat)) = sub_cfg
+                        && short_longhand
+                    {
+                        Either::Left(self.code_wrappers().wrap(feat))
+                    } else {
+                        Either::Right(
+                            Wrapped::with_parens()
+                                .when(!sub_cfg.is_all())
+                                .wrap(Display(sub_cfg, self.1)),
+                        )
+                    }
                 })
                 .joined(separator, f)
         })
@@ -461,9 +451,9 @@ impl fmt::Display for Display<'_> {
                 sub_cfgs
                     .iter()
                     .map(|sub_cfg| {
-                        fmt::from_fn(|fmt| {
-                            write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))
-                        })
+                        Wrapped::with_parens()
+                            .when(!sub_cfg.is_all())
+                            .wrap(Display(sub_cfg, self.1))
                     })
                     .joined(separator, fmt)
             }
@@ -568,21 +558,13 @@ impl fmt::Display for Display<'_> {
                 };
                 if !human_readable.is_empty() {
                     fmt.write_str(human_readable)
-                } else if let Some(v) = value {
-                    if self.1.is_html() {
-                        write!(
-                            fmt,
-                            r#"<code>{}="{}"</code>"#,
-                            Escape(name.as_str()),
-                            Escape(v.as_str())
-                        )
-                    } else {
-                        write!(fmt, r#"`{name}="{v}"`"#)
-                    }
-                } else if self.1.is_html() {
-                    write!(fmt, "<code>{}</code>", Escape(name.as_str()))
                 } else {
-                    write!(fmt, "`{name}`")
+                    let value = value
+                        .map(|v| fmt::from_fn(move |f| write!(f, "={}", self.1.escape(v.as_str()))))
+                        .maybe_display();
+                    self.code_wrappers()
+                        .wrap(format_args!("{}{value}", self.1.escape(name.as_str())))
+                        .fmt(fmt)
                 }
             }
         }
diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs
index db868c5c9a8..d62ea4c3688 100644
--- a/src/librustdoc/display.rs
+++ b/src/librustdoc/display.rs
@@ -1,6 +1,6 @@
 //! Various utilities for working with [`fmt::Display`] implementations.
 
-use std::fmt::{self, Display, Formatter};
+use std::fmt::{self, Display, Formatter, FormattingOptions};
 
 pub(crate) trait Joined: IntoIterator {
     /// Takes an iterator over elements that implement [`Display`], and format them into `f`, separated by `sep`.
@@ -45,3 +45,87 @@ impl<T: Display> MaybeDisplay for Option<T> {
         })
     }
 }
+
+#[derive(Clone, Copy)]
+pub(crate) struct Wrapped<T> {
+    prefix: T,
+    suffix: T,
+}
+
+pub(crate) enum AngleBracket {
+    Open,
+    Close,
+}
+
+impl Display for AngleBracket {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        f.write_str(match (self, f.alternate()) {
+            (Self::Open, true) => "<",
+            (Self::Open, false) => "&lt;",
+            (Self::Close, true) => ">",
+            (Self::Close, false) => "&gt;",
+        })
+    }
+}
+
+impl Wrapped<AngleBracket> {
+    pub(crate) fn with_angle_brackets() -> Self {
+        Self { prefix: AngleBracket::Open, suffix: AngleBracket::Close }
+    }
+}
+
+impl Wrapped<char> {
+    pub(crate) fn with_parens() -> Self {
+        Self { prefix: '(', suffix: ')' }
+    }
+
+    pub(crate) fn with_square_brackets() -> Self {
+        Self { prefix: '[', suffix: ']' }
+    }
+}
+
+impl<T: Display> Wrapped<T> {
+    pub(crate) fn with(prefix: T, suffix: T) -> Self {
+        Self { prefix, suffix }
+    }
+
+    pub(crate) fn when(self, if_: bool) -> Wrapped<impl Display> {
+        Wrapped {
+            prefix: if_.then_some(self.prefix).maybe_display(),
+            suffix: if_.then_some(self.suffix).maybe_display(),
+        }
+    }
+
+    pub(crate) fn wrap_fn(
+        self,
+        content: impl Fn(&mut Formatter<'_>) -> fmt::Result,
+    ) -> impl Display {
+        fmt::from_fn(move |f| {
+            self.prefix.fmt(f)?;
+            content(f)?;
+            self.suffix.fmt(f)
+        })
+    }
+
+    pub(crate) fn wrap<C: Display>(self, content: C) -> impl Display {
+        self.wrap_fn(move |f| content.fmt(f))
+    }
+}
+
+#[derive(Clone, Copy)]
+pub(crate) struct WithOpts {
+    opts: FormattingOptions,
+}
+
+impl WithOpts {
+    pub(crate) fn from(f: &Formatter<'_>) -> Self {
+        Self { opts: f.options() }
+    }
+
+    pub(crate) fn display(self, t: impl Display) -> impl Display {
+        fmt::from_fn(move |f| {
+            let mut f = f.with_options(self.opts);
+            t.fmt(&mut f)
+        })
+    }
+}
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 8c75f301841..ecaff4cdf43 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -30,7 +30,7 @@ use super::url_parts_builder::UrlPartsBuilder;
 use crate::clean::types::ExternalLocation;
 use crate::clean::utils::find_nearest_parent_module;
 use crate::clean::{self, ExternalCrate, PrimitiveType};
-use crate::display::{Joined as _, MaybeDisplay as _};
+use crate::display::{Joined as _, MaybeDisplay as _, WithOpts, Wrapped};
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::html::escape::{Escape, EscapeBodyText};
@@ -105,20 +105,16 @@ impl clean::GenericParamDef {
 
 impl clean::Generics {
     pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| {
-            let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
-            if real_params.peek().is_none() {
-                return Ok(());
-            }
-
-            let real_params =
-                fmt::from_fn(|f| real_params.clone().map(|g| g.print(cx)).joined(", ", f));
-            if f.alternate() {
-                write!(f, "<{real_params:#}>")
-            } else {
-                write!(f, "&lt;{real_params}&gt;")
-            }
-        })
+        let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
+        if real_params.peek().is_none() {
+            None
+        } else {
+            Some(
+                Wrapped::with_angle_brackets()
+                    .wrap_fn(move |f| real_params.clone().map(|g| g.print(cx)).joined(", ", f)),
+            )
+        }
+        .maybe_display()
     }
 }
 
@@ -151,11 +147,8 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) ->
                 Ok(())
             }
             clean::WherePredicate::EqPredicate { lhs, rhs } => {
-                if f.alternate() {
-                    write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx))
-                } else {
-                    write!(f, "{} == {}", lhs.print(cx), rhs.print(cx))
-                }
+                let opts = WithOpts::from(f);
+                write!(f, "{} == {}", opts.display(lhs.print(cx)), opts.display(rhs.print(cx)))
             }
         }
     })
@@ -279,13 +272,10 @@ impl clean::GenericBound {
                 ty.print(cx).fmt(f)
             }
             clean::GenericBound::Use(args) => {
-                if f.alternate() {
-                    f.write_str("use<")?;
-                } else {
-                    f.write_str("use&lt;")?;
-                }
-                args.iter().map(|arg| arg.name()).joined(", ", f)?;
-                if f.alternate() { f.write_str(">") } else { f.write_str("&gt;") }
+                f.write_str("use")?;
+                Wrapped::with_angle_brackets()
+                    .wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f))
+                    .fmt(f)
             }
         })
     }
@@ -297,40 +287,29 @@ impl clean::GenericArgs {
             match self {
                 clean::GenericArgs::AngleBracketed { args, constraints } => {
                     if !args.is_empty() || !constraints.is_empty() {
-                        if f.alternate() {
-                            f.write_str("<")?;
-                        } else {
-                            f.write_str("&lt;")?;
-                        }
-
-                        [Either::Left(args), Either::Right(constraints)]
-                            .into_iter()
-                            .flat_map(Either::factor_into_iter)
-                            .map(|either| {
-                                either.map_either(
-                                    |arg| arg.print(cx),
-                                    |constraint| constraint.print(cx),
-                                )
+                        Wrapped::with_angle_brackets()
+                            .wrap_fn(|f| {
+                                [Either::Left(args), Either::Right(constraints)]
+                                    .into_iter()
+                                    .flat_map(Either::factor_into_iter)
+                                    .map(|either| {
+                                        either.map_either(
+                                            |arg| arg.print(cx),
+                                            |constraint| constraint.print(cx),
+                                        )
+                                    })
+                                    .joined(", ", f)
                             })
-                            .joined(", ", f)?;
-
-                        if f.alternate() {
-                            f.write_str(">")?;
-                        } else {
-                            f.write_str("&gt;")?;
-                        }
+                            .fmt(f)?;
                     }
                 }
                 clean::GenericArgs::Parenthesized { inputs, output } => {
-                    f.write_str("(")?;
-                    inputs.iter().map(|ty| ty.print(cx)).joined(", ", f)?;
-                    f.write_str(")")?;
+                    Wrapped::with_parens()
+                        .wrap_fn(|f| inputs.iter().map(|ty| ty.print(cx)).joined(", ", f))
+                        .fmt(f)?;
                     if let Some(ref ty) = *output {
-                        if f.alternate() {
-                            write!(f, " -> {:#}", ty.print(cx))?;
-                        } else {
-                            write!(f, " -&gt; {}", ty.print(cx))?;
-                        }
+                        f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
+                        ty.print(cx).fmt(f)?;
                     }
                 }
                 clean::GenericArgs::ReturnTypeNotation => {
@@ -834,9 +813,10 @@ fn print_higher_ranked_params_with_space(
     fmt::from_fn(move |f| {
         if !params.is_empty() {
             f.write_str(keyword)?;
-            f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
-            params.iter().map(|lt| lt.print(cx)).joined(", ", f)?;
-            f.write_str(if f.alternate() { "> " } else { "&gt; " })?;
+            Wrapped::with_angle_brackets()
+                .wrap_fn(|f| params.iter().map(|lt| lt.print(cx)).joined(", ", f))
+                .fmt(f)?;
+            f.write_char(' ')?;
         }
         Ok(())
     })
@@ -923,26 +903,23 @@ fn fmt_type(
                         f,
                         PrimitiveType::Tuple,
                         format_args!(
-                            "({})",
-                            fmt::from_fn(|f| generic_names.iter().joined(", ", f))
+                            "{}",
+                            Wrapped::with_parens()
+                                .wrap_fn(|f| generic_names.iter().joined(", ", f))
                         ),
                         cx,
                     )
                 } else {
-                    f.write_str("(")?;
-                    many.iter().map(|item| item.print(cx)).joined(", ", f)?;
-                    f.write_str(")")
+                    Wrapped::with_parens()
+                        .wrap_fn(|f| many.iter().map(|item| item.print(cx)).joined(", ", f))
+                        .fmt(f)
                 }
             }
         },
         clean::Slice(box clean::Generic(name)) => {
             primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx)
         }
-        clean::Slice(t) => {
-            write!(f, "[")?;
-            t.print(cx).fmt(f)?;
-            write!(f, "]")
-        }
+        clean::Slice(t) => Wrapped::with_square_brackets().wrap(t.print(cx)).fmt(f),
         clean::Type::Pat(t, pat) => {
             fmt::Display::fmt(&t.print(cx), f)?;
             write!(f, " is {pat}")
@@ -953,40 +930,27 @@ fn fmt_type(
             format_args!("[{name}; {n}]", n = Escape(n)),
             cx,
         ),
-        clean::Array(t, n) => {
-            write!(f, "[")?;
-            t.print(cx).fmt(f)?;
-            if f.alternate() {
-                write!(f, "; {n}")?;
-            } else {
-                write!(f, "; ")?;
-                primitive_link(f, PrimitiveType::Array, format_args!("{n}", n = Escape(n)), cx)?;
-            }
-            write!(f, "]")
-        }
-        clean::RawPointer(m, t) => {
-            let m = match m {
-                hir::Mutability::Mut => "mut",
-                hir::Mutability::Not => "const",
-            };
-
-            if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
-                let ty = t.print(cx);
+        clean::Array(t, n) => Wrapped::with_square_brackets()
+            .wrap(fmt::from_fn(|f| {
+                t.print(cx).fmt(f)?;
+                f.write_str("; ")?;
                 if f.alternate() {
-                    primitive_link(
-                        f,
-                        clean::PrimitiveType::RawPointer,
-                        format_args!("*{m} {ty:#}"),
-                        cx,
-                    )
+                    f.write_str(n)
                 } else {
-                    primitive_link(
-                        f,
-                        clean::PrimitiveType::RawPointer,
-                        format_args!("*{m} {ty}"),
-                        cx,
-                    )
+                    primitive_link(f, PrimitiveType::Array, format_args!("{n}", n = Escape(n)), cx)
                 }
+            }))
+            .fmt(f),
+        clean::RawPointer(m, t) => {
+            let m = m.ptr_str();
+
+            if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
+                primitive_link(
+                    f,
+                    clean::PrimitiveType::RawPointer,
+                    format_args!("*{m} {ty}", ty = WithOpts::from(f).display(t.print(cx))),
+                    cx,
+                )
             } else {
                 primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?;
                 t.print(cx).fmt(f)
@@ -1020,14 +984,10 @@ fn fmt_type(
                 clean::ImplTrait(ref bounds) if bounds.len() > 1 => true,
                 _ => false,
             };
-            if needs_parens {
-                f.write_str("(")?;
-            }
-            fmt_type(ty, f, use_absolute, cx)?;
-            if needs_parens {
-                f.write_str(")")?;
-            }
-            Ok(())
+            Wrapped::with_parens()
+                .when(needs_parens)
+                .wrap_fn(|f| fmt_type(ty, f, use_absolute, cx))
+                .fmt(f)
         }
         clean::ImplTrait(bounds) => {
             f.write_str("impl ")?;
@@ -1057,23 +1017,21 @@ impl clean::QPathData {
             // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
             // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
 
-            if f.alternate() {
-                if let Some(trait_) = trait_
-                    && should_fully_qualify
-                {
-                    write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
-                } else {
-                    write!(f, "{:#}::", self_type.print(cx))?
-                }
+            if let Some(trait_) = trait_
+                && should_fully_qualify
+            {
+                let opts = WithOpts::from(f);
+                Wrapped::with_angle_brackets()
+                    .wrap(format_args!(
+                        "{} as {}",
+                        opts.display(self_type.print(cx)),
+                        opts.display(trait_.print(cx))
+                    ))
+                    .fmt(f)?
             } else {
-                if let Some(trait_) = trait_
-                    && should_fully_qualify
-                {
-                    write!(f, "&lt;{} as {}&gt;::", self_type.print(cx), trait_.print(cx))?
-                } else {
-                    write!(f, "{}::", self_type.print(cx))?
-                }
-            };
+                self_type.print(cx).fmt(f)?;
+            }
+            f.write_str("::")?;
             // It's pretty unsightly to look at `<A as B>::C` in output, and
             // we've got hyperlinking on our side, so try to avoid longer
             // notation as much as possible by making `C` a hyperlink to trait
@@ -1132,7 +1090,7 @@ impl clean::Impl {
 
             if let Some(ref ty) = self.trait_ {
                 if self.is_negative_trait_impl() {
-                    write!(f, "!")?;
+                    f.write_char('!')?;
                 }
                 if self.kind.is_fake_variadic()
                     && let Some(generics) = ty.generics()
@@ -1140,18 +1098,17 @@ impl clean::Impl {
                 {
                     let last = ty.last();
                     if f.alternate() {
-                        write!(f, "{last}<")?;
-                        self.print_type(inner_type, f, use_absolute, cx)?;
-                        write!(f, ">")?;
+                        write!(f, "{last}")?;
                     } else {
-                        write!(f, "{}&lt;", print_anchor(ty.def_id(), last, cx))?;
-                        self.print_type(inner_type, f, use_absolute, cx)?;
-                        write!(f, "&gt;")?;
-                    }
+                        write!(f, "{}", print_anchor(ty.def_id(), last, cx))?;
+                    };
+                    Wrapped::with_angle_brackets()
+                        .wrap_fn(|f| self.print_type(inner_type, f, use_absolute, cx))
+                        .fmt(f)?;
                 } else {
                     ty.print(cx).fmt(f)?;
                 }
-                write!(f, " for ")?;
+                f.write_str(" for ")?;
             }
 
             if let Some(ty) = self.kind.as_blanket_ty() {
@@ -1218,18 +1175,10 @@ impl clean::Impl {
             && let Ok(ty) = generics.exactly_one()
             && self.kind.is_fake_variadic()
         {
-            let wrapper = print_anchor(path.def_id(), path.last(), cx);
-            if f.alternate() {
-                write!(f, "{wrapper:#}&lt;")?;
-            } else {
-                write!(f, "{wrapper}<")?;
-            }
-            self.print_type(ty, f, use_absolute, cx)?;
-            if f.alternate() {
-                write!(f, "&gt;")?;
-            } else {
-                write!(f, ">")?;
-            }
+            print_anchor(path.def_id(), path.last(), cx).fmt(f)?;
+            Wrapped::with_angle_brackets()
+                .wrap_fn(|f| self.print_type(ty, f, use_absolute, cx))
+                .fmt(f)?;
         } else {
             fmt_type(type_, f, use_absolute, cx)?;
         }
@@ -1311,23 +1260,13 @@ impl clean::FnDecl {
     pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             let ellipsis = if self.c_variadic { ", ..." } else { "" };
-            if f.alternate() {
-                write!(
-                    f,
-                    "({params:#}{ellipsis}){arrow:#}",
-                    params = print_params(&self.inputs, cx),
-                    ellipsis = ellipsis,
-                    arrow = self.print_output(cx)
-                )
-            } else {
-                write!(
-                    f,
-                    "({params}{ellipsis}){arrow}",
-                    params = print_params(&self.inputs, cx),
-                    ellipsis = ellipsis,
-                    arrow = self.print_output(cx)
-                )
-            }
+            Wrapped::with_parens()
+                .wrap_fn(|f| {
+                    print_params(&self.inputs, cx).fmt(f)?;
+                    f.write_str(ellipsis)
+                })
+                .fmt(f)?;
+            self.print_output(cx).fmt(f)
         })
     }
 
@@ -1346,8 +1285,7 @@ impl clean::FnDecl {
         fmt::from_fn(move |f| {
             // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
             let mut counter = WriteCounter(0);
-            write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))
-                .unwrap();
+            write!(&mut counter, "{:#}", fmt::from_fn(|f| { self.inner_full_print(None, f, cx) }))?;
             // If the text form was over 80 characters wide, we will line-wrap our output.
             let line_wrapping_indent =
                 if header_len + counter.0 > 80 { Some(indent) } else { None };
@@ -1365,53 +1303,56 @@ impl clean::FnDecl {
         f: &mut fmt::Formatter<'_>,
         cx: &Context<'_>,
     ) -> fmt::Result {
-        f.write_char('(')?;
+        Wrapped::with_parens()
+            .wrap_fn(|f| {
+                if !self.inputs.is_empty() {
+                    let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
 
-        if !self.inputs.is_empty() {
-            let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
-
-            if let Some(indent) = line_wrapping_indent {
-                write!(f, "\n{indent}")?;
-            }
+                    if let Some(indent) = line_wrapping_indent {
+                        write!(f, "\n{indent}")?;
+                    }
 
-            let sep = fmt::from_fn(|f| {
-                if let Some(indent) = line_wrapping_indent {
-                    write!(f, ",\n{indent}")
-                } else {
-                    f.write_str(", ")
-                }
-            });
+                    let sep = fmt::from_fn(|f| {
+                        if let Some(indent) = line_wrapping_indent {
+                            write!(f, ",\n{indent}")
+                        } else {
+                            f.write_str(", ")
+                        }
+                    });
 
-            self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
+                    self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
 
-            if line_wrapping_indent.is_some() {
-                writeln!(f, ",")?
-            }
+                    if line_wrapping_indent.is_some() {
+                        writeln!(f, ",")?
+                    }
 
-            if self.c_variadic {
-                match line_wrapping_indent {
-                    None => write!(f, ", ...")?,
-                    Some(indent) => writeln!(f, "{indent}...")?,
-                };
-            }
-        }
+                    if self.c_variadic {
+                        match line_wrapping_indent {
+                            None => write!(f, ", ...")?,
+                            Some(indent) => writeln!(f, "{indent}...")?,
+                        };
+                    }
+                }
 
-        if let Some(n) = line_wrapping_indent {
-            write!(f, "{}", Indent(n))?
-        }
+                if let Some(n) = line_wrapping_indent {
+                    write!(f, "{}", Indent(n))?
+                }
 
-        f.write_char(')')?;
+                Ok(())
+            })
+            .fmt(f)?;
 
         self.print_output(cx).fmt(f)
     }
 
     fn print_output(&self, cx: &Context<'_>) -> impl Display {
-        fmt::from_fn(move |f| match &self.output {
-            clean::Tuple(tys) if tys.is_empty() => Ok(()),
-            ty if f.alternate() => {
-                write!(f, " -> {:#}", ty.print(cx))
+        fmt::from_fn(move |f| {
+            if self.output.is_unit() {
+                return Ok(());
             }
-            ty => write!(f, " -&gt; {}", ty.print(cx)),
+
+            f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
+            self.output.print(cx).fmt(f)
         })
     }
 }
@@ -1422,10 +1363,13 @@ pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>)
             f.write_str("#[doc(hidden)] ")?;
         }
 
-        match item.visibility(cx.tcx()) {
-            None => {}
-            Some(ty::Visibility::Public) => f.write_str("pub ")?,
-            Some(ty::Visibility::Restricted(vis_did)) => {
+        let Some(vis) = item.visibility(cx.tcx()) else {
+            return Ok(());
+        };
+
+        match vis {
+            ty::Visibility::Public => f.write_str("pub ")?,
+            ty::Visibility::Restricted(vis_did) => {
                 // FIXME(camelid): This may not work correctly if `item_did` is a module.
                 //                 However, rustdoc currently never displays a module's
                 //                 visibility, so it shouldn't matter.
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 75febd6f737..3ea9de381ec 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -2227,11 +2227,18 @@ function preLoadCss(cssUrl) {
     });
 }());
 
-// This section is a bugfix for firefox: when copying text with `user-select: none`, it adds
-// extra backline characters.
+
+// Workaround for browser-specific bugs when copying code snippets.
+//
+// * In Firefox, copying text that includes elements with `user-select: none`
+//   inserts extra blank lines.
+//   - Firefox issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1273836
+//   - Rust issue: https://github.com/rust-lang/rust/issues/141464
 //
-// Rustdoc issue: Workaround for https://github.com/rust-lang/rust/issues/141464
-// Firefox issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1273836
+// * In Chromium-based browsers, `document.getSelection()` includes elements
+//   with `user-select: none`, causing unwanted line numbers to be copied.
+//   - Chromium issue: https://issues.chromium.org/issues/446539520
+//   - Rust issue: https://github.com/rust-lang/rust/issues/146816
 (function() {
     document.body.addEventListener("copy", event => {
         let target = nonnull(event.target);
@@ -2248,9 +2255,13 @@ function preLoadCss(cssUrl) {
         if (!isInsideCode) {
             return;
         }
-        const selection = document.getSelection();
-         // @ts-expect-error
-        nonnull(event.clipboardData).setData("text/plain", selection.toString());
+        const selection = nonnull(document.getSelection());
+        const text = Array.from({ length: selection.rangeCount }, (_, i) => {
+            const fragment = selection.getRangeAt(i).cloneContents();
+            fragment.querySelectorAll("[data-nosnippet]").forEach(el => el.remove());
+            return fragment.textContent;
+        }).join("");
+        nonnull(event.clipboardData).setData("text/plain", text);
         event.preventDefault();
     });
 }());
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 9871066b9eb..5d8f8f4bed1 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -10,6 +10,7 @@
 #![feature(box_patterns)]
 #![feature(debug_closure_helpers)]
 #![feature(file_buffered)]
+#![feature(formatting_options)]
 #![feature(if_let_guard)]
 #![feature(iter_advance_by)]
 #![feature(iter_intersperse)]
@@ -835,8 +836,10 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
         config::InputMode::NoInputMergeFinalize => {
             return wrap_return(
                 dcx,
-                run_merge_finalize(render_options)
-                    .map_err(|e| format!("could not write merged cross-crate info: {e}")),
+                rustc_span::create_session_globals_then(options.edition, &[], None, || {
+                    run_merge_finalize(render_options)
+                        .map_err(|e| format!("could not write merged cross-crate info: {e}"))
+                }),
             );
         }
     };
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index cdada5a2230..6597c3c70f6 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -12,7 +12,7 @@ path = "src/bin/main.rs"
 
 [dependencies]
 # tidy-alphabetical-start
-anstyle-svg = "0.1.3"
+anstyle-svg = "0.1.11"
 build_helper = { path = "../../build_helper" }
 camino = "1"
 colored = "2"
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index 1277fd225eb..e84a2278766 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -201,6 +201,8 @@ pub struct TestProps {
     /// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios
     /// that don't otherwise want/need `-Z build-std`.
     pub add_core_stubs: bool,
+    /// Add these flags to the build of `minicore`.
+    pub core_stubs_compile_flags: Vec<String>,
     /// Whether line annotatins are required for the given error kind.
     pub dont_require_annotations: HashSet<ErrorKind>,
     /// Whether pretty printers should be disabled in gdb.
@@ -253,6 +255,7 @@ mod directives {
     pub const FILECHECK_FLAGS: &'static str = "filecheck-flags";
     pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg";
     pub const ADD_CORE_STUBS: &'static str = "add-core-stubs";
+    pub const CORE_STUBS_COMPILE_FLAGS: &'static str = "core-stubs-compile-flags";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
     pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers";
@@ -311,6 +314,7 @@ impl TestProps {
             no_auto_check_cfg: false,
             has_enzyme: false,
             add_core_stubs: false,
+            core_stubs_compile_flags: vec![],
             dont_require_annotations: Default::default(),
             disable_gdb_pretty_printers: false,
             compare_output_by_lines: false,
@@ -653,6 +657,21 @@ impl TestProps {
 
                     self.update_add_core_stubs(ln, config);
 
+                    if let Some(flags) = config.parse_name_value_directive(
+                        ln,
+                        directives::CORE_STUBS_COMPILE_FLAGS,
+                        testfile,
+                        line_number,
+                    ) {
+                        let flags = split_flags(&flags);
+                        for flag in &flags {
+                            if flag == "--edition" || flag.starts_with("--edition=") {
+                                panic!("you must use `//@ edition` to configure the edition");
+                            }
+                        }
+                        self.core_stubs_compile_flags.extend(flags);
+                    }
+
                     if let Some(err_kind) = config.parse_name_value_directive(
                         ln,
                         DONT_REQUIRE_ANNOTATIONS,
diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs
index 0ef84fb4594..4fef8992567 100644
--- a/src/tools/compiletest/src/directives/directive_names.rs
+++ b/src/tools/compiletest/src/directives/directive_names.rs
@@ -19,6 +19,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "check-test-line-numbers-match",
     "compare-output-by-lines",
     "compile-flags",
+    "core-stubs-compile-flags",
     "disable-gdb-pretty-printers",
     "doc-flags",
     "dont-check-compiler-stderr",
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 89fb8eb4357..29578acb404 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1322,6 +1322,7 @@ impl<'test> TestCx<'test> {
 
         rustc.args(&["--crate-type", "rlib"]);
         rustc.arg("-Cpanic=abort");
+        rustc.args(self.props.core_stubs_compile_flags.clone());
 
         let res = self.compose_and_run(rustc, self.config.compile_lib_path.as_path(), None, None);
         if !res.status.success() {
@@ -1432,6 +1433,12 @@ impl<'test> TestCx<'test> {
 
         aux_rustc.arg("-L").arg(&aux_dir);
 
+        if aux_props.add_core_stubs {
+            let minicore_path = self.build_minicore();
+            aux_rustc.arg("--extern");
+            aux_rustc.arg(&format!("minicore={}", minicore_path));
+        }
+
         let auxres = aux_cx.compose_and_run(
             aux_rustc,
             aux_cx.config.compile_lib_path.as_path(),
@@ -1858,14 +1865,13 @@ impl<'test> TestCx<'test> {
             }
         }
 
-        rustc.args(&self.props.compile_flags);
-
         // FIXME(jieyouxu): we should report a fatal error or warning if user wrote `-Cpanic=` with
-        // something that's not `abort` and `-Cforce-unwind-tables` with a value that is not `yes`,
-        // however, by moving this last we should override previous `-Cpanic`s and
-        // `-Cforce-unwind-tables`s. Note that checking here is very fragile, because we'd have to
-        // account for all possible compile flag splittings (they have some... intricacies and are
-        // not yet normalized).
+        // something that's not `abort` and `-Cforce-unwind-tables` with a value that is not `yes`.
+        //
+        // We could apply these last and override any provided flags. That would ensure that the
+        // build works, but some tests want to exercise that mixing panic modes in specific ways is
+        // rejected. So we enable aborting panics and unwind tables before adding flags, just to
+        // change the default.
         //
         // `minicore` requires `#![no_std]` and `#![no_core]`, which means no unwinding panics.
         if self.props.add_core_stubs {
@@ -1873,6 +1879,8 @@ impl<'test> TestCx<'test> {
             rustc.arg("-Cforce-unwind-tables=yes");
         }
 
+        rustc.args(&self.props.compile_flags);
+
         rustc
     }
 
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 3ce5ea8356b..3a764329f9b 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1415,12 +1415,12 @@ fn test_fmuladd() {
 
     #[inline(never)]
     pub fn test_operations_f32(a: f32, b: f32, c: f32) {
-        assert_approx_eq!(unsafe { fmuladdf32(a, b, c) }, a * b + c);
+        assert_approx_eq!(fmuladdf32(a, b, c), a * b + c);
     }
 
     #[inline(never)]
     pub fn test_operations_f64(a: f64, b: f64, c: f64) {
-        assert_approx_eq!(unsafe { fmuladdf64(a, b, c) }, a * b + c);
+        assert_approx_eq!(fmuladdf64(a, b, c), a * b + c);
     }
 
     test_operations_f32(0.1, 0.2, 0.3);
diff --git a/src/tools/miri/tests/pass/intrinsics/fmuladd_nondeterministic.rs b/src/tools/miri/tests/pass/intrinsics/fmuladd_nondeterministic.rs
index b688405c4b1..4d3e91c4cba 100644
--- a/src/tools/miri/tests/pass/intrinsics/fmuladd_nondeterministic.rs
+++ b/src/tools/miri/tests/pass/intrinsics/fmuladd_nondeterministic.rs
@@ -28,7 +28,7 @@ fn main() {
             let c = std::hint::black_box(-a * b);
             // It is unspecified whether the following operation is fused or not. The
             // following evaluates to 0.0 if unfused, and nonzero (-1.66e-18) if fused.
-            let x = unsafe { fmuladdf64(a, b, c) };
+            let x = fmuladdf64(a, b, c);
             x == 0.0
         }),
         "`fmuladdf64` failed to be evaluated as both fused and unfused"
@@ -41,7 +41,7 @@ fn main() {
             let c = std::hint::black_box(-a * b);
             // It is unspecified whether the following operation is fused or not. The
             // following evaluates to 0.0 if unfused, and nonzero (-8.1956386e-10) if fused.
-            let x = unsafe { fmuladdf32(a, b, c) };
+            let x = fmuladdf32(a, b, c);
             x == 0.0
         }),
         "`fmuladdf32` failed to be evaluated as both fused and unfused"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index e275d3042cb..247080102fb 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -367,6 +367,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "expect-test",
     "fallible-iterator", // dependency of `thorin`
     "fastrand",
+    "find-msvc-tools",
     "flate2",
     "fluent-bundle",
     "fluent-langneg",
diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs
index 7a53c08737f..ade774616c7 100644
--- a/src/tools/tidy/src/rustdoc_json.rs
+++ b/src/tools/tidy/src/rustdoc_json.rs
@@ -17,11 +17,13 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, diag_ctx: DiagCtx) {
     };
 
     // First we check that `src/rustdoc-json-types` was modified.
-    if !crate::files_modified(ci_info, |p| p == RUSTDOC_JSON_TYPES) {
+    if !crate::files_modified(ci_info, |p| p.starts_with(RUSTDOC_JSON_TYPES)) {
         // `rustdoc-json-types` was not modified so nothing more to check here.
-        check.verbose_msg("`rustdoc-json-types` was not modified.");
         return;
     }
+
+    check.message("`rustdoc-json-types` modified, checking format version");
+
     // Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated.
     match crate::git_diff(base_commit, src_path.join("rustdoc-json-types")) {
         Some(output) => {
diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs
index b5c116cdfef..ebea9fe40f5 100644
--- a/tests/assembly-llvm/targets/targets-elf.rs
+++ b/tests/assembly-llvm/targets/targets-elf.rs
@@ -658,6 +658,9 @@
 //@ revisions: x86_64_unknown_managarm_mlibc
 //@ [x86_64_unknown_managarm_mlibc] compile-flags: --target x86_64-unknown-managarm-mlibc
 //@ [x86_64_unknown_managarm_mlibc] needs-llvm-components: x86
+//@ revisions: x86_64_unknown_motor
+//@ [x86_64_unknown_motor] compile-flags: --target x86_64-unknown-motor
+//@ [x86_64_unknown_motor] needs-llvm-components: x86
 //@ revisions: x86_64_unknown_netbsd
 //@ [x86_64_unknown_netbsd] compile-flags: --target x86_64-unknown-netbsd
 //@ [x86_64_unknown_netbsd] needs-llvm-components: x86
diff --git a/tests/codegen-llvm/asm/powerpc-clobbers.rs b/tests/codegen-llvm/asm/powerpc-clobbers.rs
index f7fc7eea5d5..10d7ae4dba4 100644
--- a/tests/codegen-llvm/asm/powerpc-clobbers.rs
+++ b/tests/codegen-llvm/asm/powerpc-clobbers.rs
@@ -58,10 +58,10 @@ pub unsafe fn v0_clobber() {
 
 // Output format depends on the availability of altivec.
 // CHECK-LABEL: @clobber_abi
-// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
 #[no_mangle]
 pub unsafe fn clobber_abi() {
     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
diff --git a/tests/codegen-llvm/asm/readonly-not-pure.rs b/tests/codegen-llvm/asm/readonly-not-pure.rs
new file mode 100644
index 00000000000..a3c0e276c7f
--- /dev/null
+++ b/tests/codegen-llvm/asm/readonly-not-pure.rs
@@ -0,0 +1,48 @@
+//@ add-core-stubs
+//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "rlib"]
+#![feature(no_core)]
+#![no_core]
+
+// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed
+// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes,
+// but it may have side-effects.
+
+extern crate minicore;
+use minicore::*;
+
+pub static mut VAR: i32 = 0;
+
+// CHECK-LABEL: @no_options
+// CHECK: call i32 asm
+#[no_mangle]
+pub unsafe fn no_options() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored);
+    VAR
+}
+
+// CHECK-LABEL: @readonly_pure
+// CHECK-NOT: call i32 asm
+#[no_mangle]
+pub unsafe fn readonly_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly));
+    VAR
+}
+
+// CHECK-LABEL: @readonly_not_pure
+// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]]
+#[no_mangle]
+pub unsafe fn readonly_not_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(readonly));
+    VAR
+}
+
+// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) }
diff --git a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs
index 4bec579831d..255f20e6ff6 100644
--- a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs
+++ b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs
@@ -7,7 +7,5 @@ use std::intrinsics::sqrtf32;
 // CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}}
 
 fn main() {
-    unsafe {
-        sqrtf32(0.0f32);
-    }
+    sqrtf32(0.0f32);
 }
diff --git a/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs
new file mode 100644
index 00000000000..b97729fa146
--- /dev/null
+++ b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Copt-level=3
+//@ needs-deterministic-layouts
+
+// Currently Vec<T> and &[T] have layouts that start with (pointer, len)
+// which makes the conversion branchless.
+// A nice-to-have property, not guaranteed.
+#![crate_type = "cdylib"]
+
+// CHECK-LABEL: @branchless_cow_slices
+#[no_mangle]
+pub fn branchless_cow_slices<'a>(cow: &'a std::borrow::Cow<'a, [u8]>) -> &'a [u8] {
+    // CHECK-NOT: br
+    // CHECK-NOT: select
+    // CHECK-NOT: icmp
+    // CHECK: ret { ptr, {{i32|i64}} }
+    &*cow
+}
diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml b/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml
new file mode 100644
index 00000000000..3c61c12a84e
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml
@@ -0,0 +1,12 @@
+cargo-features = ["profile-rustflags"]
+
+[package]
+name = "panic_scenarios"
+version = "0.1.0"
+edition = "2024"
+
+[lib]
+path = "lib.rs"
+
+[profile.release]
+rustflags = ["-Zmerge-functions=disabled", "-Zcodegen-source-order", "--emit=llvm-ir"]
diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs b/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs
new file mode 100644
index 00000000000..1e20da93ba8
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs
@@ -0,0 +1,65 @@
+#![no_std]
+
+#[unsafe(no_mangle)]
+pub fn panic_noarg() {
+    // CHECK-LABEL: @panic_noarg(
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: tail call void @llvm.trap()
+    panic!();
+}
+
+#[unsafe(no_mangle)]
+pub fn panic_str() {
+    // CHECK-LABEL: @panic_str(
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: tail call void @llvm.trap()
+    panic!("ouch");
+}
+
+#[unsafe(no_mangle)]
+pub fn bounds_check(x: &[u8], idx: usize) -> &u8 {
+    // CHECK-LABEL: @bounds_check(
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: icmp ult
+    // CHECK-NEXT: br i1
+    // CHECK: bb1:
+    // CHECK-NEXT: getelementptr inbounds nuw i8
+    // CHECK-NEXT: ret ptr
+    // CHECK: panic:
+    // CHECK-NEXT: tail call void @llvm.trap()
+    &x[idx]
+}
+
+#[unsafe(no_mangle)]
+pub fn str_bounds_check(x: &str, idx: usize) -> &str {
+    // CHECK-LABEL: @str_bounds_check(
+    // CHECK-NOT: call
+    // CHECK: tail call void @llvm.trap()
+    // CHECK-NOT: call
+    &x[idx..]
+}
+
+#[unsafe(no_mangle)]
+pub fn unsigned_integer_div(x: u16, y: u16) -> u16 {
+    // CHECK-LABEL: @unsigned_integer_div(
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: icmp eq i16
+    // CHECK-NEXT: br i1
+    // CHECK: bb1:
+    // CHECK-NEXT: udiv i16
+    // CHECK-NEXT: ret i16
+    // CHECK: panic:
+    // CHECK-NEXT: tail call void @llvm.trap()
+    x / y
+}
+
+#[unsafe(no_mangle)]
+pub fn refcell_already_borrowed() {
+    // CHECK-LABEL: @refcell_already_borrowed(
+    // CHECK-NOT: call
+    // CHECK: tail call void @llvm.trap()
+    // CHECK-NOT: call
+    let r = core::cell::RefCell::new(0u8);
+    let _guard = r.borrow_mut();
+    r.borrow_mut();
+}
diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs b/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs
new file mode 100644
index 00000000000..d7a7a8bfd8c
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs
@@ -0,0 +1,46 @@
+// This is a codegen test which checks that when code is compiled with panic=immediate-abort,
+// we get a `tail call void @llvm.trap()` in user code instead of a call into the standard
+// library's panic formatting code (such as panic_fmt) or one of the numerous panic outlining shims
+// (such as slice_index_fail).
+
+#![deny(warnings)]
+
+use run_make_support::{cargo, llvm_filecheck, path, rfs, target};
+
+fn main() {
+    let target_dir = path("target");
+
+    cargo()
+        .args(&[
+            "build",
+            "--release",
+            "--lib",
+            "--manifest-path",
+            "Cargo.toml",
+            "-Zbuild-std=core",
+            "--target",
+            &target(),
+        ])
+        .env("RUSTFLAGS", "-Zunstable-options -Cpanic=immediate-abort")
+        .env("CARGO_TARGET_DIR", &target_dir)
+        .env("RUSTC_BOOTSTRAP", "1")
+        // Visual Studio 2022 requires that the LIB env var be set so it can
+        // find the Windows SDK.
+        .env("LIB", std::env::var("LIB").unwrap_or_default())
+        .run();
+
+    let out_dir = target_dir.join(target()).join("release").join("deps");
+    let ir_file = rfs::read_dir(out_dir)
+        .find_map(|e| {
+            let path = e.unwrap().path();
+            let file_name = path.file_name().unwrap().to_str().unwrap();
+            if file_name.starts_with("panic_scenarios") && file_name.ends_with(".ll") {
+                Some(path)
+            } else {
+                None
+            }
+        })
+        .unwrap();
+
+    llvm_filecheck().patterns("lib.rs").input_file(ir_file).run();
+}
diff --git a/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml b/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml
new file mode 100644
index 00000000000..1e278d557c0
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml
@@ -0,0 +1,4 @@
+[package]
+name = "hello"
+version = "0.1.0"
+edition = "2024"
diff --git a/tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs b/tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs b/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs
new file mode 100644
index 00000000000..3eeef38c962
--- /dev/null
+++ b/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs
@@ -0,0 +1,39 @@
+// This test ensures we are able to compile and link a simple binary with panic=immediate-abort.
+// The test panic-immediate-abort-codegen checks that panic strategy produces the desired codegen,
+// but is based on compiling a library crate (which is the norm for codegen tests because it is
+// cleaner and more portable). So this test ensures that we didn't mix up a cfg or a compiler
+// implementation detail in a way that makes panic=immediate-abort encounter errors at link time.
+
+// Ideally this test would be run for most targets, but unfortunately:
+// This test is currently written using `fn main() {}` which requires std.
+// And since the default linker is only a linker for the host, we can't handle cross-compilation.
+// Both of these shortcomings could be addressed at the cost of making the test more complicated.
+//@ needs-target-std
+//@ ignore-cross-compile
+
+#![deny(warnings)]
+
+use run_make_support::{cargo, path, target};
+
+fn main() {
+    let target_dir = path("target");
+
+    cargo()
+        .current_dir("hello")
+        .args(&[
+            "build",
+            "--release",
+            "--manifest-path",
+            "Cargo.toml",
+            "-Zbuild-std",
+            "--target",
+            &target(),
+        ])
+        .env("RUSTFLAGS", "-Zunstable-options -Cpanic=immediate-abort")
+        .env("CARGO_TARGET_DIR", &target_dir)
+        .env("RUSTC_BOOTSTRAP", "1")
+        // Visual Studio 2022 requires that the LIB env var be set so it can
+        // find the Windows SDK.
+        .env("LIB", std::env::var("LIB").unwrap_or_default())
+        .run();
+}
diff --git a/tests/run-make/crate-loading/multiple-dep-versions-3.rs b/tests/run-make/crate-loading/dep-2-reexport.rs
index 07444511472..07444511472 100644
--- a/tests/run-make/crate-loading/multiple-dep-versions-3.rs
+++ b/tests/run-make/crate-loading/dep-2-reexport.rs
diff --git a/tests/run-make/crate-loading/multiple-dep-versions-1.rs b/tests/run-make/crate-loading/dependency-1.rs
index bfeabccf5c1..bfeabccf5c1 100644
--- a/tests/run-make/crate-loading/multiple-dep-versions-1.rs
+++ b/tests/run-make/crate-loading/dependency-1.rs
diff --git a/tests/run-make/crate-loading/multiple-dep-versions-2.rs b/tests/run-make/crate-loading/dependency-2.rs
index 682d1ff64b8..682d1ff64b8 100644
--- a/tests/run-make/crate-loading/multiple-dep-versions-2.rs
+++ b/tests/run-make/crate-loading/dependency-2.rs
diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs
index 6ad456e3e3e..8f257786123 100644
--- a/tests/run-make/crate-loading/rmake.rs
+++ b/tests/run-make/crate-loading/rmake.rs
@@ -6,12 +6,9 @@
 use run_make_support::{diff, rust_lib_name, rustc};
 
 fn main() {
-    rustc().input("multiple-dep-versions-1.rs").run();
-    rustc().input("multiple-dep-versions-2.rs").extra_filename("2").metadata("2").run();
-    rustc()
-        .input("multiple-dep-versions-3.rs")
-        .extern_("dependency", rust_lib_name("dependency2"))
-        .run();
+    rustc().input("dependency-1.rs").run();
+    rustc().input("dependency-2.rs").extra_filename("2").metadata("2").run();
+    rustc().input("dep-2-reexport.rs").extern_("dependency", rust_lib_name("dependency2")).run();
 
     let out = rustc()
         .input("multiple-dep-versions.rs")
diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs
index 1b30c538b5e..e9d09e359c6 100644
--- a/tests/run-make/musl-default-linking/rmake.rs
+++ b/tests/run-make/musl-default-linking/rmake.rs
@@ -4,7 +4,7 @@ use run_make_support::{rustc, serde_json};
 // Per https://github.com/rust-lang/compiler-team/issues/422,
 // we should be trying to move these targets to dynamically link
 // musl libc by default.
-//@ needs-llvm-components: aarch64 arm mips powerpc x86
+//@ needs-llvm-components: aarch64 arm powerpc x86
 static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[
     "aarch64-unknown-linux-musl",
     "arm-unknown-linux-musleabi",
@@ -14,7 +14,6 @@ static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[
     "armv7-unknown-linux-musleabihf",
     "i586-unknown-linux-musl",
     "i686-unknown-linux-musl",
-    "mips64el-unknown-linux-muslabi64",
     "powerpc64le-unknown-linux-musl",
     "x86_64-unknown-linux-musl",
 ];
diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs
new file mode 100644
index 00000000000..0b1e1948d5f
--- /dev/null
+++ b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs
@@ -0,0 +1,28 @@
+// Running --merge=finalize without an input crate root should not trigger ICE.
+// Issue: https://github.com/rust-lang/rust/issues/146646
+
+//@ needs-target-std
+
+use run_make_support::{path, rustdoc};
+
+fn main() {
+    let out_dir = path("out");
+    let merged_dir = path("merged");
+    let parts_out_dir = path("parts");
+    rustdoc()
+        .input("sierra.rs")
+        .out_dir(&out_dir)
+        .arg("-Zunstable-options")
+        .arg(format!("--parts-out-dir={}", parts_out_dir.display()))
+        .arg("--merge=none")
+        .run();
+    assert!(parts_out_dir.join("crate-info").exists());
+
+    let output = rustdoc()
+        .arg("-Zunstable-options")
+        .out_dir(&out_dir)
+        .arg(format!("--include-parts-dir={}", parts_out_dir.display()))
+        .arg("--merge=finalize")
+        .run();
+    output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug.");
+}
diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs b/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs
new file mode 100644
index 00000000000..f8fc48341ed
--- /dev/null
+++ b/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs
@@ -0,0 +1 @@
+pub struct Sierra;
diff --git a/tests/rustdoc/reexport/private-mod-override-reexport.rs b/tests/rustdoc/reexport/private-mod-override-reexport.rs
new file mode 100644
index 00000000000..849acc5fdae
--- /dev/null
+++ b/tests/rustdoc/reexport/private-mod-override-reexport.rs
@@ -0,0 +1,13 @@
+// https://github.com/rust-lang/rust/issues/60926
+#![crate_name = "foo"]
+
+mod m1 {
+    pub mod m2 {
+        pub struct Foo;
+    }
+}
+
+pub use m1::*;
+use crate::m1::m2;
+
+//@ count foo/index.html '//a[@class="mod"]' 0
diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr
index 124013f89af..82faba8d167 100644
--- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr
@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
 LL |         asm!("", out("fp") _);
    |                  ^^^^^^^^^^^
 
-error: invalid register `lr`: the link register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:48:18
-   |
-LL |         asm!("", out("lr") _);
-   |                  ^^^^^^^^^^^
-
-error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:50:18
-   |
-LL |         asm!("", out("ctr") _);
-   |                  ^^^^^^^^^^^^
-
 error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:52:18
+  --> $DIR/bad-reg.rs:48:18
    |
 LL |         asm!("", out("vrsave") _);
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:100:18
+  --> $DIR/bad-reg.rs:96:18
    |
 LL |         asm!("", in("cr") x);
    |                  ^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:103:18
+  --> $DIR/bad-reg.rs:99:18
    |
 LL |         asm!("", out("cr") x);
    |                  ^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:106:26
+  --> $DIR/bad-reg.rs:102:26
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                          ^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:109:26
+  --> $DIR/bad-reg.rs:105:26
    |
 LL |         asm!("/* {} */", out(cr) _);
    |                          ^^^^^^^^^
 
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:109:18
+   |
+LL |         asm!("", in("ctr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:112:18
+   |
+LL |         asm!("", out("ctr") x);
+   |                  ^^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:115:26
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                          ^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:118:26
+   |
+LL |         asm!("/* {} */", out(ctr) _);
+   |                          ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:122:18
+   |
+LL |         asm!("", in("lr") x);
+   |                  ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:125:18
+   |
+LL |         asm!("", out("lr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:128:26
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                          ^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:131:26
+   |
+LL |         asm!("/* {} */", out(lr) _);
+   |                          ^^^^^^^^^
+
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:113:18
+  --> $DIR/bad-reg.rs:135:18
    |
 LL |         asm!("", in("xer") x);
    |                  ^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:116:18
+  --> $DIR/bad-reg.rs:138:18
    |
 LL |         asm!("", out("xer") x);
    |                  ^^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:119:26
+  --> $DIR/bad-reg.rs:141:26
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                          ^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:122:26
+  --> $DIR/bad-reg.rs:144:26
    |
 LL |         asm!("/* {} */", out(xer) _);
    |                          ^^^^^^^^^^
 
 error: register `cr0` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:126:31
+  --> $DIR/bad-reg.rs:148:31
    |
 LL |         asm!("", out("cr") _, out("cr0") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr0`
@@ -103,7 +139,7 @@ LL |         asm!("", out("cr") _, out("cr0") _);
    |                  register `cr`
 
 error: register `cr1` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:128:31
+  --> $DIR/bad-reg.rs:150:31
    |
 LL |         asm!("", out("cr") _, out("cr1") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr1`
@@ -111,7 +147,7 @@ LL |         asm!("", out("cr") _, out("cr1") _);
    |                  register `cr`
 
 error: register `cr2` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:130:31
+  --> $DIR/bad-reg.rs:152:31
    |
 LL |         asm!("", out("cr") _, out("cr2") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr2`
@@ -119,7 +155,7 @@ LL |         asm!("", out("cr") _, out("cr2") _);
    |                  register `cr`
 
 error: register `cr3` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:132:31
+  --> $DIR/bad-reg.rs:154:31
    |
 LL |         asm!("", out("cr") _, out("cr3") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr3`
@@ -127,7 +163,7 @@ LL |         asm!("", out("cr") _, out("cr3") _);
    |                  register `cr`
 
 error: register `cr4` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:134:31
+  --> $DIR/bad-reg.rs:156:31
    |
 LL |         asm!("", out("cr") _, out("cr4") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr4`
@@ -135,7 +171,7 @@ LL |         asm!("", out("cr") _, out("cr4") _);
    |                  register `cr`
 
 error: register `cr5` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:136:31
+  --> $DIR/bad-reg.rs:158:31
    |
 LL |         asm!("", out("cr") _, out("cr5") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr5`
@@ -143,7 +179,7 @@ LL |         asm!("", out("cr") _, out("cr5") _);
    |                  register `cr`
 
 error: register `cr6` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:138:31
+  --> $DIR/bad-reg.rs:160:31
    |
 LL |         asm!("", out("cr") _, out("cr6") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr6`
@@ -151,7 +187,7 @@ LL |         asm!("", out("cr") _, out("cr6") _);
    |                  register `cr`
 
 error: register `cr7` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:140:31
+  --> $DIR/bad-reg.rs:162:31
    |
 LL |         asm!("", out("cr") _, out("cr7") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr7`
@@ -165,7 +201,7 @@ LL |         asm!("", out("r13") _);
    |                  ^^^^^^^^^^^^
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:67:27
+  --> $DIR/bad-reg.rs:63:27
    |
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
@@ -173,7 +209,7 @@ LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:70:28
+  --> $DIR/bad-reg.rs:66:28
    |
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
@@ -181,7 +217,7 @@ LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:78:35
+  --> $DIR/bad-reg.rs:74:35
    |
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
@@ -189,7 +225,7 @@ LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:100:27
+  --> $DIR/bad-reg.rs:96:27
    |
 LL |         asm!("", in("cr") x);
    |                           ^
@@ -197,7 +233,7 @@ LL |         asm!("", in("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:103:28
+  --> $DIR/bad-reg.rs:99:28
    |
 LL |         asm!("", out("cr") x);
    |                            ^
@@ -205,7 +241,7 @@ LL |         asm!("", out("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:106:33
+  --> $DIR/bad-reg.rs:102:33
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                                 ^
@@ -213,7 +249,55 @@ LL |         asm!("/* {} */", in(cr) x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:113:28
+  --> $DIR/bad-reg.rs:109:28
+   |
+LL |         asm!("", in("ctr") x);
+   |                            ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:112:29
+   |
+LL |         asm!("", out("ctr") x);
+   |                             ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:115:34
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                                  ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:122:27
+   |
+LL |         asm!("", in("lr") x);
+   |                           ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:125:28
+   |
+LL |         asm!("", out("lr") x);
+   |                            ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:128:33
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                                 ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:135:28
    |
 LL |         asm!("", in("xer") x);
    |                            ^
@@ -221,7 +305,7 @@ LL |         asm!("", in("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:116:29
+  --> $DIR/bad-reg.rs:138:29
    |
 LL |         asm!("", out("xer") x);
    |                             ^
@@ -229,12 +313,12 @@ LL |         asm!("", out("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:119:34
+  --> $DIR/bad-reg.rs:141:34
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                                  ^
    |
    = note: register class `xer` supports these types: 
 
-error: aborting due to 34 previous errors
+error: aborting due to 46 previous errors
 
diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr
index b11c946f80d..fac70ea77cb 100644
--- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr
@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
 LL |         asm!("", out("fp") _);
    |                  ^^^^^^^^^^^
 
-error: invalid register `lr`: the link register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:48:18
-   |
-LL |         asm!("", out("lr") _);
-   |                  ^^^^^^^^^^^
-
-error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:50:18
-   |
-LL |         asm!("", out("ctr") _);
-   |                  ^^^^^^^^^^^^
-
 error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:52:18
+  --> $DIR/bad-reg.rs:48:18
    |
 LL |         asm!("", out("vrsave") _);
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:100:18
+  --> $DIR/bad-reg.rs:96:18
    |
 LL |         asm!("", in("cr") x);
    |                  ^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:103:18
+  --> $DIR/bad-reg.rs:99:18
    |
 LL |         asm!("", out("cr") x);
    |                  ^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:106:26
+  --> $DIR/bad-reg.rs:102:26
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                          ^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:109:26
+  --> $DIR/bad-reg.rs:105:26
    |
 LL |         asm!("/* {} */", out(cr) _);
    |                          ^^^^^^^^^
 
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:109:18
+   |
+LL |         asm!("", in("ctr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:112:18
+   |
+LL |         asm!("", out("ctr") x);
+   |                  ^^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:115:26
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                          ^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:118:26
+   |
+LL |         asm!("/* {} */", out(ctr) _);
+   |                          ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:122:18
+   |
+LL |         asm!("", in("lr") x);
+   |                  ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:125:18
+   |
+LL |         asm!("", out("lr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:128:26
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                          ^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:131:26
+   |
+LL |         asm!("/* {} */", out(lr) _);
+   |                          ^^^^^^^^^
+
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:113:18
+  --> $DIR/bad-reg.rs:135:18
    |
 LL |         asm!("", in("xer") x);
    |                  ^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:116:18
+  --> $DIR/bad-reg.rs:138:18
    |
 LL |         asm!("", out("xer") x);
    |                  ^^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:119:26
+  --> $DIR/bad-reg.rs:141:26
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                          ^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:122:26
+  --> $DIR/bad-reg.rs:144:26
    |
 LL |         asm!("/* {} */", out(xer) _);
    |                          ^^^^^^^^^^
 
 error: register `cr0` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:126:31
+  --> $DIR/bad-reg.rs:148:31
    |
 LL |         asm!("", out("cr") _, out("cr0") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr0`
@@ -103,7 +139,7 @@ LL |         asm!("", out("cr") _, out("cr0") _);
    |                  register `cr`
 
 error: register `cr1` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:128:31
+  --> $DIR/bad-reg.rs:150:31
    |
 LL |         asm!("", out("cr") _, out("cr1") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr1`
@@ -111,7 +147,7 @@ LL |         asm!("", out("cr") _, out("cr1") _);
    |                  register `cr`
 
 error: register `cr2` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:130:31
+  --> $DIR/bad-reg.rs:152:31
    |
 LL |         asm!("", out("cr") _, out("cr2") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr2`
@@ -119,7 +155,7 @@ LL |         asm!("", out("cr") _, out("cr2") _);
    |                  register `cr`
 
 error: register `cr3` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:132:31
+  --> $DIR/bad-reg.rs:154:31
    |
 LL |         asm!("", out("cr") _, out("cr3") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr3`
@@ -127,7 +163,7 @@ LL |         asm!("", out("cr") _, out("cr3") _);
    |                  register `cr`
 
 error: register `cr4` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:134:31
+  --> $DIR/bad-reg.rs:156:31
    |
 LL |         asm!("", out("cr") _, out("cr4") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr4`
@@ -135,7 +171,7 @@ LL |         asm!("", out("cr") _, out("cr4") _);
    |                  register `cr`
 
 error: register `cr5` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:136:31
+  --> $DIR/bad-reg.rs:158:31
    |
 LL |         asm!("", out("cr") _, out("cr5") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr5`
@@ -143,7 +179,7 @@ LL |         asm!("", out("cr") _, out("cr5") _);
    |                  register `cr`
 
 error: register `cr6` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:138:31
+  --> $DIR/bad-reg.rs:160:31
    |
 LL |         asm!("", out("cr") _, out("cr6") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr6`
@@ -151,7 +187,7 @@ LL |         asm!("", out("cr") _, out("cr6") _);
    |                  register `cr`
 
 error: register `cr7` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:140:31
+  --> $DIR/bad-reg.rs:162:31
    |
 LL |         asm!("", out("cr") _, out("cr7") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr7`
@@ -165,67 +201,67 @@ LL |         asm!("", out("r13") _);
    |                  ^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:57:18
+  --> $DIR/bad-reg.rs:53:18
    |
 LL |         asm!("", in("v0") v32x4); // requires altivec
    |                  ^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:59:18
+  --> $DIR/bad-reg.rs:55:18
    |
 LL |         asm!("", out("v0") v32x4); // requires altivec
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:61:18
+  --> $DIR/bad-reg.rs:57:18
    |
 LL |         asm!("", in("v0") v64x2); // requires vsx
    |                  ^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:64:18
+  --> $DIR/bad-reg.rs:60:18
    |
 LL |         asm!("", out("v0") v64x2); // requires vsx
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:67:18
+  --> $DIR/bad-reg.rs:63:18
    |
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                  ^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:70:18
+  --> $DIR/bad-reg.rs:66:18
    |
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                  ^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:73:26
+  --> $DIR/bad-reg.rs:69:26
    |
 LL |         asm!("/* {} */", in(vreg) v32x4); // requires altivec
    |                          ^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:75:26
+  --> $DIR/bad-reg.rs:71:26
    |
 LL |         asm!("/* {} */", in(vreg) v64x2); // requires vsx
    |                          ^^^^^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:78:26
+  --> $DIR/bad-reg.rs:74:26
    |
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                          ^^^^^^^^^^
 
 error: register class `vreg` requires at least one of the following target features: altivec, vsx
-  --> $DIR/bad-reg.rs:81:26
+  --> $DIR/bad-reg.rs:77:26
    |
 LL |         asm!("/* {} */", out(vreg) _); // requires altivec
    |                          ^^^^^^^^^^^
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:100:27
+  --> $DIR/bad-reg.rs:96:27
    |
 LL |         asm!("", in("cr") x);
    |                           ^
@@ -233,7 +269,7 @@ LL |         asm!("", in("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:103:28
+  --> $DIR/bad-reg.rs:99:28
    |
 LL |         asm!("", out("cr") x);
    |                            ^
@@ -241,7 +277,7 @@ LL |         asm!("", out("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:106:33
+  --> $DIR/bad-reg.rs:102:33
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                                 ^
@@ -249,7 +285,55 @@ LL |         asm!("/* {} */", in(cr) x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:113:28
+  --> $DIR/bad-reg.rs:109:28
+   |
+LL |         asm!("", in("ctr") x);
+   |                            ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:112:29
+   |
+LL |         asm!("", out("ctr") x);
+   |                             ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:115:34
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                                  ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:122:27
+   |
+LL |         asm!("", in("lr") x);
+   |                           ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:125:28
+   |
+LL |         asm!("", out("lr") x);
+   |                            ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:128:33
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                                 ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:135:28
    |
 LL |         asm!("", in("xer") x);
    |                            ^
@@ -257,7 +341,7 @@ LL |         asm!("", in("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:116:29
+  --> $DIR/bad-reg.rs:138:29
    |
 LL |         asm!("", out("xer") x);
    |                             ^
@@ -265,12 +349,12 @@ LL |         asm!("", out("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:119:34
+  --> $DIR/bad-reg.rs:141:34
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                                  ^
    |
    = note: register class `xer` supports these types: 
 
-error: aborting due to 41 previous errors
+error: aborting due to 53 previous errors
 
diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
index a93b2b018df..42a59448f42 100644
--- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
 LL |         asm!("", out("fp") _);
    |                  ^^^^^^^^^^^
 
-error: invalid register `lr`: the link register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:48:18
-   |
-LL |         asm!("", out("lr") _);
-   |                  ^^^^^^^^^^^
-
-error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:50:18
-   |
-LL |         asm!("", out("ctr") _);
-   |                  ^^^^^^^^^^^^
-
 error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:52:18
+  --> $DIR/bad-reg.rs:48:18
    |
 LL |         asm!("", out("vrsave") _);
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:100:18
+  --> $DIR/bad-reg.rs:96:18
    |
 LL |         asm!("", in("cr") x);
    |                  ^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:103:18
+  --> $DIR/bad-reg.rs:99:18
    |
 LL |         asm!("", out("cr") x);
    |                  ^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:106:26
+  --> $DIR/bad-reg.rs:102:26
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                          ^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:109:26
+  --> $DIR/bad-reg.rs:105:26
    |
 LL |         asm!("/* {} */", out(cr) _);
    |                          ^^^^^^^^^
 
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:109:18
+   |
+LL |         asm!("", in("ctr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:112:18
+   |
+LL |         asm!("", out("ctr") x);
+   |                  ^^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:115:26
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                          ^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:118:26
+   |
+LL |         asm!("/* {} */", out(ctr) _);
+   |                          ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:122:18
+   |
+LL |         asm!("", in("lr") x);
+   |                  ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:125:18
+   |
+LL |         asm!("", out("lr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:128:26
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                          ^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:131:26
+   |
+LL |         asm!("/* {} */", out(lr) _);
+   |                          ^^^^^^^^^
+
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:113:18
+  --> $DIR/bad-reg.rs:135:18
    |
 LL |         asm!("", in("xer") x);
    |                  ^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:116:18
+  --> $DIR/bad-reg.rs:138:18
    |
 LL |         asm!("", out("xer") x);
    |                  ^^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:119:26
+  --> $DIR/bad-reg.rs:141:26
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                          ^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:122:26
+  --> $DIR/bad-reg.rs:144:26
    |
 LL |         asm!("/* {} */", out(xer) _);
    |                          ^^^^^^^^^^
 
 error: register `cr0` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:126:31
+  --> $DIR/bad-reg.rs:148:31
    |
 LL |         asm!("", out("cr") _, out("cr0") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr0`
@@ -103,7 +139,7 @@ LL |         asm!("", out("cr") _, out("cr0") _);
    |                  register `cr`
 
 error: register `cr1` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:128:31
+  --> $DIR/bad-reg.rs:150:31
    |
 LL |         asm!("", out("cr") _, out("cr1") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr1`
@@ -111,7 +147,7 @@ LL |         asm!("", out("cr") _, out("cr1") _);
    |                  register `cr`
 
 error: register `cr2` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:130:31
+  --> $DIR/bad-reg.rs:152:31
    |
 LL |         asm!("", out("cr") _, out("cr2") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr2`
@@ -119,7 +155,7 @@ LL |         asm!("", out("cr") _, out("cr2") _);
    |                  register `cr`
 
 error: register `cr3` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:132:31
+  --> $DIR/bad-reg.rs:154:31
    |
 LL |         asm!("", out("cr") _, out("cr3") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr3`
@@ -127,7 +163,7 @@ LL |         asm!("", out("cr") _, out("cr3") _);
    |                  register `cr`
 
 error: register `cr4` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:134:31
+  --> $DIR/bad-reg.rs:156:31
    |
 LL |         asm!("", out("cr") _, out("cr4") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr4`
@@ -135,7 +171,7 @@ LL |         asm!("", out("cr") _, out("cr4") _);
    |                  register `cr`
 
 error: register `cr5` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:136:31
+  --> $DIR/bad-reg.rs:158:31
    |
 LL |         asm!("", out("cr") _, out("cr5") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr5`
@@ -143,7 +179,7 @@ LL |         asm!("", out("cr") _, out("cr5") _);
    |                  register `cr`
 
 error: register `cr6` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:138:31
+  --> $DIR/bad-reg.rs:160:31
    |
 LL |         asm!("", out("cr") _, out("cr6") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr6`
@@ -151,7 +187,7 @@ LL |         asm!("", out("cr") _, out("cr6") _);
    |                  register `cr`
 
 error: register `cr7` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:140:31
+  --> $DIR/bad-reg.rs:162:31
    |
 LL |         asm!("", out("cr") _, out("cr7") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr7`
@@ -165,7 +201,7 @@ LL |         asm!("", out("r13") _);
    |                  ^^^^^^^^^^^^
 
 error: `vsx` target feature is not enabled
-  --> $DIR/bad-reg.rs:61:27
+  --> $DIR/bad-reg.rs:57:27
    |
 LL |         asm!("", in("v0") v64x2); // requires vsx
    |                           ^^^^^
@@ -173,7 +209,7 @@ LL |         asm!("", in("v0") v64x2); // requires vsx
    = note: this is required to use type `i64x2` with register class `vreg`
 
 error: `vsx` target feature is not enabled
-  --> $DIR/bad-reg.rs:64:28
+  --> $DIR/bad-reg.rs:60:28
    |
 LL |         asm!("", out("v0") v64x2); // requires vsx
    |                            ^^^^^
@@ -181,7 +217,7 @@ LL |         asm!("", out("v0") v64x2); // requires vsx
    = note: this is required to use type `i64x2` with register class `vreg`
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:67:27
+  --> $DIR/bad-reg.rs:63:27
    |
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
@@ -189,7 +225,7 @@ LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:70:28
+  --> $DIR/bad-reg.rs:66:28
    |
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
@@ -197,7 +233,7 @@ LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: `vsx` target feature is not enabled
-  --> $DIR/bad-reg.rs:75:35
+  --> $DIR/bad-reg.rs:71:35
    |
 LL |         asm!("/* {} */", in(vreg) v64x2); // requires vsx
    |                                   ^^^^^
@@ -205,7 +241,7 @@ LL |         asm!("/* {} */", in(vreg) v64x2); // requires vsx
    = note: this is required to use type `i64x2` with register class `vreg`
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:78:35
+  --> $DIR/bad-reg.rs:74:35
    |
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
@@ -213,7 +249,7 @@ LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:100:27
+  --> $DIR/bad-reg.rs:96:27
    |
 LL |         asm!("", in("cr") x);
    |                           ^
@@ -221,7 +257,7 @@ LL |         asm!("", in("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:103:28
+  --> $DIR/bad-reg.rs:99:28
    |
 LL |         asm!("", out("cr") x);
    |                            ^
@@ -229,7 +265,7 @@ LL |         asm!("", out("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:106:33
+  --> $DIR/bad-reg.rs:102:33
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                                 ^
@@ -237,7 +273,55 @@ LL |         asm!("/* {} */", in(cr) x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:113:28
+  --> $DIR/bad-reg.rs:109:28
+   |
+LL |         asm!("", in("ctr") x);
+   |                            ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:112:29
+   |
+LL |         asm!("", out("ctr") x);
+   |                             ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:115:34
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                                  ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:122:27
+   |
+LL |         asm!("", in("lr") x);
+   |                           ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:125:28
+   |
+LL |         asm!("", out("lr") x);
+   |                            ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:128:33
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                                 ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:135:28
    |
 LL |         asm!("", in("xer") x);
    |                            ^
@@ -245,7 +329,7 @@ LL |         asm!("", in("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:116:29
+  --> $DIR/bad-reg.rs:138:29
    |
 LL |         asm!("", out("xer") x);
    |                             ^
@@ -253,12 +337,12 @@ LL |         asm!("", out("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:119:34
+  --> $DIR/bad-reg.rs:141:34
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                                  ^
    |
    = note: register class `xer` supports these types: 
 
-error: aborting due to 37 previous errors
+error: aborting due to 49 previous errors
 
diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
index 124013f89af..82faba8d167 100644
--- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
@@ -28,74 +28,110 @@ error: invalid register `fp`: the frame pointer cannot be used as an operand for
 LL |         asm!("", out("fp") _);
    |                  ^^^^^^^^^^^
 
-error: invalid register `lr`: the link register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:48:18
-   |
-LL |         asm!("", out("lr") _);
-   |                  ^^^^^^^^^^^
-
-error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:50:18
-   |
-LL |         asm!("", out("ctr") _);
-   |                  ^^^^^^^^^^^^
-
 error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:52:18
+  --> $DIR/bad-reg.rs:48:18
    |
 LL |         asm!("", out("vrsave") _);
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:100:18
+  --> $DIR/bad-reg.rs:96:18
    |
 LL |         asm!("", in("cr") x);
    |                  ^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:103:18
+  --> $DIR/bad-reg.rs:99:18
    |
 LL |         asm!("", out("cr") x);
    |                  ^^^^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:106:26
+  --> $DIR/bad-reg.rs:102:26
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                          ^^^^^^^^
 
 error: register class `cr` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:109:26
+  --> $DIR/bad-reg.rs:105:26
    |
 LL |         asm!("/* {} */", out(cr) _);
    |                          ^^^^^^^^^
 
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:109:18
+   |
+LL |         asm!("", in("ctr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:112:18
+   |
+LL |         asm!("", out("ctr") x);
+   |                  ^^^^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:115:26
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                          ^^^^^^^^^
+
+error: register class `ctr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:118:26
+   |
+LL |         asm!("/* {} */", out(ctr) _);
+   |                          ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:122:18
+   |
+LL |         asm!("", in("lr") x);
+   |                  ^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:125:18
+   |
+LL |         asm!("", out("lr") x);
+   |                  ^^^^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:128:26
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                          ^^^^^^^^
+
+error: register class `lr` can only be used as a clobber, not as an input or output
+  --> $DIR/bad-reg.rs:131:26
+   |
+LL |         asm!("/* {} */", out(lr) _);
+   |                          ^^^^^^^^^
+
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:113:18
+  --> $DIR/bad-reg.rs:135:18
    |
 LL |         asm!("", in("xer") x);
    |                  ^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:116:18
+  --> $DIR/bad-reg.rs:138:18
    |
 LL |         asm!("", out("xer") x);
    |                  ^^^^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:119:26
+  --> $DIR/bad-reg.rs:141:26
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                          ^^^^^^^^^
 
 error: register class `xer` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:122:26
+  --> $DIR/bad-reg.rs:144:26
    |
 LL |         asm!("/* {} */", out(xer) _);
    |                          ^^^^^^^^^^
 
 error: register `cr0` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:126:31
+  --> $DIR/bad-reg.rs:148:31
    |
 LL |         asm!("", out("cr") _, out("cr0") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr0`
@@ -103,7 +139,7 @@ LL |         asm!("", out("cr") _, out("cr0") _);
    |                  register `cr`
 
 error: register `cr1` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:128:31
+  --> $DIR/bad-reg.rs:150:31
    |
 LL |         asm!("", out("cr") _, out("cr1") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr1`
@@ -111,7 +147,7 @@ LL |         asm!("", out("cr") _, out("cr1") _);
    |                  register `cr`
 
 error: register `cr2` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:130:31
+  --> $DIR/bad-reg.rs:152:31
    |
 LL |         asm!("", out("cr") _, out("cr2") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr2`
@@ -119,7 +155,7 @@ LL |         asm!("", out("cr") _, out("cr2") _);
    |                  register `cr`
 
 error: register `cr3` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:132:31
+  --> $DIR/bad-reg.rs:154:31
    |
 LL |         asm!("", out("cr") _, out("cr3") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr3`
@@ -127,7 +163,7 @@ LL |         asm!("", out("cr") _, out("cr3") _);
    |                  register `cr`
 
 error: register `cr4` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:134:31
+  --> $DIR/bad-reg.rs:156:31
    |
 LL |         asm!("", out("cr") _, out("cr4") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr4`
@@ -135,7 +171,7 @@ LL |         asm!("", out("cr") _, out("cr4") _);
    |                  register `cr`
 
 error: register `cr5` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:136:31
+  --> $DIR/bad-reg.rs:158:31
    |
 LL |         asm!("", out("cr") _, out("cr5") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr5`
@@ -143,7 +179,7 @@ LL |         asm!("", out("cr") _, out("cr5") _);
    |                  register `cr`
 
 error: register `cr6` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:138:31
+  --> $DIR/bad-reg.rs:160:31
    |
 LL |         asm!("", out("cr") _, out("cr6") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr6`
@@ -151,7 +187,7 @@ LL |         asm!("", out("cr") _, out("cr6") _);
    |                  register `cr`
 
 error: register `cr7` conflicts with register `cr`
-  --> $DIR/bad-reg.rs:140:31
+  --> $DIR/bad-reg.rs:162:31
    |
 LL |         asm!("", out("cr") _, out("cr7") _);
    |                  -----------  ^^^^^^^^^^^^ register `cr7`
@@ -165,7 +201,7 @@ LL |         asm!("", out("r13") _);
    |                  ^^^^^^^^^^^^
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:67:27
+  --> $DIR/bad-reg.rs:63:27
    |
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
@@ -173,7 +209,7 @@ LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:70:28
+  --> $DIR/bad-reg.rs:66:28
    |
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
@@ -181,7 +217,7 @@ LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:78:35
+  --> $DIR/bad-reg.rs:74:35
    |
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
@@ -189,7 +225,7 @@ LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai
    = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:100:27
+  --> $DIR/bad-reg.rs:96:27
    |
 LL |         asm!("", in("cr") x);
    |                           ^
@@ -197,7 +233,7 @@ LL |         asm!("", in("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:103:28
+  --> $DIR/bad-reg.rs:99:28
    |
 LL |         asm!("", out("cr") x);
    |                            ^
@@ -205,7 +241,7 @@ LL |         asm!("", out("cr") x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:106:33
+  --> $DIR/bad-reg.rs:102:33
    |
 LL |         asm!("/* {} */", in(cr) x);
    |                                 ^
@@ -213,7 +249,55 @@ LL |         asm!("/* {} */", in(cr) x);
    = note: register class `cr` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:113:28
+  --> $DIR/bad-reg.rs:109:28
+   |
+LL |         asm!("", in("ctr") x);
+   |                            ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:112:29
+   |
+LL |         asm!("", out("ctr") x);
+   |                             ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:115:34
+   |
+LL |         asm!("/* {} */", in(ctr) x);
+   |                                  ^
+   |
+   = note: register class `ctr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:122:27
+   |
+LL |         asm!("", in("lr") x);
+   |                           ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:125:28
+   |
+LL |         asm!("", out("lr") x);
+   |                            ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:128:33
+   |
+LL |         asm!("/* {} */", in(lr) x);
+   |                                 ^
+   |
+   = note: register class `lr` supports these types: 
+
+error: type `i32` cannot be used with this register class
+  --> $DIR/bad-reg.rs:135:28
    |
 LL |         asm!("", in("xer") x);
    |                            ^
@@ -221,7 +305,7 @@ LL |         asm!("", in("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:116:29
+  --> $DIR/bad-reg.rs:138:29
    |
 LL |         asm!("", out("xer") x);
    |                             ^
@@ -229,12 +313,12 @@ LL |         asm!("", out("xer") x);
    = note: register class `xer` supports these types: 
 
 error: type `i32` cannot be used with this register class
-  --> $DIR/bad-reg.rs:119:34
+  --> $DIR/bad-reg.rs:141:34
    |
 LL |         asm!("/* {} */", in(xer) x);
    |                                  ^
    |
    = note: register class `xer` supports these types: 
 
-error: aborting due to 34 previous errors
+error: aborting due to 46 previous errors
 
diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs
index 5598f837960..21ea451934e 100644
--- a/tests/ui/asm/powerpc/bad-reg.rs
+++ b/tests/ui/asm/powerpc/bad-reg.rs
@@ -45,10 +45,6 @@ fn f() {
         //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
         asm!("", out("fp") _);
         //~^ ERROR invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
-        asm!("", out("lr") _);
-        //~^ ERROR invalid register `lr`: the link register cannot be used as an operand for inline asm
-        asm!("", out("ctr") _);
-        //~^ ERROR invalid register `ctr`: the counter register cannot be used as an operand for inline asm
         asm!("", out("vrsave") _);
         //~^ ERROR invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
 
@@ -108,6 +104,32 @@ fn f() {
         //~| ERROR type `i32` cannot be used with this register class
         asm!("/* {} */", out(cr) _);
         //~^ ERROR can only be used as a clobber
+        // ctr
+        asm!("", out("ctr") _); // ok
+        asm!("", in("ctr") x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("", out("ctr") x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("/* {} */", in(ctr) x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("/* {} */", out(ctr) _);
+        //~^ ERROR can only be used as a clobber
+        // lr
+        asm!("", out("lr") _); // ok
+        asm!("", in("lr") x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("", out("lr") x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("/* {} */", in(lr) x);
+        //~^ ERROR can only be used as a clobber
+        //~| ERROR type `i32` cannot be used with this register class
+        asm!("/* {} */", out(lr) _);
+        //~^ ERROR can only be used as a clobber
         // xer
         asm!("", out("xer") _); // ok
         asm!("", in("xer") x);
diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr
index 6b2e628e12e..39fee52a909 100644
--- a/tests/ui/check-cfg/cfg-crate-features.stderr
+++ b/tests/ui/check-cfg/cfg-crate-features.stderr
@@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist`
 LL | #![cfg(not(target(os = "does_not_exist")))]
    |                   ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, and `tvos` and 11 more
+   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, and `trusty` and 12 more
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
    = note: `#[warn(unexpected_cfgs)]` on by default
 
diff --git a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
index 989a01f2244..4b5fc91c7eb 100644
--- a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
+++ b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr
@@ -18,7 +18,7 @@ warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE`
 LL |     cfg_macro::my_lib_macro_value!();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `panic` are: `abort` and `unwind`
+   = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind`
    = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
    = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
    = help: the macro `cfg_macro::my_lib_macro_value` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
diff --git a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
index 95d10e014f3..0d99d061d28 100644
--- a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
+++ b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr
@@ -18,7 +18,7 @@ warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE`
 LL |     cfg_macro::my_lib_macro_value!();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `panic` are: `abort` and `unwind`
+   = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind`
    = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
    = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 6490fc63fd7..e62f741b302 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -80,7 +80,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     panic = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `panic` are: `abort` and `unwind`
+   = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_os = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
+   = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 28 warnings emitted
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
index 1cedbf75e4b..7ffbc64b074 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
@@ -1,7 +1,7 @@
-<svg width="743px" height="758px" xmlns="http://www.w3.org/2000/svg">
+<svg width="740px" height="758px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-012 { fill: #5555FF }
     .container {
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
index 36a33b74042..5f1fcdb3d50 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
@@ -1,7 +1,7 @@
-<svg width="743px" height="758px" xmlns="http://www.w3.org/2000/svg">
+<svg width="740px" height="758px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-012 { fill: #5555FF }
     .container {
diff --git a/tests/ui/diagnostic-flags/colored-session-opt-error.svg b/tests/ui/diagnostic-flags/colored-session-opt-error.svg
index 69f452f29f3..136c6fa5628 100644
--- a/tests/ui/diagnostic-flags/colored-session-opt-error.svg
+++ b/tests/ui/diagnostic-flags/colored-session-opt-error.svg
@@ -1,7 +1,7 @@
-<svg width="750px" height="74px" xmlns="http://www.w3.org/2000/svg">
+<svg width="740px" height="74px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-yellow { fill: #AA5500 }
     .container {
       padding: 0 10px;
diff --git a/tests/ui/diagnostic-flags/terminal_urls.rs b/tests/ui/diagnostic-flags/terminal_urls.rs
index 3c74e992395..631512ab579 100644
--- a/tests/ui/diagnostic-flags/terminal_urls.rs
+++ b/tests/ui/diagnostic-flags/terminal_urls.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zterminal-urls=yes
+//@ compile-flags: -Zterminal-urls=yes --error-format=human --color=always
 fn main() {
-    let () = 4; //~ ERROR
+    let () = 4;
 }
diff --git a/tests/ui/diagnostic-flags/terminal_urls.stderr b/tests/ui/diagnostic-flags/terminal_urls.stderr
deleted file mode 100644
index e5dfcdf6431..00000000000
--- a/tests/ui/diagnostic-flags/terminal_urls.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[]8;;https://doc.rust-lang.org/error_codes/E0308.htmlE0308]8;;]: mismatched types
-  --> $DIR/terminal_urls.rs:3:9
-   |
-LL |     let () = 4;
-   |         ^^   - this expression has type `{integer}`
-   |         |
-   |         expected integer, found `()`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/diagnostic-flags/terminal_urls.svg b/tests/ui/diagnostic-flags/terminal_urls.svg
new file mode 100644
index 00000000000..fcb65637c4a
--- /dev/null
+++ b/tests/ui/diagnostic-flags/terminal_urls.svg
@@ -0,0 +1,48 @@
+<svg width="740px" height="236px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { fill: #000000 }
+    .fg-ansi256-009 { fill: #FF5555 }
+    .fg-ansi256-012 { fill: #5555FF }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    .bold { font-weight: bold; }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[</tspan><tspan class="fg-ansi256-009 bold"><a href="https://doc.rust-lang.org/error_codes/E0308.html">E0308</a></tspan><tspan class="fg-ansi256-009 bold">]</tspan><tspan class="bold">: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/terminal_urls.rs:3:9</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     let () = 4;</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">^^</tspan><tspan>   </tspan><tspan class="fg-ansi256-012 bold">-</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this expression has type `{integer}`</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `()`</tspan>
+</tspan>
+    <tspan x="10px" y="154px">
+</tspan>
+    <tspan x="10px" y="172px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 1 previous error</tspan>
+</tspan>
+    <tspan x="10px" y="190px">
+</tspan>
+    <tspan x="10px" y="208px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
+</tspan>
+    <tspan x="10px" y="226px">
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/ui/diagnostic-flags/terminal_urls.windows.svg b/tests/ui/diagnostic-flags/terminal_urls.windows.svg
new file mode 100644
index 00000000000..e7b46638399
--- /dev/null
+++ b/tests/ui/diagnostic-flags/terminal_urls.windows.svg
@@ -0,0 +1,49 @@
+<svg width="740px" height="236px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { fill: #000000 }
+    .fg-ansi256-009 { fill: #FF5555 }
+    .fg-ansi256-014 { fill: #55FFFF }
+    .fg-ansi256-015 { fill: #FFFFFF }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    .bold { font-weight: bold; }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[</tspan><tspan class="fg-ansi256-009 bold"><a href="https://doc.rust-lang.org/error_codes/E0308.html">E0308</a></tspan><tspan class="fg-ansi256-009 bold">]</tspan><tspan class="fg-ansi256-015 bold">: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-014 bold">--&gt; </tspan><tspan>$DIR/terminal_urls.rs:3:9</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     let () = 4;</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">^^</tspan><tspan>   </tspan><tspan class="fg-ansi256-014 bold">-</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">this expression has type `{integer}`</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>         </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `()`</tspan>
+</tspan>
+    <tspan x="10px" y="154px">
+</tspan>
+    <tspan x="10px" y="172px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="fg-ansi256-015 bold">: aborting due to 1 previous error</tspan>
+</tspan>
+    <tspan x="10px" y="190px">
+</tspan>
+    <tspan x="10px" y="208px"><tspan class="fg-ansi256-015 bold">For more information about this error, try `rustc --explain E0308`.</tspan>
+</tspan>
+    <tspan x="10px" y="226px">
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/ui/error-emitter/E0308-clarification.svg b/tests/ui/error-emitter/E0308-clarification.svg
index 9432e3a4ee9..03ee973882d 100644
--- a/tests/ui/error-emitter/E0308-clarification.svg
+++ b/tests/ui/error-emitter/E0308-clarification.svg
@@ -1,7 +1,7 @@
 <svg width="740px" height="668px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-012 { fill: #5555FF }
     .fg-magenta { fill: #AA00AA }
diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg
index 19818ab6146..d414f042f0a 100644
--- a/tests/ui/error-emitter/highlighting.svg
+++ b/tests/ui/error-emitter/highlighting.svg
@@ -1,7 +1,7 @@
 <svg width="785px" height="434px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg
index f891bc1d2a6..92f9055cd1d 100644
--- a/tests/ui/error-emitter/highlighting.windows.svg
+++ b/tests/ui/error-emitter/highlighting.windows.svg
@@ -1,7 +1,7 @@
 <svg width="785px" height="434px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-014 { fill: #55FFFF }
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
index dd84234236d..5ffdc5a53fa 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.svg
@@ -1,7 +1,7 @@
 <svg width="1306px" height="866px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
index 144e57165da..37dc37e3e04 100644
--- a/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
+++ b/tests/ui/error-emitter/multiline-multipart-suggestion.windows.svg
@@ -1,7 +1,7 @@
 <svg width="1306px" height="866px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-014 { fill: #55FFFF }
diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg
index 7a88ac55b23..a774d558b58 100644
--- a/tests/ui/error-emitter/multiline-removal-suggestion.svg
+++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg
@@ -1,7 +1,7 @@
-<svg width="2238px" height="3890px" xmlns="http://www.w3.org/2000/svg">
+<svg width="2288px" height="3890px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/error-emitter/unicode-output.svg b/tests/ui/error-emitter/unicode-output.svg
index b253fff643b..bda4d1a2f28 100644
--- a/tests/ui/error-emitter/unicode-output.svg
+++ b/tests/ui/error-emitter/unicode-output.svg
@@ -1,7 +1,7 @@
 <svg width="785px" height="434px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
index 73acb072ac5..6077dbdc200 100644
--- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
+++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg
@@ -1,7 +1,7 @@
-<svg width="1188px" height="398px" xmlns="http://www.w3.org/2000/svg">
+<svg width="1096px" height="398px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/intrinsics/intrinsic-fmuladd.rs b/tests/ui/intrinsics/intrinsic-fmuladd.rs
index d03297884f7..ab4285590cb 100644
--- a/tests/ui/intrinsics/intrinsic-fmuladd.rs
+++ b/tests/ui/intrinsics/intrinsic-fmuladd.rs
@@ -11,7 +11,7 @@ macro_rules! assert_approx_eq {
 }
 
 fn main() {
-    unsafe {
+    {
         let nan: f32 = f32::NAN;
         let inf: f32 = f32::INFINITY;
         let neg_inf: f32 = f32::NEG_INFINITY;
@@ -25,7 +25,7 @@ fn main() {
         assert_eq!(fmuladdf32(8.9, inf, 3.2), inf);
         assert_eq!(fmuladdf32(-3.2, 2.4, neg_inf), neg_inf);
     }
-    unsafe {
+    {
         let nan: f64 = f64::NAN;
         let inf: f64 = f64::INFINITY;
         let neg_inf: f64 = f64::NEG_INFINITY;
diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr
index aea6f838e0d..1307a85c8b6 100644
--- a/tests/ui/intrinsics/reify-intrinsic.stderr
+++ b/tests/ui/intrinsics/reify-intrinsic.stderr
@@ -22,7 +22,7 @@ LL |         std::intrinsics::floorf32,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
    |
    = note: expected fn pointer `unsafe fn(_) -> _`
-                 found fn item `unsafe fn(_) -> _ {floorf32}`
+                 found fn item `fn(_) -> _ {floorf32}`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/iterators/issue-58952-filter-type-length.rs b/tests/ui/iterators/issue-58952-filter-type-length.rs
index 6730865b6c7..525a2e39a91 100644
--- a/tests/ui/iterators/issue-58952-filter-type-length.rs
+++ b/tests/ui/iterators/issue-58952-filter-type-length.rs
@@ -2,7 +2,7 @@
 
 //! This snippet causes the type length to blowup exponentially,
 //! so check that we don't accidentally exceed the type length limit.
-// FIXME: Once the size of iterator adaptors is further reduced,
+// FIXME: Once the size of iterator adapters is further reduced,
 // increase the complexity of this test.
 use std::collections::VecDeque;
 
diff --git a/tests/ui/panic-runtime/auxiliary/needs-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-abort.rs
index 21f862e4b43..cba4907dbb6 100644
--- a/tests/ui/panic-runtime/auxiliary/needs-abort.rs
+++ b/tests/ui/panic-runtime/auxiliary/needs-abort.rs
@@ -1,5 +1,7 @@
 //@ compile-flags:-C panic=abort
 //@ no-prefer-dynamic
 
+#![feature(no_core)]
 #![crate_type = "rlib"]
 #![no_std]
+#![no_core]
diff --git a/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs
new file mode 100644
index 00000000000..4a41d16faa0
--- /dev/null
+++ b/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs
@@ -0,0 +1,7 @@
+//@ compile-flags:-C panic=immediate-abort -Zunstable-options
+//@ no-prefer-dynamic
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_std]
+#![no_core]
diff --git a/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs
new file mode 100644
index 00000000000..295876fec52
--- /dev/null
+++ b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs
@@ -0,0 +1,18 @@
+//@ compile-flags:-C panic=unwind
+//@ no-prefer-dynamic
+//@ add-core-stubs
+
+#![crate_type = "rlib"]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+
+extern "C-unwind" fn foo() {}
+
+#[inline]
+fn bar() {
+    let ptr: extern "C-unwind" fn() = foo;
+    ptr();
+}
diff --git a/tests/ui/panic-runtime/bad-panic-flag1.rs b/tests/ui/panic-runtime/bad-panic-flag1.rs
index 117935847cb..575e30f785c 100644
--- a/tests/ui/panic-runtime/bad-panic-flag1.rs
+++ b/tests/ui/panic-runtime/bad-panic-flag1.rs
@@ -2,4 +2,4 @@
 
 fn main() {}
 
-//~? ERROR incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected
+//~? ERROR incorrect value `foo` for codegen option `panic` - either `unwind`, `abort`, or `immediate-abort` was expected
diff --git a/tests/ui/panic-runtime/bad-panic-flag1.stderr b/tests/ui/panic-runtime/bad-panic-flag1.stderr
index 013373c6f93..c30598bba53 100644
--- a/tests/ui/panic-runtime/bad-panic-flag1.stderr
+++ b/tests/ui/panic-runtime/bad-panic-flag1.stderr
@@ -1,2 +1,2 @@
-error: incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected
+error: incorrect value `foo` for codegen option `panic` - either `unwind`, `abort`, or `immediate-abort` was expected
 
diff --git a/tests/ui/panic-runtime/bad-panic-flag2.rs b/tests/ui/panic-runtime/bad-panic-flag2.rs
index b5d0442a033..4e34da217d7 100644
--- a/tests/ui/panic-runtime/bad-panic-flag2.rs
+++ b/tests/ui/panic-runtime/bad-panic-flag2.rs
@@ -2,4 +2,4 @@
 
 fn main() {}
 
-//~? ERROR codegen option `panic` requires either `unwind` or `abort`
+//~? ERROR codegen option `panic` requires either `unwind`, `abort`, or `immediate-abort`
diff --git a/tests/ui/panic-runtime/bad-panic-flag2.stderr b/tests/ui/panic-runtime/bad-panic-flag2.stderr
index 6ab94ea704d..c8d12749c5d 100644
--- a/tests/ui/panic-runtime/bad-panic-flag2.stderr
+++ b/tests/ui/panic-runtime/bad-panic-flag2.stderr
@@ -1,2 +1,2 @@
-error: codegen option `panic` requires either `unwind` or `abort` (C panic=<value>)
+error: codegen option `panic` requires either `unwind`, `abort`, or `immediate-abort` (C panic=<value>)
 
diff --git a/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs b/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs
new file mode 100644
index 00000000000..94dc7c5671e
--- /dev/null
+++ b/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs
@@ -0,0 +1,15 @@
+//@ build-fail
+//@ aux-build:needs-unwind.rs
+//@ compile-flags:-C panic=immediate-abort -Zunstable-options
+//@ no-prefer-dynamic
+
+extern crate needs_unwind;
+
+// immediate-abort does not require any panic runtime, so trying to build a binary crate with
+// panic=immediate-abort and the precompiled sysroot will fail to link, because no panic runtime
+// provides the panic entrypoints used by sysroot crates.
+// This test ensures that we get a clean compile error instead of a linker error.
+
+fn main() {}
+
+//~? ERROR the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
diff --git a/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr b/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr
new file mode 100644
index 00000000000..bd6bdd8b667
--- /dev/null
+++ b/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr
@@ -0,0 +1,4 @@
+error: the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs
new file mode 100644
index 00000000000..78977c60be9
--- /dev/null
+++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs
@@ -0,0 +1,21 @@
+//@ build-fail
+//@ aux-build:needs-abort.rs
+//@ compile-flags:-Cpanic=immediate-abort -Zunstable-options
+//@ no-prefer-dynamic
+//@ add-core-stubs
+//@ core-stubs-compile-flags: -Cpanic=immediate-abort -Zunstable-options
+
+#![feature(no_core)]
+#![no_std]
+#![no_main]
+#![no_core]
+
+extern crate minicore;
+extern crate needs_abort;
+
+#[no_mangle]
+extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
+    0
+}
+
+//~? ERROR the crate `needs_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr b/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr
new file mode 100644
index 00000000000..65a26b676b9
--- /dev/null
+++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr
@@ -0,0 +1,4 @@
+error: the crate `needs_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs
new file mode 100644
index 00000000000..1c5f597a3f9
--- /dev/null
+++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs
@@ -0,0 +1,20 @@
+//@ build-fail
+//@ aux-build:needs-immediate-abort.rs
+//@ compile-flags:-C panic=abort
+//@ no-prefer-dynamic
+//@ add-core-stubs
+//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort
+
+#![feature(no_core)]
+#![no_std]
+#![no_main]
+#![no_core]
+
+extern crate minicore;
+extern crate needs_immediate_abort;
+
+extern "C" fn main(argc: i32, argv: *const *const u8) -> i32 {
+    0
+}
+
+//~? ERROR the crate `need_immediate_abort_got_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr b/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr
new file mode 100644
index 00000000000..8dcf120cb9f
--- /dev/null
+++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr
@@ -0,0 +1,4 @@
+error: the crate `need_immediate_abort_got_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs
new file mode 100644
index 00000000000..24d521230d4
--- /dev/null
+++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs
@@ -0,0 +1,20 @@
+//@ build-fail
+//@ needs-unwind
+//@ aux-build:needs-immediate-abort.rs
+//@ no-prefer-dynamic
+//@ add-core-stubs
+//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort
+
+#![feature(no_core)]
+#![no_std]
+#![no_main]
+#![no_core]
+
+extern crate minicore;
+extern crate needs_immediate_abort;
+
+extern "C" fn main(argc: i32, argv: *const *const u8) -> i32 {
+    0
+}
+
+//~? ERROR the crate `need_immediate_abort_got_unwind` was compiled with a panic strategy which is incompatible with `immediate-abort`
diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr
new file mode 100644
index 00000000000..740fc80a77d
--- /dev/null
+++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr
@@ -0,0 +1,4 @@
+error: the crate `need_immediate_abort_got_unwind` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs
new file mode 100644
index 00000000000..5aec028a46c
--- /dev/null
+++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs
@@ -0,0 +1,21 @@
+//@ build-fail
+//@ aux-build:needs-unwind-immediate-abort.rs
+//@ compile-flags:-C panic=immediate-abort -Zunstable-options
+//@ no-prefer-dynamic
+//@ add-core-stubs
+//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort
+
+#![feature(no_core)]
+#![no_std]
+#![no_main]
+#![no_core]
+
+extern crate minicore;
+extern crate needs_unwind_immediate_abort;
+
+#[no_mangle]
+extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
+    0
+}
+
+//~? ERROR the crate `needs_unwind_immediate_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr
new file mode 100644
index 00000000000..8b3747d644f
--- /dev/null
+++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr
@@ -0,0 +1,4 @@
+error: the crate `needs_unwind_immediate_abort` was compiled with a panic strategy which is incompatible with `immediate-abort`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/proc-macro/panic-abort.rs b/tests/ui/proc-macro/panic-abort.rs
index 58e1d006433..adedba4ebca 100644
--- a/tests/ui/proc-macro/panic-abort.rs
+++ b/tests/ui/proc-macro/panic-abort.rs
@@ -2,4 +2,4 @@
 //@ force-host
 //@ check-pass
 
-//~? WARN building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
+//~? WARN building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic
diff --git a/tests/ui/proc-macro/panic-abort.stderr b/tests/ui/proc-macro/panic-abort.stderr
index a6e18614f8f..3dd75768bc4 100644
--- a/tests/ui/proc-macro/panic-abort.stderr
+++ b/tests/ui/proc-macro/panic-abort.stderr
@@ -1,4 +1,4 @@
-warning: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
+warning: building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg
index 2cab1f4b60f..4b952325cf7 100644
--- a/tests/ui/suggestions/incorrect-variant-literal.svg
+++ b/tests/ui/suggestions/incorrect-variant-literal.svg
@@ -1,7 +1,7 @@
 <svg width="886px" height="9524px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
-    .bg { background: #000000 }
+    .bg { fill: #000000 }
     .fg-ansi256-009 { fill: #FF5555 }
     .fg-ansi256-010 { fill: #55FF55 }
     .fg-ansi256-012 { fill: #5555FF }
diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs
index 6567f275240..2f108daf1e5 100644
--- a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs
+++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Znext-solver
 //@ check-pass
 
-// Fixes a regression in icu_provider_adaptors where we weren't normalizing the
+// Fixes a regression in icu_provider_adapters where we weren't normalizing the
 // return type of a function type before performing a `Ty::builtin_deref` call,
 // leading to an ICE.