about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md7
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs46
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs11
-rw-r--r--compiler/rustc_driver_impl/messages.ftl5
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs38
-rw-r--r--compiler/rustc_driver_impl/src/session_diagnostics.rs15
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl3
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs135
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs26
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs15
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs28
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp12
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs15
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs95
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs60
-rw-r--r--compiler/rustc_span/src/source_map.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs8
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs8
-rw-r--r--compiler/stable_mir/src/mir/mono.rs11
-rw-r--r--library/std/src/io/buffered/bufreader.rs8
-rw-r--r--library/std/src/io/cursor.rs7
-rw-r--r--library/std/src/io/impls.rs24
-rw-r--r--library/std/src/io/mod.rs43
-rw-r--r--library/std/src/io/stdio.rs10
-rw-r--r--library/std/src/os/windows/process.rs56
-rw-r--r--library/std/src/process.rs79
-rw-r--r--library/std/src/sys/pal/unix/fs.rs169
-rw-r--r--library/std/src/sys/pal/unix/fs/tests.rs71
-rw-r--r--library/std/src/sys/pal/unsupported/process.rs150
-rw-r--r--library/std/src/sys/pal/windows/api.rs96
-rw-r--r--library/std/src/sys/pal/windows/api/tests.rs16
-rw-r--r--library/std/src/sys/pal/windows/args.rs105
-rw-r--r--library/std/src/sys/pal/windows/mod.rs7
-rw-r--r--library/std/src/sys/pal/windows/thread.rs10
-rw-r--r--src/librustdoc/html/render/context.rs2
-rw-r--r--src/librustdoc/html/render/print_item.rs42
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css20
-rw-r--r--src/librustdoc/html/static/images/clipboard.svg2
-rw-r--r--src/librustdoc/html/static/images/favicon-16x16.pngbin715 -> 0 bytes
-rw-r--r--src/librustdoc/html/static/images/wheel.svg2
-rw-r--r--src/librustdoc/html/static_files.rs1
-rw-r--r--src/librustdoc/html/templates/page.html20
-rw-r--r--src/librustdoc/html/templates/print_item.html4
-rw-r--r--src/librustdoc/html/templates/sidebar.html2
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs3
-rw-r--r--src/tools/compiletest/src/header.rs1
-rw-r--r--src/tools/run-make-support/src/rustc.rs24
-rw-r--r--src/tools/run-make-support/src/rustdoc.rs18
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--src/tools/tidy/src/ui_tests.rs5
-rw-r--r--tests/codegen/riscv-target-abi.rs20
-rw-r--r--tests/run-make/cross-lang-lto-riscv-abi/cstart.c5
-rw-r--r--tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs9
-rw-r--r--tests/run-make/cross-lang-lto-riscv-abi/rmake.rs74
-rw-r--r--tests/run-make/exit-code/Makefile12
-rw-r--r--tests/run-make/exit-code/rmake.rs43
-rw-r--r--tests/rustdoc-gui/search-result-go-to-first.goml6
-rw-r--r--tests/rustdoc-gui/toggle-click-deadspace.goml2
-rw-r--r--tests/rustdoc-ui/ice-bug-report-url.stderr2
-rw-r--r--tests/ui-fulldeps/stable-mir/check_intrinsics.rs115
-rw-r--r--tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs16
-rw-r--r--tests/ui/conditional-compilation/cfg-generic-params.rs26
-rw-r--r--tests/ui/conditional-compilation/cfg-generic-params.stderr18
-rw-r--r--tests/ui/const-generics/const-arg-in-const-arg.rs4
-rw-r--r--tests/ui/consts/const-eval/const-eval-query-stack.stderr2
-rw-r--r--tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs22
-rw-r--r--tests/ui/debuginfo/backtrace-line-tables-only.rs49
-rw-r--r--tests/ui/does-nothing.rs2
-rw-r--r--tests/ui/does-nothing.stderr9
-rw-r--r--tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs4
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs5
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr42
-rw-r--r--tests/ui/panics/default-backtrace-ice.stderr2
-rw-r--r--tests/ui/proc-macro/derive-helper-configured.rs6
-rw-r--r--tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs6
-rw-r--r--tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr12
-rw-r--r--tests/ui/regions/regions-static-bound-rpass.rs9
-rw-r--r--tests/ui/regions/regions-static-bound-rpass.stderr38
-rw-r--r--tests/ui/regions/regions-static-bound.rs9
-rw-r--r--tests/ui/regions/regions-static-bound.stderr37
-rw-r--r--tests/ui/regions/transitively-redundant-lifetimes.rs20
-rw-r--r--tests/ui/regions/transitively-redundant-lifetimes.stderr47
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs2
-rw-r--r--tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed2
-rw-r--r--tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs4
-rw-r--r--tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr2
-rw-r--r--tests/ui/std/windows-bat-args.rs90
-rw-r--r--tests/ui/std/windows-bat-args1.bat1
-rw-r--r--tests/ui/std/windows-bat-args2.bat1
-rw-r--r--tests/ui/std/windows-bat-args3.bat1
-rw-r--r--tests/ui/track-diagnostics/track.stderr2
-rw-r--r--tests/ui/type/pattern_types/const_generics.rs13
-rw-r--r--tests/ui/typeck/remove-semi-but-confused-char.rs11
-rw-r--r--tests/ui/typeck/remove-semi-but-confused-char.stderr25
102 files changed, 1906 insertions, 511 deletions
diff --git a/RELEASES.md b/RELEASES.md
index f35dd27ec24..3bd638ff64c 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,10 @@
+Version 1.77.2 (2024-04-09)
+===========================
+
+<a id="1.77.2"></a>
+
+- [CVE-2024-24576: fix escaping of Windows batch file arguments in `std::process::Command`](https://blog.rust-lang.org/2024/04/09/cve-2024-24576.html)
+
 Version 1.77.1 (2024-03-28)
 ===========================
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 093a985495c..01addc8127e 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -346,7 +346,7 @@ impl<'a> AstValidator<'a> {
             in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
             const_context_label: parent_constness,
             remove_const_sugg: (
-                self.session.source_map().span_extend_while(span, |c| c == ' ').unwrap_or(span),
+                self.session.source_map().span_extend_while_whitespace(span),
                 match parent_constness {
                     Some(_) => rustc_errors::Applicability::MachineApplicable,
                     None => rustc_errors::Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 06a681c24e6..e61af863dc0 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -608,7 +608,7 @@ pub(crate) fn run_pass_manager(
             "LTOPostLink".as_ptr().cast(),
             11,
         ) {
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 module.module_llvm.llmod(),
                 llvm::LLVMModFlagBehavior::Error,
                 c"LTOPostLink".as_ptr().cast(),
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index df9f066e58a..d32baa6dc02 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -180,13 +180,13 @@ pub unsafe fn create_module<'ll>(
     // to ensure intrinsic calls don't use it.
     if !sess.needs_plt() {
         let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
+        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
     }
 
     // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
     if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
         let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
             canonical_jump_tables,
@@ -197,7 +197,7 @@ pub unsafe fn create_module<'ll>(
     // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
         let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
             enable_split_lto_unit,
@@ -208,7 +208,7 @@ pub unsafe fn create_module<'ll>(
     // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
     if sess.is_sanitizer_kcfi_enabled() {
         let kcfi = c"kcfi".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
+        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
     }
 
     // Control Flow Guard is currently only supported by the MSVC linker on Windows.
@@ -217,7 +217,7 @@ pub unsafe fn create_module<'ll>(
             CFGuard::Disabled => {}
             CFGuard::NoChecks => {
                 // Set `cfguard=1` module flag to emit metadata only.
-                llvm::LLVMRustAddModuleFlag(
+                llvm::LLVMRustAddModuleFlagU32(
                     llmod,
                     llvm::LLVMModFlagBehavior::Warning,
                     c"cfguard".as_ptr() as *const _,
@@ -226,7 +226,7 @@ pub unsafe fn create_module<'ll>(
             }
             CFGuard::Checks => {
                 // Set `cfguard=2` module flag to emit metadata and checks.
-                llvm::LLVMRustAddModuleFlag(
+                llvm::LLVMRustAddModuleFlagU32(
                     llmod,
                     llvm::LLVMModFlagBehavior::Warning,
                     c"cfguard".as_ptr() as *const _,
@@ -238,26 +238,26 @@ pub unsafe fn create_module<'ll>(
 
     if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
         if sess.target.arch == "aarch64" {
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 llmod,
                 llvm::LLVMModFlagBehavior::Min,
                 c"branch-target-enforcement".as_ptr().cast(),
                 bti.into(),
             );
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 llmod,
                 llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address".as_ptr().cast(),
                 pac_ret.is_some().into(),
             );
             let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 llmod,
                 llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address-all".as_ptr().cast(),
                 pac_opts.leaf.into(),
             );
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 llmod,
                 llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address-with-bkey".as_ptr().cast(),
@@ -273,7 +273,7 @@ pub unsafe fn create_module<'ll>(
 
     // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
     if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
             c"cf-protection-branch".as_ptr().cast(),
@@ -281,7 +281,7 @@ pub unsafe fn create_module<'ll>(
         )
     }
     if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Override,
             c"cf-protection-return".as_ptr().cast(),
@@ -290,7 +290,7 @@ pub unsafe fn create_module<'ll>(
     }
 
     if sess.opts.unstable_opts.virtual_function_elimination {
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Error,
             c"Virtual Function Elim".as_ptr().cast(),
@@ -300,7 +300,7 @@ pub unsafe fn create_module<'ll>(
 
     // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
     if sess.opts.unstable_opts.ehcont_guard {
-        llvm::LLVMRustAddModuleFlag(
+        llvm::LLVMRustAddModuleFlagU32(
             llmod,
             llvm::LLVMModFlagBehavior::Warning,
             c"ehcontguard".as_ptr() as *const _,
@@ -326,6 +326,22 @@ pub unsafe fn create_module<'ll>(
         llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
     );
 
+    // Emit RISC-V specific target-abi metadata
+    // to workaround lld as the LTO plugin not
+    // correctly setting target-abi for the LTO object
+    // FIXME: https://github.com/llvm/llvm-project/issues/50591
+    // If llvm_abiname is empty, emit nothing.
+    let llvm_abiname = &sess.target.options.llvm_abiname;
+    if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() {
+        llvm::LLVMRustAddModuleFlagString(
+            llmod,
+            llvm::LLVMModFlagBehavior::Error,
+            c"target-abi".as_ptr(),
+            llvm_abiname.as_ptr().cast(),
+            llvm_abiname.len(),
+        );
+    }
+
     // Add module flags specified via -Z llvm_module_flag
     for (key, value, behavior) in &sess.opts.unstable_opts.llvm_module_flag {
         let key = format!("{key}\0");
@@ -341,7 +357,7 @@ pub unsafe fn create_module<'ll>(
             // We already checked this during option parsing
             _ => unreachable!(),
         };
-        llvm::LLVMRustAddModuleFlag(llmod, behavior, key.as_ptr().cast(), *value)
+        llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value)
     }
 
     llmod
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index d3a851b40c0..4fdaa59e0e5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -110,7 +110,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
                     .unstable_opts
                     .dwarf_version
                     .unwrap_or(sess.target.default_dwarf_version);
-                llvm::LLVMRustAddModuleFlag(
+                llvm::LLVMRustAddModuleFlagU32(
                     self.llmod,
                     llvm::LLVMModFlagBehavior::Warning,
                     c"Dwarf Version".as_ptr().cast(),
@@ -118,7 +118,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
                 );
             } else {
                 // Indicate that we want CodeView debug information on MSVC
-                llvm::LLVMRustAddModuleFlag(
+                llvm::LLVMRustAddModuleFlagU32(
                     self.llmod,
                     llvm::LLVMModFlagBehavior::Warning,
                     c"CodeView".as_ptr().cast(),
@@ -127,7 +127,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
             }
 
             // Prevent bitcode readers from deleting the debug info.
-            llvm::LLVMRustAddModuleFlag(
+            llvm::LLVMRustAddModuleFlagU32(
                 self.llmod,
                 llvm::LLVMModFlagBehavior::Warning,
                 c"Debug Info Version".as_ptr().cast(),
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 284bc74d5c4..5509baaa3e9 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1801,12 +1801,21 @@ extern "C" {
     ///
     /// In order for Rust-C LTO to work, module flags must be compatible with Clang. What
     /// "compatible" means depends on the merge behaviors involved.
-    pub fn LLVMRustAddModuleFlag(
+    pub fn LLVMRustAddModuleFlagU32(
         M: &Module,
         merge_behavior: LLVMModFlagBehavior,
         name: *const c_char,
         value: u32,
     );
+
+    pub fn LLVMRustAddModuleFlagString(
+        M: &Module,
+        merge_behavior: LLVMModFlagBehavior,
+        name: *const c_char,
+        value: *const c_char,
+        value_len: size_t,
+    );
+
     pub fn LLVMRustHasModuleFlag(M: &Module, name: *const c_char, len: size_t) -> bool;
 
     pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;
diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl
index 62391daecd0..5b39248302e 100644
--- a/compiler/rustc_driver_impl/messages.ftl
+++ b/compiler/rustc_driver_impl/messages.ftl
@@ -1,10 +1,7 @@
 driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
 driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
 driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
-driver_impl_ice_bug_report_outdated =
-    it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the meantime
-    .update = please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
-    .url = if the problem still persists, we would appreciate a bug report: {$bug_report_url}
+driver_impl_ice_bug_report_update_note = please make sure that you have updated to the latest nightly
 driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
 
 driver_impl_ice_flags = compiler flags: {$flags}
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index b4007aeb8d7..1f44621736c 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -61,7 +61,7 @@ use std::str;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, OnceLock};
 use std::time::{Instant, SystemTime};
-use time::{Date, OffsetDateTime, Time};
+use time::OffsetDateTime;
 
 #[allow(unused_macros)]
 macro do_not_use_print($($t:tt)*) {
@@ -1385,9 +1385,6 @@ pub fn install_ice_hook(
     using_internal_features
 }
 
-const DATE_FORMAT: &[time::format_description::FormatItem<'static>] =
-    &time::macros::format_description!("[year]-[month]-[day]");
-
 /// Prints the ICE message, including query stack, but without backtrace.
 ///
 /// The message will point the user at `bug_report_url` to report the ICE.
@@ -1416,33 +1413,14 @@ fn report_ice(
         dcx.emit_err(session_diagnostics::Ice);
     }
 
-    use time::ext::NumericalDuration;
-
-    // Try to hint user to update nightly if applicable when reporting an ICE.
-    // Attempt to calculate when current version was released, and add 12 hours
-    // as buffer. If the current version's release timestamp is older than
-    // the system's current time + 24 hours + 12 hours buffer if we're on
-    // nightly.
-    if let Some("nightly") = option_env!("CFG_RELEASE_CHANNEL")
-        && let Some(version) = option_env!("CFG_VERSION")
-        && let Some(ver_date_str) = option_env!("CFG_VER_DATE")
-        && let Ok(ver_date) = Date::parse(&ver_date_str, DATE_FORMAT)
-        && let ver_datetime = OffsetDateTime::new_utc(ver_date, Time::MIDNIGHT)
-        && let system_datetime = OffsetDateTime::from(SystemTime::now())
-        && system_datetime.checked_sub(36.hours()).is_some_and(|d| d > ver_datetime)
-        && !using_internal_features.load(std::sync::atomic::Ordering::Relaxed)
-    {
-        dcx.emit_note(session_diagnostics::IceBugReportOutdated {
-            version,
-            bug_report_url,
-            note_update: (),
-            note_url: (),
-        });
+    if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
+        dcx.emit_note(session_diagnostics::IceBugReportInternalFeature);
     } else {
-        if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
-            dcx.emit_note(session_diagnostics::IceBugReportInternalFeature);
-        } else {
-            dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
+        dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
+
+        // Only emit update nightly hint for users on nightly builds.
+        if rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
+            dcx.emit_note(session_diagnostics::UpdateNightlyNote);
         }
     }
 
diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs
index 62d0da62d2a..1a9683e840a 100644
--- a/compiler/rustc_driver_impl/src/session_diagnostics.rs
+++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs
@@ -43,19 +43,12 @@ pub(crate) struct IceBugReport<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(driver_impl_ice_bug_report_internal_feature)]
-pub(crate) struct IceBugReportInternalFeature;
+#[diag(driver_impl_ice_bug_report_update_note)]
+pub(crate) struct UpdateNightlyNote;
 
 #[derive(Diagnostic)]
-#[diag(driver_impl_ice_bug_report_outdated)]
-pub(crate) struct IceBugReportOutdated<'a> {
-    pub version: &'a str,
-    pub bug_report_url: &'a str,
-    #[note(driver_impl_update)]
-    pub note_update: (),
-    #[note(driver_impl_url)]
-    pub note_url: (),
-}
+#[diag(driver_impl_ice_bug_report_internal_feature)]
+pub(crate) struct IceBugReportInternalFeature;
 
 #[derive(Diagnostic)]
 #[diag(driver_impl_ice_version)]
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index f90190797ae..6c0551848d6 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -46,6 +46,7 @@ impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
     }
 }
 
+#[macro_export]
 macro_rules! into_diag_arg_using_display {
     ($( $ty:ty ),+ $(,)?) => {
         $(
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index e66a834ab9e..86b8b6d6b2b 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -355,6 +355,9 @@ hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pa
 hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
     .label = not allowed in type signatures
 
+hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
+    .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
+
 hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
 
 hir_analysis_return_type_notation_equality_bound =
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4fd7c870fc7..c26f982fa47 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -8,11 +8,13 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
+use rustc_macros::LintDiagnostic;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -136,6 +138,8 @@ where
         infcx.implied_bounds_tys_compat(param_env, body_def_id, &assumed_wf_types, false);
     let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
 
+    lint_redundant_lifetimes(tcx, body_def_id, &outlives_env);
+
     let errors = infcx.resolve_regions(&outlives_env);
     if errors.is_empty() {
         return Ok(());
@@ -2010,6 +2014,137 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
     res
 }
 
+fn lint_redundant_lifetimes<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    owner_id: LocalDefId,
+    outlives_env: &OutlivesEnvironment<'tcx>,
+) {
+    let def_kind = tcx.def_kind(owner_id);
+    match def_kind {
+        DefKind::Struct
+        | DefKind::Union
+        | DefKind::Enum
+        | DefKind::Trait
+        | DefKind::TraitAlias
+        | DefKind::Fn
+        | DefKind::Const
+        | DefKind::Impl { of_trait: _ } => {
+            // Proceed
+        }
+        DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
+            let parent_def_id = tcx.local_parent(owner_id);
+            if matches!(tcx.def_kind(parent_def_id), DefKind::Impl { of_trait: true }) {
+                // Don't check for redundant lifetimes for associated items of trait
+                // implementations, since the signature is required to be compatible
+                // with the trait, even if the implementation implies some lifetimes
+                // are redundant.
+                return;
+            }
+        }
+        DefKind::Mod
+        | DefKind::Variant
+        | DefKind::TyAlias
+        | DefKind::ForeignTy
+        | DefKind::TyParam
+        | DefKind::ConstParam
+        | DefKind::Static { .. }
+        | DefKind::Ctor(_, _)
+        | DefKind::Macro(_)
+        | DefKind::ExternCrate
+        | DefKind::Use
+        | DefKind::ForeignMod
+        | DefKind::AnonConst
+        | DefKind::InlineConst
+        | DefKind::OpaqueTy
+        | DefKind::Field
+        | DefKind::LifetimeParam
+        | DefKind::GlobalAsm
+        | DefKind::Closure => return,
+    }
+
+    // The ordering of this lifetime map is a bit subtle.
+    //
+    // Specifically, we want to find a "candidate" lifetime that precedes a "victim" lifetime,
+    // where we can prove that `'candidate = 'victim`.
+    //
+    // `'static` must come first in this list because we can never replace `'static` with
+    // something else, but if we find some lifetime `'a` where `'a = 'static`, we want to
+    // suggest replacing `'a` with `'static`.
+    let mut lifetimes = vec![tcx.lifetimes.re_static];
+    lifetimes.extend(
+        ty::GenericArgs::identity_for_item(tcx, owner_id).iter().filter_map(|arg| arg.as_region()),
+    );
+    // If we are in a function, add its late-bound lifetimes too.
+    if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) {
+        for var in tcx.fn_sig(owner_id).instantiate_identity().bound_vars() {
+            let ty::BoundVariableKind::Region(kind) = var else { continue };
+            lifetimes.push(ty::Region::new_late_param(tcx, owner_id.to_def_id(), kind));
+        }
+    }
+    lifetimes.retain(|candidate| candidate.has_name());
+
+    // Keep track of lifetimes which have already been replaced with other lifetimes.
+    // This makes sure that if `'a = 'b = 'c`, we don't say `'c` should be replaced by
+    // both `'a` and `'b`.
+    let mut shadowed = FxHashSet::default();
+
+    for (idx, &candidate) in lifetimes.iter().enumerate() {
+        // Don't suggest removing a lifetime twice. We only need to check this
+        // here and not up in the `victim` loop because equality is transitive,
+        // so if A = C and B = C, then A must = B, so it'll be shadowed too in
+        // A's victim loop.
+        if shadowed.contains(&candidate) {
+            continue;
+        }
+
+        for &victim in &lifetimes[(idx + 1)..] {
+            // We should only have late-bound lifetimes of the `BrNamed` variety,
+            // since we get these signatures straight from `hir_lowering`. And any
+            // other regions (ReError/ReStatic/etc.) shouldn't matter, since we
+            // can't really suggest to remove them.
+            let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
+            | ty::ReLateParam(ty::LateParamRegion {
+                bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
+                ..
+            })) = victim.kind()
+            else {
+                continue;
+            };
+
+            // Do not rename lifetimes not local to this item since they'll overlap
+            // with the lint running on the parent. We still want to consider parent
+            // lifetimes which make child lifetimes redundant, otherwise we would
+            // have truncated the `identity_for_item` args above.
+            if tcx.parent(def_id) != owner_id.to_def_id() {
+                continue;
+            }
+
+            // If `candidate <: victim` and `victim <: candidate`, then they're equal.
+            if outlives_env.free_region_map().sub_free_regions(tcx, candidate, victim)
+                && outlives_env.free_region_map().sub_free_regions(tcx, victim, candidate)
+            {
+                shadowed.insert(victim);
+                tcx.emit_node_span_lint(
+                    rustc_lint_defs::builtin::REDUNDANT_LIFETIMES,
+                    tcx.local_def_id_to_hir_id(def_id.expect_local()),
+                    tcx.def_span(def_id),
+                    RedundantLifetimeArgsLint { candidate, victim },
+                );
+            }
+        }
+    }
+}
+
+#[derive(LintDiagnostic)]
+#[diag(hir_analysis_redundant_lifetime_args)]
+#[note]
+struct RedundantLifetimeArgsLint<'tcx> {
+    /// The lifetime we have found to be redundant.
+    victim: ty::Region<'tcx>,
+    // The lifetime we can replace the victim with.
+    candidate: ty::Region<'tcx>,
+}
+
 pub fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
 }
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 0b8ac9926e4..affd678fc6c 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -20,7 +20,6 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::resolve_bound_vars::*;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
-use rustc_session::lint;
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
@@ -867,31 +866,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             }) => {
                 self.visit_lifetime(lifetime);
                 walk_list!(self, visit_param_bound, bounds);
-
-                if lifetime.res != hir::LifetimeName::Static {
-                    for bound in bounds {
-                        let hir::GenericBound::Outlives(lt) = bound else {
-                            continue;
-                        };
-                        if lt.res != hir::LifetimeName::Static {
-                            continue;
-                        }
-                        self.insert_lifetime(lt, ResolvedArg::StaticLifetime);
-                        self.tcx.node_span_lint(
-                            lint::builtin::UNUSED_LIFETIMES,
-                            lifetime.hir_id,
-                            lifetime.ident.span,
-                            format!("unnecessary lifetime parameter `{}`", lifetime.ident),
-                            |lint| {
-                                let help = format!(
-                                    "you can use the `'static` lifetime directly, in place of `{}`",
-                                    lifetime.ident,
-                                );
-                                lint.help(help);
-                            },
-                        );
-                    }
-                }
             }
             &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
                 self.visit_ty(lhs_ty);
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 59f0fac5aa7..9fb8b4ac40e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2223,6 +2223,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                         Err(LitToConstError::TypeError) => todo!(),
                                     }
                                 }
+
+                                hir::ExprKind::Path(hir::QPath::Resolved(
+                                    _,
+                                    &hir::Path {
+                                        res: Res::Def(DefKind::ConstParam, def_id), ..
+                                    },
+                                )) => {
+                                    let ty = tcx
+                                        .type_of(def_id)
+                                        .no_bound_vars()
+                                        .expect("const parameter types cannot be generic");
+                                    let item_def_id = tcx.parent(def_id);
+                                    let generics = tcx.generics_of(item_def_id);
+                                    let index = generics.param_def_id_to_index[&def_id];
+                                    let name = tcx.item_name(def_id);
+                                    ty::Const::new_param(tcx, ty::ParamConst::new(index, name), ty)
+                                }
+
                                 _ => {
                                     let err = tcx
                                         .dcx()
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index d3df3dd3885..7a1a2c498aa 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2023,8 +2023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .tcx
                 .sess
                 .source_map()
-                .span_extend_while(range_start.span, |c| c.is_whitespace())
-                .unwrap_or(range_start.span)
+                .span_extend_while_whitespace(range_start.span)
                 .shrink_to_hi()
                 .to(range_end.span);
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 9a05fb1c30f..7855031e705 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -15,7 +15,7 @@ use rustc_middle::traits::{
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{sym, Span};
 
 use crate::errors::{
     ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
@@ -763,8 +763,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             let mac_call = rustc_span::source_map::original_sp(last_stmt.span, blk.span);
             self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)?
         } else {
-            last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1))
+            self.tcx
+                .sess
+                .source_map()
+                .span_extend_while_whitespace(last_expr.span)
+                .shrink_to_hi()
+                .with_hi(last_stmt.span.hi())
         };
+
         Some((span, needs_box))
     }
 
@@ -867,10 +873,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         format!(" {ident} ")
                     };
                     let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi();
-                    (
-                        sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span),
-                        sugg,
-                    )
+                    (sm.span_extend_while_whitespace(left_span), sugg)
                 };
                 Some(SuggestRemoveSemiOrReturnBinding::Add { sp: span, code: sugg, ident: *ident })
             }
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index e2010ab3830..16e3b8c11c1 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -215,10 +215,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
             if let Some(deletion_span) = deletion_span {
                 let msg = "elide the single-use lifetime";
                 let (use_span, replace_lt) = if elide {
-                    let use_span = sess
-                        .source_map()
-                        .span_extend_while(use_span, char::is_whitespace)
-                        .unwrap_or(use_span);
+                    let use_span = sess.source_map().span_extend_while_whitespace(use_span);
                     (use_span, String::new())
                 } else {
                     (use_span, "'_".to_owned())
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 53b5273803c..2713690f812 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -79,6 +79,7 @@ declare_lint_pass! {
         PROC_MACRO_BACK_COMPAT,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
+        REDUNDANT_LIFETIMES,
         REFINING_IMPL_TRAIT_INTERNAL,
         REFINING_IMPL_TRAIT_REACHABLE,
         RENAMED_AND_REMOVED_LINTS,
@@ -1708,6 +1709,33 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `redundant_lifetimes` lint detects lifetime parameters that are
+    /// redundant because they are equal to another named lifetime.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #[deny(redundant_lifetimes)]
+    ///
+    /// // `'a = 'static`, so all usages of `'a` can be replaced with `'static`
+    /// pub fn bar<'a: 'static>() {}
+    ///
+    /// // `'a = 'b`, so all usages of `'b` can be replaced with `'a`
+    /// pub fn bar<'a: 'b, 'b: 'a>() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Unused lifetime parameters may signal a mistake or unfinished code.
+    /// Consider removing the parameter.
+    pub REDUNDANT_LIFETIMES,
+    Allow,
+    "detects lifetime parameters that are redundant because they are equal to some other named lifetime"
+}
+
+declare_lint! {
     /// The `tyvar_behind_raw_pointer` lint detects raw pointer to an
     /// inference variable.
     ///
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index a6894a7e089..37c2da4c23a 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -817,7 +817,7 @@ extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
 
 extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
 
-extern "C" void LLVMRustAddModuleFlag(
+extern "C" void LLVMRustAddModuleFlagU32(
     LLVMModuleRef M,
     Module::ModFlagBehavior MergeBehavior,
     const char *Name,
@@ -825,6 +825,16 @@ extern "C" void LLVMRustAddModuleFlag(
   unwrap(M)->addModuleFlag(MergeBehavior, Name, Value);
 }
 
+extern "C" void LLVMRustAddModuleFlagString(
+    LLVMModuleRef M,
+    Module::ModFlagBehavior MergeBehavior,
+    const char *Name,
+    const char *Value,
+    size_t ValueLen) {
+  unwrap(M)->addModuleFlag(MergeBehavior, Name,
+    MDString::get(unwrap(M)->getContext(), StringRef(Value, ValueLen)));
+}
+
 extern "C" bool LLVMRustHasModuleFlag(LLVMModuleRef M, const char *Name,
                                       size_t Len) {
   return unwrap(M)->getModuleFlag(StringRef(Name, Len)) != nullptr;
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 0daf83162db..6275c5d2a11 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -757,7 +757,7 @@ pub struct GlobalCtxt<'tcx> {
 impl<'tcx> GlobalCtxt<'tcx> {
     /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
     /// `f`.
-    pub fn enter<'a: 'tcx, F, R>(&'a self, f: F) -> R
+    pub fn enter<F, R>(&'tcx self, f: F) -> R
     where
         F: FnOnce(TyCtxt<'tcx>) -> R,
     {
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index ee18647cdd8..cc1d6e50f6d 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -5,13 +5,13 @@ use std::fmt::Write;
 use std::ops::ControlFlow;
 
 use crate::ty::{
-    AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque, PolyTraitPredicate,
-    Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
-    TypeVisitor,
+    self, AliasTy, Const, ConstKind, FallibleTypeFolder, InferConst, InferTy, Opaque,
+    PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{Applicability, Diag, DiagArgValue, IntoDiagArg};
+use rustc_errors::{into_diag_arg_using_display, Applicability, Diag, DiagArgValue, IntoDiagArg};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -19,10 +19,9 @@ use rustc_hir::{PredicateOrigin, WherePredicate};
 use rustc_span::{BytePos, Span};
 use rustc_type_ir::TyKind::*;
 
-impl<'tcx> IntoDiagArg for Ty<'tcx> {
-    fn into_diag_arg(self) -> DiagArgValue {
-        self.to_string().into_diag_arg()
-    }
+into_diag_arg_using_display! {
+    Ty<'_>,
+    ty::Region<'_>,
 }
 
 impl<'tcx> Ty<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index d6ec7d64926..b26f968bf5e 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -126,59 +126,41 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
 
         let mut field_remapping = UnordMap::default();
 
-        // One parent capture may correspond to several child captures if we end up
-        // refining the set of captures via edition-2021 precise captures. We want to
-        // match up any number of child captures with one parent capture, so we keep
-        // peeking off this `Peekable` until the child doesn't match anymore.
-        let mut parent_captures =
-            tcx.closure_captures(parent_def_id).iter().copied().enumerate().peekable();
-        // Make sure we use every field at least once, b/c why are we capturing something
-        // if it's not used in the inner coroutine.
-        let mut field_used_at_least_once = false;
-
-        for (child_field_idx, child_capture) in tcx
+        let mut child_captures = tcx
             .closure_captures(coroutine_def_id)
             .iter()
             .copied()
             // By construction we capture all the args first.
             .skip(num_args)
             .enumerate()
+            .peekable();
+
+        // One parent capture may correspond to several child captures if we end up
+        // refining the set of captures via edition-2021 precise captures. We want to
+        // match up any number of child captures with one parent capture, so we keep
+        // peeking off this `Peekable` until the child doesn't match anymore.
+        for (parent_field_idx, parent_capture) in
+            tcx.closure_captures(parent_def_id).iter().copied().enumerate()
         {
-            loop {
-                let Some(&(parent_field_idx, parent_capture)) = parent_captures.peek() else {
-                    bug!("we ran out of parent captures!")
-                };
+            // Make sure we use every field at least once, b/c why are we capturing something
+            // if it's not used in the inner coroutine.
+            let mut field_used_at_least_once = false;
 
-                let PlaceBase::Upvar(parent_base) = parent_capture.place.base else {
-                    bug!("expected capture to be an upvar");
-                };
-                let PlaceBase::Upvar(child_base) = child_capture.place.base else {
-                    bug!("expected capture to be an upvar");
-                };
+            // A parent matches a child if they share the same prefix of projections.
+            // The child may have more, if it is capturing sub-fields out of
+            // something that is captured by-move in the parent closure.
+            while child_captures.peek().map_or(false, |(_, child_capture)| {
+                child_prefix_matches_parent_projections(parent_capture, child_capture)
+            }) {
+                let (child_field_idx, child_capture) = child_captures.next().unwrap();
 
+                // This analysis only makes sense if the parent capture is a
+                // prefix of the child capture.
                 assert!(
-                    child_capture.place.projections.len() >= parent_capture.place.projections.len()
+                    child_capture.place.projections.len() >= parent_capture.place.projections.len(),
+                    "parent capture ({parent_capture:#?}) expected to be prefix of \
+                    child capture ({child_capture:#?})"
                 );
-                // A parent matches a child they share the same prefix of projections.
-                // The child may have more, if it is capturing sub-fields out of
-                // something that is captured by-move in the parent closure.
-                if parent_base.var_path.hir_id != child_base.var_path.hir_id
-                    || !std::iter::zip(
-                        &child_capture.place.projections,
-                        &parent_capture.place.projections,
-                    )
-                    .all(|(child, parent)| child.kind == parent.kind)
-                {
-                    // Make sure the field was used at least once.
-                    assert!(
-                        field_used_at_least_once,
-                        "we captured {parent_capture:#?} but it was not used in the child coroutine?"
-                    );
-                    field_used_at_least_once = false;
-                    // Skip this field.
-                    let _ = parent_captures.next().unwrap();
-                    continue;
-                }
 
                 // Store this set of additional projections (fields and derefs).
                 // We need to re-apply them later.
@@ -221,15 +203,15 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
                 );
 
                 field_used_at_least_once = true;
-                break;
             }
-        }
 
-        // Pop the last parent capture
-        if field_used_at_least_once {
-            let _ = parent_captures.next().unwrap();
+            // Make sure the field was used at least once.
+            assert!(
+                field_used_at_least_once,
+                "we captured {parent_capture:#?} but it was not used in the child coroutine?"
+            );
         }
-        assert_eq!(parent_captures.next(), None, "leftover parent captures?");
+        assert_eq!(child_captures.next(), None, "leftover child captures?");
 
         if coroutine_kind == ty::ClosureKind::FnOnce {
             assert_eq!(field_remapping.len(), tcx.closure_captures(parent_def_id).len());
@@ -251,6 +233,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
         let mut by_move_body = body.clone();
         MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
         dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(()));
+        // FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body.
         by_move_body.source = mir::MirSource::from_instance(InstanceDef::CoroutineKindShim {
             coroutine_def_id: coroutine_def_id.to_def_id(),
         });
@@ -258,6 +241,22 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
     }
 }
 
+fn child_prefix_matches_parent_projections(
+    parent_capture: &ty::CapturedPlace<'_>,
+    child_capture: &ty::CapturedPlace<'_>,
+) -> bool {
+    let PlaceBase::Upvar(parent_base) = parent_capture.place.base else {
+        bug!("expected capture to be an upvar");
+    };
+    let PlaceBase::Upvar(child_base) = child_capture.place.base else {
+        bug!("expected capture to be an upvar");
+    };
+
+    parent_base.var_path.hir_id == child_base.var_path.hir_id
+        && std::iter::zip(&child_capture.place.projections, &parent_capture.place.projections)
+            .all(|(child, parent)| child.kind == parent.kind)
+}
+
 struct MakeByMoveBody<'tcx> {
     tcx: TyCtxt<'tcx>,
     field_remapping: UnordMap<FieldIdx, (FieldIdx, Ty<'tcx>, bool, &'tcx [Projection<'tcx>])>,
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 0762016ef75..221224eed01 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -4,9 +4,10 @@
 //! monomorphic body using internal representation.
 //! After that, we convert the internal representation into a stable one.
 use crate::rustc_smir::{Stable, Tables};
+use rustc_hir::def::DefKind;
 use rustc_middle::mir;
 use rustc_middle::mir::visit::MutVisitor;
-use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 
 /// Builds a monomorphic body for a given instance.
 pub struct BodyBuilder<'tcx> {
@@ -16,46 +17,43 @@ pub struct BodyBuilder<'tcx> {
 
 impl<'tcx> BodyBuilder<'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
+        let instance = match instance.def {
+            // To get the fallback body of an intrinsic, we need to convert it to an item.
+            ty::InstanceDef::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
+            _ => instance,
+        };
         BodyBuilder { tcx, instance }
     }
 
     /// Build a stable monomorphic body for a given instance based on the MIR body.
     ///
-    /// Note that we skip instantiation for static and constants. Trying to do so can cause ICE.
-    ///
-    /// We do monomorphize non-generic functions to eval unevaluated constants.
+    /// All constants are also evaluated.
     pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
-        let mut body = self.tcx.instance_mir(self.instance.def).clone();
-        if self.tcx.def_kind(self.instance.def_id()).is_fn_like() || !self.instance.args.is_empty()
+        let body = tables.tcx.instance_mir(self.instance.def).clone();
+        let mono_body = if !self.instance.args.is_empty()
+            // Without the `generic_const_exprs` feature gate, anon consts in signatures do not
+            // get generic parameters. Which is wrong, but also not a problem without
+            // generic_const_exprs
+            || self.tcx.def_kind(self.instance.def_id()) != DefKind::AnonConst
         {
-            self.visit_body(&mut body);
-        }
-        body.stable(tables)
-    }
-
-    fn monomorphize<T>(&self, value: T) -> T
-    where
-        T: ty::TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.instance.instantiate_mir_and_normalize_erasing_regions(
-            self.tcx,
-            ty::ParamEnv::reveal_all(),
-            ty::EarlyBinder::bind(value),
-        )
+            let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions(
+                tables.tcx,
+                ty::ParamEnv::reveal_all(),
+                ty::EarlyBinder::bind(body),
+            );
+            self.visit_body(&mut mono_body);
+            mono_body
+        } else {
+            // Already monomorphic.
+            body
+        };
+        mono_body.stable(tables)
     }
 }
 
 impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
-    fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, _location: mir::Location) {
-        *ct = self.monomorphize(*ct);
-    }
-
-    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: mir::visit::TyContext) {
-        *ty = self.monomorphize(*ty);
-    }
-
     fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
-        let const_ = self.monomorphize(constant.const_);
+        let const_ = constant.const_;
         let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), constant.span) {
             Ok(v) => v,
             Err(mir::interpret::ErrorHandled::Reported(..)) => return,
@@ -68,10 +66,6 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
         self.super_constant(constant, location);
     }
 
-    fn visit_args(&mut self, args: &mut GenericArgsRef<'tcx>, _: mir::Location) {
-        *args = self.monomorphize(*args);
-    }
-
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 770624d331d..f721a04d6b9 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -654,6 +654,12 @@ impl SourceMap {
         })
     }
 
+    /// Extends the span to include any trailing whitespace, or returns the original
+    /// span if a `SpanSnippetError` was encountered.
+    pub fn span_extend_while_whitespace(&self, span: Span) -> Span {
+        self.span_extend_while(span, char::is_whitespace).unwrap_or(span)
+    }
+
     /// Extends the given `Span` to previous character while the previous character matches the predicate
     pub fn span_extend_prev_while(
         &self,
@@ -1034,12 +1040,9 @@ impl SourceMap {
     /// // ^^^^^^ input
     /// ```
     pub fn mac_call_stmt_semi_span(&self, mac_call: Span) -> Option<Span> {
-        let span = self.span_extend_while(mac_call, char::is_whitespace).ok()?;
-        let span = span.shrink_to_hi().with_hi(BytePos(span.hi().0.checked_add(1)?));
-        if self.span_to_snippet(span).as_deref() != Ok(";") {
-            return None;
-        }
-        Some(span)
+        let span = self.span_extend_while_whitespace(mac_call);
+        let span = self.next_point(span);
+        if self.span_to_snippet(span).as_deref() == Ok(";") { Some(span) } else { None }
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index af90372b97c..2067956d0f5 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1592,8 +1592,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     .tcx
                     .sess
                     .source_map()
-                    .span_extend_while(expr_span, char::is_whitespace)
-                    .unwrap_or(expr_span)
+                    .span_extend_while_whitespace(expr_span)
                     .shrink_to_hi()
                     .to(await_expr.span.shrink_to_hi());
                 err.span_suggestion(
@@ -4851,10 +4850,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
     let hir::IsAsync::Async(async_span) = sig.header.asyncness else {
         return None;
     };
-    let Ok(async_span) = tcx.sess.source_map().span_extend_while(async_span, |c| c.is_whitespace())
-    else {
-        return None;
-    };
+    let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span);
 
     let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
     let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 77cd4662ae5..902b76e8c1e 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -133,10 +133,14 @@ fn layout_of_uncached<'tcx>(
                 ty::PatternKind::Range { start, end, include_end } => {
                     if let Abi::Scalar(scalar) | Abi::ScalarPair(scalar, _) = &mut layout.abi {
                         if let Some(start) = start {
-                            scalar.valid_range_mut().start = start.eval_bits(tcx, param_env);
+                            scalar.valid_range_mut().start = start
+                                .try_eval_bits(tcx, param_env)
+                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                         }
                         if let Some(end) = end {
-                            let mut end = end.eval_bits(tcx, param_env);
+                            let mut end = end
+                                .try_eval_bits(tcx, param_env)
+                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
                             if !include_end {
                                 end = end.wrapping_sub(1);
                             }
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs
index aafa89c03e0..a032a180fcf 100644
--- a/compiler/stable_mir/src/mir/mono.rs
+++ b/compiler/stable_mir/src/mir/mono.rs
@@ -41,13 +41,22 @@ impl Instance {
         with(|cx| cx.instance_args(self.def))
     }
 
-    /// Get the body of an Instance. The body will be eagerly monomorphized.
+    /// Get the body of an Instance.
+    ///
+    /// The body will be eagerly monomorphized and all constants will already be evaluated.
+    ///
+    /// This method will return the intrinsic fallback body if one was defined.
     pub fn body(&self) -> Option<Body> {
         with(|context| context.instance_body(self.def))
     }
 
     /// Check whether this instance has a body available.
     ///
+    /// For intrinsics with fallback body, this will return `true`. It is up to the user to decide
+    /// whether to specialize the intrinsic or to use its fallback body.
+    ///
+    /// For more information on fallback body, see <https://github.com/rust-lang/rust/issues/93145>.
+    ///
     /// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build
     /// the StableMIR body.
     pub fn has_body(&self) -> bool {
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index acaa7e9228e..250cd583696 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -322,6 +322,14 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
         crate::io::default_read_exact(self, buf)
     }
 
+    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        if self.buf.consume_with(cursor.capacity(), |claimed| cursor.append(claimed)) {
+            return Ok(());
+        }
+
+        crate::io::default_read_buf_exact(self, cursor)
+    }
+
     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
         if self.buf.pos() == self.buf.filled() && total_len >= self.capacity() {
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 4ef1f1b695e..49dde828c1f 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -357,6 +357,13 @@ where
         self.pos += n as u64;
         Ok(())
     }
+
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        let n = cursor.capacity();
+        Read::read_buf_exact(&mut self.remaining_slice(), cursor)?;
+        self.pos += n as u64;
+        Ok(())
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index cb972abd2b8..ee7ed4bcc9a 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -50,6 +50,10 @@ impl<R: Read + ?Sized> Read for &mut R {
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         (**self).read_exact(buf)
     }
+    #[inline]
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        (**self).read_buf_exact(cursor)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write + ?Sized> Write for &mut W {
@@ -154,6 +158,10 @@ impl<R: Read + ?Sized> Read for Box<R> {
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         (**self).read_exact(buf)
     }
+    #[inline]
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        (**self).read_buf_exact(cursor)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write + ?Sized> Write for Box<W> {
@@ -302,6 +310,22 @@ impl Read for &[u8] {
     }
 
     #[inline]
+    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        if cursor.capacity() > self.len() {
+            return Err(io::const_io_error!(
+                ErrorKind::UnexpectedEof,
+                "failed to fill whole buffer"
+            ));
+        }
+        let (a, b) = self.split_at(cursor.capacity());
+
+        cursor.append(a);
+
+        *self = b;
+        Ok(())
+    }
+
+    #[inline]
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         let len = self.len();
         buf.try_reserve(len)?;
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 10bf9c51d16..980b3e7aa48 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -582,6 +582,29 @@ where
     Ok(())
 }
 
+pub(crate) fn default_read_buf_exact<R: Read + ?Sized>(
+    this: &mut R,
+    mut cursor: BorrowedCursor<'_>,
+) -> Result<()> {
+    while cursor.capacity() > 0 {
+        let prev_written = cursor.written();
+        match this.read_buf(cursor.reborrow()) {
+            Ok(()) => {}
+            Err(e) if e.is_interrupted() => continue,
+            Err(e) => return Err(e),
+        }
+
+        if cursor.written() == prev_written {
+            return Err(error::const_io_error!(
+                ErrorKind::UnexpectedEof,
+                "failed to fill whole buffer"
+            ));
+        }
+    }
+
+    Ok(())
+}
+
 /// The `Read` trait allows for reading bytes from a source.
 ///
 /// Implementors of the `Read` trait are called 'readers'.
@@ -978,24 +1001,8 @@ pub trait Read {
     ///
     /// If this function returns an error, all bytes read will be appended to `cursor`.
     #[unstable(feature = "read_buf", issue = "78485")]
-    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> Result<()> {
-        while cursor.capacity() > 0 {
-            let prev_written = cursor.written();
-            match self.read_buf(cursor.reborrow()) {
-                Ok(()) => {}
-                Err(e) if e.is_interrupted() => continue,
-                Err(e) => return Err(e),
-            }
-
-            if cursor.written() == prev_written {
-                return Err(error::const_io_error!(
-                    ErrorKind::UnexpectedEof,
-                    "failed to fill whole buffer"
-                ));
-            }
-        }
-
-        Ok(())
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> {
+        default_read_buf_exact(self, cursor)
     }
 
     /// Creates a "by reference" adaptor for this instance of `Read`.
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 8f60b3b1535..73fa7cbc3fe 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -451,6 +451,9 @@ impl Read for Stdin {
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         self.lock().read_exact(buf)
     }
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        self.lock().read_buf_exact(cursor)
+    }
 }
 
 #[stable(feature = "read_shared_stdin", since = "1.78.0")]
@@ -477,6 +480,9 @@ impl Read for &Stdin {
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         self.lock().read_exact(buf)
     }
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        self.lock().read_buf_exact(cursor)
+    }
 }
 
 // only used by platform-dependent io::copy specializations, i.e. unused on some platforms
@@ -517,6 +523,10 @@ impl Read for StdinLock<'_> {
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         self.inner.read_exact(buf)
     }
+
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        self.inner.read_buf_exact(cursor)
+    }
 }
 
 impl SpecReadByte for StdinLock<'_> {
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 1be3acf5d43..15ab2250122 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -199,8 +199,60 @@ pub trait CommandExt: Sealed {
 
     /// Append literal text to the command line without any quoting or escaping.
     ///
-    /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
-    /// `CommandLineToArgvW` escaping rules.
+    /// This is useful for passing arguments to applications which doesn't follow
+    /// the standard C run-time escaping rules, such as `cmd.exe /c`.
+    ///
+    /// # Bat files
+    ///
+    /// Note the `cmd /c` command line has slightly different escaping rules then bat files
+    /// themselves. If possible, it may be better to write complex arguments to a temporary
+    /// .bat file, with appropriate escaping, and simply run that using:
+    ///
+    /// ```no_run
+    /// # use std::process::Command;
+    /// # let temp_bat_file = "";
+    /// # #[allow(unused)]
+    /// let output = Command::new("cmd").args(["/c", &format!("\"{temp_bat_file}\"")]).output();
+    /// ```
+    ///
+    /// # Example
+    ///
+    /// Run a bat script using both trusted and untrusted arguments.
+    ///
+    /// ```no_run
+    /// #[cfg(windows)]
+    /// // `my_script_path` is a path to known bat file.
+    /// // `user_name` is an untrusted name given by the user.
+    /// fn run_script(
+    ///     my_script_path: &str,
+    ///     user_name: &str,
+    /// ) -> Result<std::process::Output, std::io::Error> {
+    ///     use std::io::{Error, ErrorKind};
+    ///     use std::os::windows::process::CommandExt;
+    ///     use std::process::Command;
+    ///
+    ///     // Create the command line, making sure to quote the script path.
+    ///     // This assumes the fixed arguments have been tested to work with the script we're using.
+    ///     let mut cmd_args = format!(r#""{my_script_path}" "--features=[a,b,c]""#);
+    ///
+    ///     // Make sure the user name is safe. In particular we need to be
+    ///     // cautious of ascii symbols that cmd may interpret specially.
+    ///     // Here we only allow alphanumeric characters.
+    ///     if !user_name.chars().all(|c| c.is_alphanumeric()) {
+    ///         return Err(Error::new(ErrorKind::InvalidInput, "invalid user name"));
+    ///     }
+    ///     // now we've checked the user name, let's add that too.
+    ///     cmd_args.push(' ');
+    ///     cmd_args.push_str(&format!("--user {user_name}"));
+    ///
+    ///     // call cmd.exe and return the output
+    ///     Command::new("cmd.exe")
+    ///         .arg("/c")
+    ///         // surround the entire command in an extra pair of quotes, as required by cmd.exe.
+    ///         .raw_arg(&format!("\"{cmd_args}\""))
+    ///         .output()
+    /// }
+    /// ````
     #[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")]
     fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
 
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index b84d5f11954..69cc61b30ef 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -88,6 +88,47 @@
 //! assert_eq!(b"test", output.stdout.as_slice());
 //! ```
 //!
+//! # Windows argument splitting
+//!
+//! On Unix systems arguments are passed to a new process as an array of strings
+//! but on Windows arguments are passed as a single commandline string and it's
+//! up to the child process to parse it into an array. Therefore the parent and
+//! child processes must agree on how the commandline string is encoded.
+//!
+//! Most programs use the standard C run-time `argv`, which in practice results
+//! in consistent argument handling. However some programs have their own way of
+//! parsing the commandline string. In these cases using [`arg`] or [`args`] may
+//! result in the child process seeing a different array of arguments then the
+//! parent process intended.
+//!
+//! Two ways of mitigating this are:
+//!
+//! * Validate untrusted input so that only a safe subset is allowed.
+//! * Use [`raw_arg`] to build a custom commandline. This bypasses the escaping
+//!   rules used by [`arg`] so should be used with due caution.
+//!
+//! `cmd.exe` and `.bat` use non-standard argument parsing and are especially
+//! vulnerable to malicious input as they may be used to run arbitrary shell
+//! commands. Untrusted arguments should be restricted as much as possible.
+//! For examples on handling this see [`raw_arg`].
+//!
+//! ### Bat file special handling
+//!
+//! On Windows, `Command` uses the Windows API function [`CreateProcessW`] to
+//! spawn new processes. An undocumented feature of this function is that,
+//! when given a `.bat` file as the application to run, it will automatically
+//! convert that into running `cmd.exe /c` with the bat file as the next argument.
+//!
+//! For historical reasons Rust currently preserves this behaviour when using
+//! [`Command::new`], and escapes the arguments according to `cmd.exe` rules.
+//! Due to the complexity of `cmd.exe` argument handling, it might not be
+//! possible to safely escape some special chars, and using them will result
+//! in an error being returned at process spawn. The set of unescapeable
+//! special chars might change between releases.
+//!
+//! Also note that running `.bat` scripts in this way may be removed in the
+//! future and so should not be relied upon.
+//!
 //! [`spawn`]: Command::spawn
 //! [`output`]: Command::output
 //!
@@ -97,6 +138,12 @@
 //!
 //! [`Write`]: io::Write
 //! [`Read`]: io::Read
+//!
+//! [`arg`]: Command::arg
+//! [`args`]: Command::args
+//! [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+//!
+//! [`CreateProcessW`]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
 
 #![stable(feature = "process", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
@@ -611,6 +658,22 @@ impl Command {
     /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
+    /// <div class="warning">
+    ///
+    /// On Windows use caution with untrusted inputs. Most applications use the
+    /// standard convention for decoding arguments passed to them. These are safe to use with `arg`.
+    /// However some applications, such as `cmd.exe` and `.bat` files, use a non-standard way of decoding arguments
+    /// and are therefore vulnerable to malicious input.
+    /// In the case of `cmd.exe` this is especially important because a malicious argument can potentially run arbitrary shell commands.
+    ///
+    /// See [Windows argument splitting][windows-args] for more details
+    /// or [`raw_arg`] for manually implementing non-standard argument encoding.
+    ///
+    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+    /// [windows-args]: crate::process#windows-argument-splitting
+    ///
+    /// </div>
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -641,6 +704,22 @@ impl Command {
     /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
+    /// <div class="warning">
+    ///
+    /// On Windows use caution with untrusted inputs. Most applications use the
+    /// standard convention for decoding arguments passed to them. These are safe to use with `args`.
+    /// However some applications, such as `cmd.exe` and `.bat` files, use a non-standard way of decoding arguments
+    /// and are therefore vulnerable to malicious input.
+    /// In the case of `cmd.exe` this is especially important because a malicious argument can potentially run arbitrary shell commands.
+    ///
+    /// See [Windows argument splitting][windows-args] for more details
+    /// or [`raw_arg`] for manually implementing non-standard argument encoding.
+    ///
+    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg
+    /// [windows-args]: crate::process#windows-argument-splitting
+    ///
+    /// </div>
+    ///
     /// # Examples
     ///
     /// Basic usage:
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 96f64051cda..e8430b6ae70 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1,10 +1,13 @@
 // miri has some special hacks here that make things unused.
 #![cfg_attr(miri, allow(unused))]
 
+#[cfg(test)]
+mod tests;
+
 use crate::os::unix::prelude::*;
 
 use crate::ffi::{CStr, OsStr, OsString};
-use crate::fmt;
+use crate::fmt::{self, Write as _};
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
@@ -356,7 +359,7 @@ pub struct DirEntry {
     entry: dirent64,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 pub struct OpenOptions {
     // generic
     read: bool,
@@ -370,7 +373,7 @@ pub struct OpenOptions {
     mode: mode_t,
 }
 
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, PartialEq, Eq)]
 pub struct FilePermissions {
     mode: mode_t,
 }
@@ -389,7 +392,7 @@ pub struct FileTimes {
     created: Option<SystemTime>,
 }
 
-#[derive(Copy, Clone, Eq, Debug)]
+#[derive(Copy, Clone, Eq)]
 pub struct FileType {
     mode: mode_t,
 }
@@ -406,11 +409,13 @@ impl core::hash::Hash for FileType {
     }
 }
 
-#[derive(Debug)]
 pub struct DirBuilder {
     mode: mode_t,
 }
 
+#[derive(Copy, Clone)]
+struct Mode(mode_t);
+
 cfg_has_statx! {{
     impl FileAttr {
         fn from_stat64(stat: stat64) -> Self {
@@ -689,12 +694,26 @@ impl FileType {
     }
 }
 
+impl fmt::Debug for FileType {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let FileType { mode } = self;
+        f.debug_struct("FileType").field("mode", &Mode(*mode)).finish()
+    }
+}
+
 impl FromInner<u32> for FilePermissions {
     fn from_inner(mode: u32) -> FilePermissions {
         FilePermissions { mode: mode as mode_t }
     }
 }
 
+impl fmt::Debug for FilePermissions {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let FilePermissions { mode } = self;
+        f.debug_struct("FilePermissions").field("mode", &Mode(*mode)).finish()
+    }
+}
+
 impl fmt::Debug for ReadDir {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
@@ -1135,6 +1154,23 @@ impl OpenOptions {
     }
 }
 
+impl fmt::Debug for OpenOptions {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let OpenOptions { read, write, append, truncate, create, create_new, custom_flags, mode } =
+            self;
+        f.debug_struct("OpenOptions")
+            .field("read", read)
+            .field("write", write)
+            .field("append", append)
+            .field("truncate", truncate)
+            .field("create", create)
+            .field("create_new", create_new)
+            .field("custom_flags", custom_flags)
+            .field("mode", &Mode(*mode))
+            .finish()
+    }
+}
+
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
         run_path_with_cstr(path, &|path| File::open_c(path, opts))
@@ -1425,6 +1461,13 @@ impl DirBuilder {
     }
 }
 
+impl fmt::Debug for DirBuilder {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let DirBuilder { mode } = self;
+        f.debug_struct("DirBuilder").field("mode", &Mode(*mode)).finish()
+    }
+}
+
 impl AsInner<FileDesc> for File {
     #[inline]
     fn as_inner(&self) -> &FileDesc {
@@ -1597,6 +1640,73 @@ impl fmt::Debug for File {
     }
 }
 
+// Format in octal, followed by the mode format used in `ls -l`.
+//
+// References:
+//   https://pubs.opengroup.org/onlinepubs/009696899/utilities/ls.html
+//   https://www.gnu.org/software/libc/manual/html_node/Testing-File-Type.html
+//   https://www.gnu.org/software/libc/manual/html_node/Permission-Bits.html
+//
+// Example:
+//   0o100664 (-rw-rw-r--)
+impl fmt::Debug for Mode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self(mode) = *self;
+        write!(f, "0o{mode:06o}")?;
+
+        let entry_type = match mode & libc::S_IFMT {
+            libc::S_IFDIR => 'd',
+            libc::S_IFBLK => 'b',
+            libc::S_IFCHR => 'c',
+            libc::S_IFLNK => 'l',
+            libc::S_IFIFO => 'p',
+            libc::S_IFREG => '-',
+            _ => return Ok(()),
+        };
+
+        f.write_str(" (")?;
+        f.write_char(entry_type)?;
+
+        // Owner permissions
+        f.write_char(if mode & libc::S_IRUSR != 0 { 'r' } else { '-' })?;
+        f.write_char(if mode & libc::S_IWUSR != 0 { 'w' } else { '-' })?;
+        let owner_executable = mode & libc::S_IXUSR != 0;
+        let setuid = mode as c_int & libc::S_ISUID as c_int != 0;
+        f.write_char(match (owner_executable, setuid) {
+            (true, true) => 's',  // executable and setuid
+            (false, true) => 'S', // setuid
+            (true, false) => 'x', // executable
+            (false, false) => '-',
+        })?;
+
+        // Group permissions
+        f.write_char(if mode & libc::S_IRGRP != 0 { 'r' } else { '-' })?;
+        f.write_char(if mode & libc::S_IWGRP != 0 { 'w' } else { '-' })?;
+        let group_executable = mode & libc::S_IXGRP != 0;
+        let setgid = mode as c_int & libc::S_ISGID as c_int != 0;
+        f.write_char(match (group_executable, setgid) {
+            (true, true) => 's',  // executable and setgid
+            (false, true) => 'S', // setgid
+            (true, false) => 'x', // executable
+            (false, false) => '-',
+        })?;
+
+        // Other permissions
+        f.write_char(if mode & libc::S_IROTH != 0 { 'r' } else { '-' })?;
+        f.write_char(if mode & libc::S_IWOTH != 0 { 'w' } else { '-' })?;
+        let other_executable = mode & libc::S_IXOTH != 0;
+        let sticky = mode as c_int & libc::S_ISVTX as c_int != 0;
+        f.write_char(match (entry_type, other_executable, sticky) {
+            ('d', true, true) => 't',  // searchable and restricted deletion
+            ('d', false, true) => 'T', // restricted deletion
+            (_, true, _) => 'x',       // executable
+            (_, false, _) => '-',
+        })?;
+
+        f.write_char(')')
+    }
+}
+
 pub fn readdir(path: &Path) -> io::Result<ReadDir> {
     let ptr = run_path_with_cstr(path, &|p| unsafe { Ok(libc::opendir(p.as_ptr())) })?;
     if ptr.is_null() {
@@ -1847,39 +1957,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     use crate::sync::atomic::{AtomicBool, Ordering};
 
-    const COPYFILE_ACL: u32 = 1 << 0;
-    const COPYFILE_STAT: u32 = 1 << 1;
-    const COPYFILE_XATTR: u32 = 1 << 2;
-    const COPYFILE_DATA: u32 = 1 << 3;
-
-    const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL;
-    const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR;
-    const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA;
-
-    const COPYFILE_STATE_COPIED: u32 = 8;
-
-    #[allow(non_camel_case_types)]
-    type copyfile_state_t = *mut libc::c_void;
-    #[allow(non_camel_case_types)]
-    type copyfile_flags_t = u32;
-
-    extern "C" {
-        fn fcopyfile(
-            from: libc::c_int,
-            to: libc::c_int,
-            state: copyfile_state_t,
-            flags: copyfile_flags_t,
-        ) -> libc::c_int;
-        fn copyfile_state_alloc() -> copyfile_state_t;
-        fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int;
-        fn copyfile_state_get(
-            state: copyfile_state_t,
-            flag: u32,
-            dst: *mut libc::c_void,
-        ) -> libc::c_int;
-    }
-
-    struct FreeOnDrop(copyfile_state_t);
+    const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
+
+    struct FreeOnDrop(libc::copyfile_state_t);
     impl Drop for FreeOnDrop {
         fn drop(&mut self) {
             // The code below ensures that `FreeOnDrop` is never a null pointer
@@ -1887,7 +1967,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
                 // `copyfile_state_free` returns -1 if the `to` or `from` files
                 // cannot be closed. However, this is not considered this an
                 // error.
-                copyfile_state_free(self.0);
+                libc::copyfile_state_free(self.0);
             }
         }
     }
@@ -1896,6 +1976,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     // We store the availability in a global to avoid unnecessary syscalls
     static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true);
     syscall! {
+        // Mirrors `libc::fclonefileat`
         fn fclonefileat(
             srcfd: libc::c_int,
             dst_dirfd: libc::c_int,
@@ -1932,22 +2013,22 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     // We ensure that `FreeOnDrop` never contains a null pointer so it is
     // always safe to call `copyfile_state_free`
     let state = unsafe {
-        let state = copyfile_state_alloc();
+        let state = libc::copyfile_state_alloc();
         if state.is_null() {
             return Err(crate::io::Error::last_os_error());
         }
         FreeOnDrop(state)
     };
 
-    let flags = if writer_metadata.is_file() { COPYFILE_ALL } else { COPYFILE_DATA };
+    let flags = if writer_metadata.is_file() { COPYFILE_ALL } else { libc::COPYFILE_DATA };
 
-    cvt(unsafe { fcopyfile(reader.as_raw_fd(), writer.as_raw_fd(), state.0, flags) })?;
+    cvt(unsafe { libc::fcopyfile(reader.as_raw_fd(), writer.as_raw_fd(), state.0, flags) })?;
 
     let mut bytes_copied: libc::off_t = 0;
     cvt(unsafe {
-        copyfile_state_get(
+        libc::copyfile_state_get(
             state.0,
-            COPYFILE_STATE_COPIED,
+            libc::COPYFILE_STATE_COPIED as u32,
             core::ptr::addr_of_mut!(bytes_copied) as *mut libc::c_void,
         )
     })?;
diff --git a/library/std/src/sys/pal/unix/fs/tests.rs b/library/std/src/sys/pal/unix/fs/tests.rs
new file mode 100644
index 00000000000..71be3472148
--- /dev/null
+++ b/library/std/src/sys/pal/unix/fs/tests.rs
@@ -0,0 +1,71 @@
+use crate::sys::pal::unix::fs::FilePermissions;
+
+#[test]
+fn test_debug_permissions() {
+    for (expected, mode) in [
+        // typical directory
+        ("FilePermissions { mode: 0o040775 (drwxrwxr-x) }", 0o04_0775),
+        // typical text file
+        ("FilePermissions { mode: 0o100664 (-rw-rw-r--) }", 0o10_0664),
+        // setuid executable (/usr/bin/doas)
+        ("FilePermissions { mode: 0o104755 (-rwsr-xr-x) }", 0o10_4755),
+        // char device (/dev/zero)
+        ("FilePermissions { mode: 0o020666 (crw-rw-rw-) }", 0o02_0666),
+        // block device (/dev/vda)
+        ("FilePermissions { mode: 0o060660 (brw-rw----) }", 0o06_0660),
+        // symbolic link
+        ("FilePermissions { mode: 0o120777 (lrwxrwxrwx) }", 0o12_0777),
+        // fifo
+        ("FilePermissions { mode: 0o010664 (prw-rw-r--) }", 0o01_0664),
+        // none
+        ("FilePermissions { mode: 0o100000 (----------) }", 0o10_0000),
+        // unrecognized
+        ("FilePermissions { mode: 0o000001 }", 1),
+    ] {
+        assert_eq!(format!("{:?}", FilePermissions { mode }), expected);
+    }
+
+    for (expected, mode) in [
+        // owner readable
+        ("FilePermissions { mode: 0o100400 (-r--------) }", libc::S_IRUSR),
+        // owner writable
+        ("FilePermissions { mode: 0o100200 (--w-------) }", libc::S_IWUSR),
+        // owner executable
+        ("FilePermissions { mode: 0o100100 (---x------) }", libc::S_IXUSR),
+        // setuid
+        ("FilePermissions { mode: 0o104000 (---S------) }", libc::S_ISUID),
+        // owner executable and setuid
+        ("FilePermissions { mode: 0o104100 (---s------) }", libc::S_IXUSR | libc::S_ISUID),
+        // group readable
+        ("FilePermissions { mode: 0o100040 (----r-----) }", libc::S_IRGRP),
+        // group writable
+        ("FilePermissions { mode: 0o100020 (-----w----) }", libc::S_IWGRP),
+        // group executable
+        ("FilePermissions { mode: 0o100010 (------x---) }", libc::S_IXGRP),
+        // setgid
+        ("FilePermissions { mode: 0o102000 (------S---) }", libc::S_ISGID),
+        // group executable and setgid
+        ("FilePermissions { mode: 0o102010 (------s---) }", libc::S_IXGRP | libc::S_ISGID),
+        // other readable
+        ("FilePermissions { mode: 0o100004 (-------r--) }", libc::S_IROTH),
+        // other writeable
+        ("FilePermissions { mode: 0o100002 (--------w-) }", libc::S_IWOTH),
+        // other executable
+        ("FilePermissions { mode: 0o100001 (---------x) }", libc::S_IXOTH),
+        // sticky
+        ("FilePermissions { mode: 0o101000 (----------) }", libc::S_ISVTX),
+        // other executable and sticky
+        ("FilePermissions { mode: 0o101001 (---------x) }", libc::S_IXOTH | libc::S_ISVTX),
+    ] {
+        assert_eq!(format!("{:?}", FilePermissions { mode: libc::S_IFREG | mode }), expected);
+    }
+
+    for (expected, mode) in [
+        // restricted deletion ("sticky") flag is set, and search permission is not granted to others
+        ("FilePermissions { mode: 0o041000 (d--------T) }", libc::S_ISVTX),
+        // sticky and searchable
+        ("FilePermissions { mode: 0o041001 (d--------t) }", libc::S_ISVTX | libc::S_IXOTH),
+    ] {
+        assert_eq!(format!("{:?}", FilePermissions { mode: libc::S_IFDIR | mode }), expected);
+    }
+}
diff --git a/library/std/src/sys/pal/unsupported/process.rs b/library/std/src/sys/pal/unsupported/process.rs
index 6a989dd3e76..2445d9073db 100644
--- a/library/std/src/sys/pal/unsupported/process.rs
+++ b/library/std/src/sys/pal/unsupported/process.rs
@@ -1,7 +1,6 @@
-use crate::ffi::OsStr;
+use crate::ffi::{OsStr, OsString};
 use crate::fmt;
 use crate::io;
-use crate::marker::PhantomData;
 use crate::num::NonZero;
 use crate::path::Path;
 use crate::sys::fs::File;
@@ -16,7 +15,14 @@ pub use crate::ffi::OsString as EnvKey;
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct Command {
+    program: OsString,
+    args: Vec<OsString>,
     env: CommandEnv,
+
+    cwd: Option<OsString>,
+    stdin: Option<Stdio>,
+    stdout: Option<Stdio>,
+    stderr: Option<Stdio>,
 }
 
 // passed back to std::process with the pipes connected to the child, if any
@@ -27,39 +33,62 @@ pub struct StdioPipes {
     pub stderr: Option<AnonPipe>,
 }
 
-// FIXME: This should be a unit struct, so we can always construct it
-// The value here should be never used, since we cannot spawn processes.
+#[derive(Debug)]
 pub enum Stdio {
     Inherit,
     Null,
     MakePipe,
+    ParentStdout,
+    ParentStderr,
+    #[allow(dead_code)] // This variant exists only for the Debug impl
+    InheritFile(File),
 }
 
 impl Command {
-    pub fn new(_program: &OsStr) -> Command {
-        Command { env: Default::default() }
+    pub fn new(program: &OsStr) -> Command {
+        Command {
+            program: program.to_owned(),
+            args: vec![program.to_owned()],
+            env: Default::default(),
+            cwd: None,
+            stdin: None,
+            stdout: None,
+            stderr: None,
+        }
     }
 
-    pub fn arg(&mut self, _arg: &OsStr) {}
+    pub fn arg(&mut self, arg: &OsStr) {
+        self.args.push(arg.to_owned());
+    }
 
     pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
-    pub fn cwd(&mut self, _dir: &OsStr) {}
+    pub fn cwd(&mut self, dir: &OsStr) {
+        self.cwd = Some(dir.to_owned());
+    }
 
-    pub fn stdin(&mut self, _stdin: Stdio) {}
+    pub fn stdin(&mut self, stdin: Stdio) {
+        self.stdin = Some(stdin);
+    }
 
-    pub fn stdout(&mut self, _stdout: Stdio) {}
+    pub fn stdout(&mut self, stdout: Stdio) {
+        self.stdout = Some(stdout);
+    }
 
-    pub fn stderr(&mut self, _stderr: Stdio) {}
+    pub fn stderr(&mut self, stderr: Stdio) {
+        self.stderr = Some(stderr);
+    }
 
     pub fn get_program(&self) -> &OsStr {
-        panic!("unsupported")
+        &self.program
     }
 
     pub fn get_args(&self) -> CommandArgs<'_> {
-        CommandArgs { _p: PhantomData }
+        let mut iter = self.args.iter();
+        iter.next();
+        CommandArgs { iter }
     }
 
     pub fn get_envs(&self) -> CommandEnvs<'_> {
@@ -67,7 +96,7 @@ impl Command {
     }
 
     pub fn get_current_dir(&self) -> Option<&Path> {
-        None
+        self.cwd.as_ref().map(|cs| Path::new(cs))
     }
 
     pub fn spawn(
@@ -91,31 +120,83 @@ impl From<AnonPipe> for Stdio {
 
 impl From<io::Stdout> for Stdio {
     fn from(_: io::Stdout) -> Stdio {
-        // FIXME: This is wrong.
-        // Instead, the Stdio we have here should be a unit struct.
-        panic!("unsupported")
+        Stdio::ParentStdout
     }
 }
 
 impl From<io::Stderr> for Stdio {
     fn from(_: io::Stderr) -> Stdio {
-        // FIXME: This is wrong.
-        // Instead, the Stdio we have here should be a unit struct.
-        panic!("unsupported")
+        Stdio::ParentStderr
     }
 }
 
 impl From<File> for Stdio {
-    fn from(_file: File) -> Stdio {
-        // FIXME: This is wrong.
-        // Instead, the Stdio we have here should be a unit struct.
-        panic!("unsupported")
+    fn from(file: File) -> Stdio {
+        Stdio::InheritFile(file)
     }
 }
 
 impl fmt::Debug for Command {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
+    // show all attributes
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if f.alternate() {
+            let mut debug_command = f.debug_struct("Command");
+            debug_command.field("program", &self.program).field("args", &self.args);
+            if !self.env.is_unchanged() {
+                debug_command.field("env", &self.env);
+            }
+
+            if self.cwd.is_some() {
+                debug_command.field("cwd", &self.cwd);
+            }
+
+            if self.stdin.is_some() {
+                debug_command.field("stdin", &self.stdin);
+            }
+            if self.stdout.is_some() {
+                debug_command.field("stdout", &self.stdout);
+            }
+            if self.stderr.is_some() {
+                debug_command.field("stderr", &self.stderr);
+            }
+
+            debug_command.finish()
+        } else {
+            if let Some(ref cwd) = self.cwd {
+                write!(f, "cd {cwd:?} && ")?;
+            }
+            if self.env.does_clear() {
+                write!(f, "env -i ")?;
+                // Altered env vars will be printed next, that should exactly work as expected.
+            } else {
+                // Removed env vars need the command to be wrapped in `env`.
+                let mut any_removed = false;
+                for (key, value_opt) in self.get_envs() {
+                    if value_opt.is_none() {
+                        if !any_removed {
+                            write!(f, "env ")?;
+                            any_removed = true;
+                        }
+                        write!(f, "-u {} ", key.to_string_lossy())?;
+                    }
+                }
+            }
+            // Altered env vars can just be added in front of the program.
+            for (key, value_opt) in self.get_envs() {
+                if let Some(value) = value_opt {
+                    write!(f, "{}={value:?} ", key.to_string_lossy())?;
+                }
+            }
+            if self.program != self.args[0] {
+                write!(f, "[{:?}] ", self.program)?;
+            }
+            write!(f, "{:?}", self.args[0])?;
+
+            for arg in &self.args[1..] {
+                write!(f, " {:?}", arg)?;
+            }
+            Ok(())
+        }
     }
 }
 
@@ -217,23 +298,30 @@ impl Process {
 }
 
 pub struct CommandArgs<'a> {
-    _p: PhantomData<&'a ()>,
+    iter: crate::slice::Iter<'a, OsString>,
 }
 
 impl<'a> Iterator for CommandArgs<'a> {
     type Item = &'a OsStr;
     fn next(&mut self) -> Option<&'a OsStr> {
-        None
+        self.iter.next().map(|os| &**os)
     }
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(0))
+        self.iter.size_hint()
     }
 }
 
-impl<'a> ExactSizeIterator for CommandArgs<'a> {}
+impl<'a> ExactSizeIterator for CommandArgs<'a> {
+    fn len(&self) -> usize {
+        self.iter.len()
+    }
+    fn is_empty(&self) -> bool {
+        self.iter.is_empty()
+    }
+}
 
 impl<'a> fmt::Debug for CommandArgs<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_list().finish()
+        f.debug_list().entries(self.iter.clone()).finish()
     }
 }
diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs
index 90e1bff52a3..555ad581b85 100644
--- a/library/std/src/sys/pal/windows/api.rs
+++ b/library/std/src/sys/pal/windows/api.rs
@@ -34,6 +34,102 @@ use core::ptr::addr_of;
 
 use super::c;
 
+/// Creates a null-terminated UTF-16 string from a str.
+pub macro wide_str($str:literal) {{
+    const _: () = {
+        if core::slice::memchr::memchr(0, $str.as_bytes()).is_some() {
+            panic!("null terminated strings cannot contain interior nulls");
+        }
+    };
+    crate::sys::pal::windows::api::utf16!(concat!($str, '\0'))
+}}
+
+/// Creates a UTF-16 string from a str without null termination.
+pub macro utf16($str:expr) {{
+    const UTF8: &str = $str;
+    const UTF16_LEN: usize = crate::sys::pal::windows::api::utf16_len(UTF8);
+    const UTF16: [u16; UTF16_LEN] = crate::sys::pal::windows::api::to_utf16(UTF8);
+    &UTF16
+}}
+
+#[cfg(test)]
+mod tests;
+
+/// Gets the UTF-16 length of a UTF-8 string, for use in the wide_str macro.
+pub const fn utf16_len(s: &str) -> usize {
+    let s = s.as_bytes();
+    let mut i = 0;
+    let mut len = 0;
+    while i < s.len() {
+        // the length of a UTF-8 encoded code-point is given by the number of
+        // leading ones, except in the case of ASCII.
+        let utf8_len = match s[i].leading_ones() {
+            0 => 1,
+            n => n as usize,
+        };
+        i += utf8_len;
+        // Note that UTF-16 surrogates (U+D800 to U+DFFF) are not encodable as UTF-8,
+        // so (unlike with WTF-8) we don't have to worry about how they'll get re-encoded.
+        len += if utf8_len < 4 { 1 } else { 2 };
+    }
+    len
+}
+
+/// Const convert UTF-8 to UTF-16, for use in the wide_str macro.
+///
+/// Note that this is designed for use in const contexts so is not optimized.
+pub const fn to_utf16<const UTF16_LEN: usize>(s: &str) -> [u16; UTF16_LEN] {
+    let mut output = [0_u16; UTF16_LEN];
+    let mut pos = 0;
+    let s = s.as_bytes();
+    let mut i = 0;
+    while i < s.len() {
+        match s[i].leading_ones() {
+            // Decode UTF-8 based on its length.
+            // See https://en.wikipedia.org/wiki/UTF-8
+            0 => {
+                // ASCII is the same in both encodings
+                output[pos] = s[i] as u16;
+                i += 1;
+                pos += 1;
+            }
+            2 => {
+                // Bits: 110xxxxx 10xxxxxx
+                output[pos] = ((s[i] as u16 & 0b11111) << 6) | (s[i + 1] as u16 & 0b111111);
+                i += 2;
+                pos += 1;
+            }
+            3 => {
+                // Bits: 1110xxxx 10xxxxxx 10xxxxxx
+                output[pos] = ((s[i] as u16 & 0b1111) << 12)
+                    | ((s[i + 1] as u16 & 0b111111) << 6)
+                    | (s[i + 2] as u16 & 0b111111);
+                i += 3;
+                pos += 1;
+            }
+            4 => {
+                // Bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+                let mut c = ((s[i] as u32 & 0b111) << 18)
+                    | ((s[i + 1] as u32 & 0b111111) << 12)
+                    | ((s[i + 2] as u32 & 0b111111) << 6)
+                    | (s[i + 3] as u32 & 0b111111);
+                // re-encode as UTF-16 (see https://en.wikipedia.org/wiki/UTF-16)
+                // - Subtract 0x10000 from the code point
+                // - For the high surrogate, shift right by 10 then add 0xD800
+                // - For the low surrogate, take the low 10 bits then add 0xDC00
+                c -= 0x10000;
+                output[pos] = ((c >> 10) + 0xD800) as u16;
+                output[pos + 1] = ((c & 0b1111111111) + 0xDC00) as u16;
+                i += 4;
+                pos += 2;
+            }
+            // valid UTF-8 cannot have any other values
+            _ => unreachable!(),
+        }
+    }
+    output
+}
+
 /// Helper method for getting the size of `T` as a u32.
 /// Errors at compile time if the size would overflow.
 ///
diff --git a/library/std/src/sys/pal/windows/api/tests.rs b/library/std/src/sys/pal/windows/api/tests.rs
new file mode 100644
index 00000000000..fab022c7b93
--- /dev/null
+++ b/library/std/src/sys/pal/windows/api/tests.rs
@@ -0,0 +1,16 @@
+use crate::sys::pal::windows::api::{utf16, wide_str};
+
+macro_rules! check_utf16 {
+    ($str:literal) => {{
+        assert!(wide_str!($str).iter().copied().eq($str.encode_utf16().chain([0])));
+        assert!(utf16!($str).iter().copied().eq($str.encode_utf16()));
+    }};
+}
+
+#[test]
+fn test_utf16_macros() {
+    check_utf16!("hello world");
+    check_utf16!("€4.50");
+    check_utf16!("𨉟呐㗂越");
+    check_utf16!("Pchnąć w tę łódź jeża lub ośm skrzyń fig");
+}
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index 2ecfe088d10..5098c05196e 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -7,7 +7,7 @@
 mod tests;
 
 use super::os::current_exe;
-use crate::ffi::OsString;
+use crate::ffi::{OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::num::NonZero;
@@ -17,6 +17,7 @@ use crate::sys::path::get_long_path;
 use crate::sys::process::ensure_no_nuls;
 use crate::sys::{c, to_u16s};
 use crate::sys_common::wstr::WStrUnits;
+use crate::sys_common::AsInner;
 use crate::vec;
 
 use crate::iter;
@@ -262,16 +263,92 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i
     Ok(())
 }
 
+fn append_bat_arg(cmd: &mut Vec<u16>, arg: &OsStr, mut quote: bool) -> io::Result<()> {
+    ensure_no_nuls(arg)?;
+    // If an argument has 0 characters then we need to quote it to ensure
+    // that it actually gets passed through on the command line or otherwise
+    // it will be dropped entirely when parsed on the other end.
+    //
+    // We also need to quote the argument if it ends with `\` to guard against
+    // bat usage such as `"%~2"` (i.e. force quote arguments) otherwise a
+    // trailing slash will escape the closing quote.
+    if arg.is_empty() || arg.as_encoded_bytes().last() == Some(&b'\\') {
+        quote = true;
+    }
+    for cp in arg.as_inner().inner.code_points() {
+        if let Some(cp) = cp.to_char() {
+            // Rather than trying to find every ascii symbol that must be quoted,
+            // we assume that all ascii symbols must be quoted unless they're known to be good.
+            // We also quote Unicode control blocks for good measure.
+            // Note an unquoted `\` is fine so long as the argument isn't otherwise quoted.
+            static UNQUOTED: &str = r"#$*+-./:?@\_";
+            let ascii_needs_quotes =
+                cp.is_ascii() && !(cp.is_ascii_alphanumeric() || UNQUOTED.contains(cp));
+            if ascii_needs_quotes || cp.is_control() {
+                quote = true;
+            }
+        }
+    }
+
+    if quote {
+        cmd.push('"' as u16);
+    }
+    // Loop through the string, escaping `\` only if followed by `"`.
+    // And escaping `"` by doubling them.
+    let mut backslashes: usize = 0;
+    for x in arg.encode_wide() {
+        if x == '\\' as u16 {
+            backslashes += 1;
+        } else {
+            if x == '"' as u16 {
+                // Add n backslashes to total 2n before internal `"`.
+                cmd.extend((0..backslashes).map(|_| '\\' as u16));
+                // Appending an additional double-quote acts as an escape.
+                cmd.push(b'"' as u16)
+            } else if x == '%' as u16 || x == '\r' as u16 {
+                // yt-dlp hack: replaces `%` with `%%cd:~,%` to stop %VAR% being expanded as an environment variable.
+                //
+                // # Explanation
+                //
+                // cmd supports extracting a substring from a variable using the following syntax:
+                //     %variable:~start_index,end_index%
+                //
+                // In the above command `cd` is used as the variable and the start_index and end_index are left blank.
+                // `cd` is a built-in variable that dynamically expands to the current directory so it's always available.
+                // Explicitly omitting both the start and end index creates a zero-length substring.
+                //
+                // Therefore it all resolves to nothing. However, by doing this no-op we distract cmd.exe
+                // from potentially expanding %variables% in the argument.
+                cmd.extend_from_slice(&[
+                    '%' as u16, '%' as u16, 'c' as u16, 'd' as u16, ':' as u16, '~' as u16,
+                    ',' as u16,
+                ]);
+            }
+            backslashes = 0;
+        }
+        cmd.push(x);
+    }
+    if quote {
+        // Add n backslashes to total 2n before ending `"`.
+        cmd.extend((0..backslashes).map(|_| '\\' as u16));
+        cmd.push('"' as u16);
+    }
+    Ok(())
+}
+
 pub(crate) fn make_bat_command_line(
     script: &[u16],
     args: &[Arg],
     force_quotes: bool,
 ) -> io::Result<Vec<u16>> {
+    const INVALID_ARGUMENT_ERROR: io::Error =
+        io::const_io_error!(io::ErrorKind::InvalidInput, r#"batch file arguments are invalid"#);
     // Set the start of the command line to `cmd.exe /c "`
     // It is necessary to surround the command in an extra pair of quotes,
     // hence the trailing quote here. It will be closed after all arguments
     // have been added.
-    let mut cmd: Vec<u16> = "cmd.exe /d /c \"".encode_utf16().collect();
+    // Using /e:ON enables "command extensions" which is essential for the `%` hack to work.
+    let mut cmd: Vec<u16> = "cmd.exe /e:ON /v:OFF /d /c \"".encode_utf16().collect();
 
     // Push the script name surrounded by its quote pair.
     cmd.push(b'"' as u16);
@@ -291,18 +368,22 @@ pub(crate) fn make_bat_command_line(
     // reconstructed by the batch script by default.
     for arg in args {
         cmd.push(' ' as u16);
-        // Make sure to always quote special command prompt characters, including:
-        // * Characters `cmd /?` says require quotes.
-        // * `%` for environment variables, as in `%TMP%`.
-        // * `|<>` pipe/redirect characters.
-        const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
-        let force_quotes = match arg {
-            Arg::Regular(arg) if !force_quotes => {
-                arg.as_encoded_bytes().iter().any(|c| SPECIAL.contains(c))
+        match arg {
+            Arg::Regular(arg_os) => {
+                let arg_bytes = arg_os.as_encoded_bytes();
+                // Disallow \r and \n as they may truncate the arguments.
+                const DISALLOWED: &[u8] = b"\r\n";
+                if arg_bytes.iter().any(|c| DISALLOWED.contains(c)) {
+                    return Err(INVALID_ARGUMENT_ERROR);
+                }
+                append_bat_arg(&mut cmd, arg_os, force_quotes)?;
+            }
+            _ => {
+                // Raw arguments are passed on as-is.
+                // It's the user's responsibility to properly handle arguments in this case.
+                append_arg(&mut cmd, arg, force_quotes)?;
             }
-            _ => force_quotes,
         };
-        append_arg(&mut cmd, arg, force_quotes)?;
     }
 
     // Close the quote we left opened earlier.
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 6a561518fad..a734c2bd4c7 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -5,6 +5,7 @@ use crate::io::ErrorKind;
 use crate::mem::MaybeUninit;
 use crate::os::windows::ffi::{OsStrExt, OsStringExt};
 use crate::path::PathBuf;
+use crate::sys::pal::windows::api::wide_str;
 use crate::time::Duration;
 
 pub use self::rand::hashmap_random_keys;
@@ -12,6 +13,8 @@ pub use self::rand::hashmap_random_keys;
 #[macro_use]
 pub mod compat;
 
+mod api;
+
 pub mod alloc;
 pub mod args;
 pub mod c;
@@ -41,8 +44,6 @@ cfg_if::cfg_if! {
     }
 }
 
-mod api;
-
 /// Map a Result<T, WinError> to io::Result<T>.
 trait IoResult<T> {
     fn io_result(self) -> crate::io::Result<T>;
@@ -60,7 +61,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
 
     // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
     // exists, we have to call it ourselves.
-    thread::Thread::set_name(&c"main");
+    thread::Thread::set_name_wide(wide_str!("main"));
 }
 
 // SAFETY: must be called only once during runtime cleanup.
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index c0c63c3340f..9b1c5b34bbf 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -59,13 +59,17 @@ impl Thread {
     pub fn set_name(name: &CStr) {
         if let Ok(utf8) = name.to_str() {
             if let Ok(utf16) = to_u16s(utf8) {
-                unsafe {
-                    c::SetThreadDescription(c::GetCurrentThread(), utf16.as_ptr());
-                };
+                Self::set_name_wide(&utf16)
             };
         };
     }
 
+    pub fn set_name_wide(name: &[u16]) {
+        unsafe {
+            c::SetThreadDescription(c::GetCurrentThread(), name.as_ptr());
+        };
+    }
+
     pub fn join(self) {
         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
         if rc == c::WAIT_FAILED {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index fc6f51e8272..4cab2d64257 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -231,7 +231,7 @@ impl<'tcx> Context<'tcx> {
                 rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo),
             };
             let mut page_buffer = Buffer::html();
-            print_item(self, it, &mut page_buffer, &page);
+            print_item(self, it, &mut page_buffer);
             layout::render(
                 &clone_shared.layout,
                 &page,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index fbb521a6188..168db5c0948 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -31,11 +31,10 @@ use crate::html::format::{
     display_fn, join_with_double_colon, print_abi_with_space, print_constness_with_space,
     print_where_clause, visibility_print_with_space, Buffer, Ending, PrintWithSpace,
 };
-use crate::html::layout::Page;
+use crate::html::highlight;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 use crate::html::render::{document_full, document_item_info};
 use crate::html::url_parts_builder::UrlPartsBuilder;
-use crate::html::{highlight, static_files};
 
 use askama::Template;
 use itertools::Itertools;
@@ -157,8 +156,6 @@ struct PathComponent {
 #[derive(Template)]
 #[template(path = "print_item.html")]
 struct ItemVars<'a> {
-    static_root_path: &'a str,
-    clipboard_svg: &'static static_files::StaticFile,
     typ: &'a str,
     name: &'a str,
     item_type: &'a str,
@@ -178,12 +175,7 @@ fn print_where_clause_and_check<'a, 'tcx: 'a>(
     len_before != buffer.len()
 }
 
-pub(super) fn print_item(
-    cx: &mut Context<'_>,
-    item: &clean::Item,
-    buf: &mut Buffer,
-    page: &Page<'_>,
-) {
+pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buffer) {
     debug_assert!(!item.is_stripped());
     let typ = match *item.kind {
         clean::ModuleItem(_) => {
@@ -252,8 +244,6 @@ pub(super) fn print_item(
     };
 
     let item_vars = ItemVars {
-        static_root_path: &page.get_static_root_path(),
-        clipboard_svg: &static_files::STATIC_FILES.clipboard_svg,
         typ,
         name: item.name.as_ref().unwrap().as_str(),
         item_type: &item.type_().to_string(),
@@ -1237,22 +1227,18 @@ fn item_opaque_ty(
 }
 
 fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
-    fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
-        wrap_item(w, |w| {
-            write!(
-                w,
-                "{attrs}{vis}type {name}{generics}{where_clause} = {type_};",
-                attrs = render_attributes_in_pre(it, "", cx),
-                vis = visibility_print_with_space(it, cx),
-                name = it.name.unwrap(),
-                generics = t.generics.print(cx),
-                where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
-                type_ = t.type_.print(cx),
-            );
-        });
-    }
-
-    write_content(w, cx, it, t);
+    wrap_item(w, |w| {
+        write!(
+            w,
+            "{attrs}{vis}type {name}{generics}{where_clause} = {type_};",
+            attrs = render_attributes_in_pre(it, "", cx),
+            vis = visibility_print_with_space(it, cx),
+            name = it.name.unwrap(),
+            generics = t.generics.print(cx),
+            where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
+            type_ = t.type_.print(cx),
+        );
+    });
 
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
 
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 0bb073b1cea..e9c687b42fa 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1603,6 +1603,16 @@ a.tooltip:hover::after {
 	border-color: var(--settings-button-border-focus);
 }
 
+#settings-menu > a {
+	line-height: 0;
+	font-size: 0;
+}
+#settings-menu > a:before {
+	content: url('wheel-63255fc4502dca9a.svg');
+	width: 22px;
+	height: 22px;
+}
+
 #sidebar-button > a:before {
 	content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" \
 		fill="none" stroke="black">\
@@ -1622,11 +1632,17 @@ a.tooltip:hover::after {
 	padding-left: 2px;
 	border: 0;
 	width: 33px;
+	line-height: 0;
+	font-size: 0;
 }
-#copy-path > img {
+
+#copy-path:before {
 	filter: var(--copy-path-img-filter);
+	content: url('clipboard-24048e6d87f63d07.svg');
+	width: 19px;
+	height: 18px;
 }
-#copy-path:hover > img {
+#copy-path:hover:before {
 	filter: var(--copy-path-img-hover-filter);
 }
 
diff --git a/src/librustdoc/html/static/images/clipboard.svg b/src/librustdoc/html/static/images/clipboard.svg
index 8adbd996304..e437c83fb6b 100644
--- a/src/librustdoc/html/static/images/clipboard.svg
+++ b/src/librustdoc/html/static/images/clipboard.svg
@@ -1 +1 @@
-<svg width="24" height="25" viewBox="0 0 24 25" xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard"><path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/><path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/></svg>
+<svg width="19" height="18" viewBox="0 0 24 25" xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard"><path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/><path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/></svg>
diff --git a/src/librustdoc/html/static/images/favicon-16x16.png b/src/librustdoc/html/static/images/favicon-16x16.png
deleted file mode 100644
index ea4b45cae16..00000000000
--- a/src/librustdoc/html/static/images/favicon-16x16.png
+++ /dev/null
Binary files differdiff --git a/src/librustdoc/html/static/images/wheel.svg b/src/librustdoc/html/static/images/wheel.svg
index 83c07f63d10..ba30f13dd58 100644
--- a/src/librustdoc/html/static/images/wheel.svg
+++ b/src/librustdoc/html/static/images/wheel.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="27.434" height="29.5" enable-background="new 0 0 27.434 29.5" viewBox="0 0 27.434 29.5"><path d="M27.316 18.39a2.696 2.696 0 0 0-.98-1.46 1.62 1.62 0 0 1-.016-.762l.035-.176v-1.191c0-1.246-.003-1.278-.046-1.473a1.717 1.717 0 0 1 .007-.805c.477-.343.829-.859.997-1.472.257-.957.074-2.094-.508-3.117l-.594-1.032c-.746-1.304-1.965-2.117-3.18-2.117-.379 0-.75.078-1.086.235a1.958 1.958 0 0 1-.855-.391l-.102-.082-.117-.063-1.855-1.07-.094-.055-.106-.043c-.378-.156-.66-.41-.77-.554C17.919 1.172 16.349 0 14.297 0h-1.155c-2.043 0-3.61 1.152-3.75 2.723-.114.14-.391.382-.758.527l-.102.04-.094.05-1.94 1.066-.134.074-.117.094a2.019 2.019 0 0 1-.832.403 2.518 2.518 0 0 0-1.008-.211c-1.199 0-2.414.82-3.168 2.14l-.59 1.032c-.41.718-.64 1.523-.64 2.257-.004.953.36 1.758 1.012 2.258.035.152.058.445-.016.785-.04.168-.063.282-.063 1.563 0 1.148 0 1.148.016 1.261l.008.075.015.074c.075.344.047.64.012.8-.644.5-1.004 1.302-.992 2.259.008.726.238 1.52.648 2.242l.59 1.027c.758 1.332 1.965 2.16 3.149 2.16.324 0 .644-.062.937-.187.168.039.492.156.813.418l.11.086.124.07 2.047 1.156.102.059.105.043c.363.144.648.379.766.52.164 1.519 1.718 2.632 3.746 2.632h1.156c2.035 0 3.598-1.133 3.746-2.672.117-.144.402-.394.773-.55l.114-.047.101-.063 1.961-1.156.106-.063.097-.078c.309-.246.653-.37.832-.398.313.136.66.21 1.016.21 1.2 0 2.41-.82 3.164-2.14l.594-1.031c.59-1.028.777-2.164.52-3.117Zm-2.043 2.247-.59 1.031c-.437.766-1.105 1.25-1.636 1.25a.7.7 0 0 1-.371-.094 1.146 1.146 0 0 0-.567-.129c-.593 0-1.382.297-2.007.797l-1.961 1.156c-1.016.426-1.848 1.293-1.848 1.93 0 .64-.898 1.16-1.996 1.16H13.14c-1.102 0-2-.515-2-1.14 0-.63-.832-1.477-1.852-1.887l-2.047-1.16c-.637-.512-1.426-.813-2.008-.813-.199 0-.379.035-.515.114a.648.648 0 0 1-.332.085c-.52 0-1.18-.5-1.621-1.273l-.59-1.031c-.543-.953-.555-1.98-.024-2.285.532-.305.782-1.434.551-2.504V14.8c0-1.09.02-1.18.02-1.18.238-1.074-.008-2.203-.551-2.516-.54-.304-.54-1.34.008-2.293l.59-1.03c.437-.766 1.101-1.255 1.636-1.255a.73.73 0 0 1 .364.094c.152.086.343.125.566.125.594 0 1.379-.297 2.004-.793l1.945-1.066c1.02-.407 1.856-1.278 1.856-1.934 0-.656.898-1.191 2-1.191h1.156c1.098 0 1.996.543 1.996 1.21 0 .669.832 1.555 1.848 1.973L20 6.012c.617.492 1.402.777 2.012.777.242 0 .453-.047.62-.14a.79.79 0 0 1 .403-.102c.55 0 1.223.476 1.652 1.23l.59 1.032c.543.953.52 2.004-.062 2.336-.574.332-.86 1.48-.625 2.554 0 0 .008.04.008 1.102v1.011c-.215 1.051.07 2.176.636 2.5.567.325.586 1.368.04 2.325Zm0 0"/><path d="M13.61 7.61a7.084 7.084 0 0 0-7.083 7.085 7.085 7.085 0 1 0 14.168 0A7.088 7.088 0 0 0 13.61 7.61Zm0 12.41a5.33 5.33 0 0 1-5.325-5.325 5.33 5.33 0 0 1 5.324-5.32 5.327 5.327 0 0 1 5.325 5.32 5.328 5.328 0 0 1-5.325 5.325Zm0 0"/><path d="M13.684 9.906a4.722 4.722 0 0 0-4.72 4.719 4.722 4.722 0 0 0 4.72 4.719 4.724 4.724 0 0 0 4.714-4.719 4.724 4.724 0 0 0-4.714-4.719Zm0 7.676a2.954 2.954 0 1 1 0-5.91 2.953 2.953 0 0 1 2.953 2.953 2.957 2.957 0 0 1-2.953 2.957Zm0 0"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" enable-background="new 0 0 22 22" viewBox="0 0 27.434 29.5"><path d="M27.316 18.39a2.696 2.696 0 0 0-.98-1.46 1.62 1.62 0 0 1-.016-.762l.035-.176v-1.191c0-1.246-.003-1.278-.046-1.473a1.717 1.717 0 0 1 .007-.805c.477-.343.829-.859.997-1.472.257-.957.074-2.094-.508-3.117l-.594-1.032c-.746-1.304-1.965-2.117-3.18-2.117-.379 0-.75.078-1.086.235a1.958 1.958 0 0 1-.855-.391l-.102-.082-.117-.063-1.855-1.07-.094-.055-.106-.043c-.378-.156-.66-.41-.77-.554C17.919 1.172 16.349 0 14.297 0h-1.155c-2.043 0-3.61 1.152-3.75 2.723-.114.14-.391.382-.758.527l-.102.04-.094.05-1.94 1.066-.134.074-.117.094a2.019 2.019 0 0 1-.832.403 2.518 2.518 0 0 0-1.008-.211c-1.199 0-2.414.82-3.168 2.14l-.59 1.032c-.41.718-.64 1.523-.64 2.257-.004.953.36 1.758 1.012 2.258.035.152.058.445-.016.785-.04.168-.063.282-.063 1.563 0 1.148 0 1.148.016 1.261l.008.075.015.074c.075.344.047.64.012.8-.644.5-1.004 1.302-.992 2.259.008.726.238 1.52.648 2.242l.59 1.027c.758 1.332 1.965 2.16 3.149 2.16.324 0 .644-.062.937-.187.168.039.492.156.813.418l.11.086.124.07 2.047 1.156.102.059.105.043c.363.144.648.379.766.52.164 1.519 1.718 2.632 3.746 2.632h1.156c2.035 0 3.598-1.133 3.746-2.672.117-.144.402-.394.773-.55l.114-.047.101-.063 1.961-1.156.106-.063.097-.078c.309-.246.653-.37.832-.398.313.136.66.21 1.016.21 1.2 0 2.41-.82 3.164-2.14l.594-1.031c.59-1.028.777-2.164.52-3.117Zm-2.043 2.247-.59 1.031c-.437.766-1.105 1.25-1.636 1.25a.7.7 0 0 1-.371-.094 1.146 1.146 0 0 0-.567-.129c-.593 0-1.382.297-2.007.797l-1.961 1.156c-1.016.426-1.848 1.293-1.848 1.93 0 .64-.898 1.16-1.996 1.16H13.14c-1.102 0-2-.515-2-1.14 0-.63-.832-1.477-1.852-1.887l-2.047-1.16c-.637-.512-1.426-.813-2.008-.813-.199 0-.379.035-.515.114a.648.648 0 0 1-.332.085c-.52 0-1.18-.5-1.621-1.273l-.59-1.031c-.543-.953-.555-1.98-.024-2.285.532-.305.782-1.434.551-2.504V14.8c0-1.09.02-1.18.02-1.18.238-1.074-.008-2.203-.551-2.516-.54-.304-.54-1.34.008-2.293l.59-1.03c.437-.766 1.101-1.255 1.636-1.255a.73.73 0 0 1 .364.094c.152.086.343.125.566.125.594 0 1.379-.297 2.004-.793l1.945-1.066c1.02-.407 1.856-1.278 1.856-1.934 0-.656.898-1.191 2-1.191h1.156c1.098 0 1.996.543 1.996 1.21 0 .669.832 1.555 1.848 1.973L20 6.012c.617.492 1.402.777 2.012.777.242 0 .453-.047.62-.14a.79.79 0 0 1 .403-.102c.55 0 1.223.476 1.652 1.23l.59 1.032c.543.953.52 2.004-.062 2.336-.574.332-.86 1.48-.625 2.554 0 0 .008.04.008 1.102v1.011c-.215 1.051.07 2.176.636 2.5.567.325.586 1.368.04 2.325Zm0 0"/><path d="M13.61 7.61a7.084 7.084 0 0 0-7.083 7.085 7.085 7.085 0 1 0 14.168 0A7.088 7.088 0 0 0 13.61 7.61Zm0 12.41a5.33 5.33 0 0 1-5.325-5.325 5.33 5.33 0 0 1 5.324-5.32 5.327 5.327 0 0 1 5.325 5.32 5.328 5.328 0 0 1-5.325 5.325Zm0 0"/><path d="M13.684 9.906a4.722 4.722 0 0 0-4.72 4.719 4.722 4.722 0 0 0 4.72 4.719 4.724 4.724 0 0 0 4.714-4.719 4.724 4.724 0 0 0-4.714-4.719Zm0 7.676a2.954 2.954 0 1 1 0-5.91 2.953 2.953 0 0 1 2.953 2.953 2.957 2.957 0 0 1-2.953 2.957Zm0 0"/></svg>
\ No newline at end of file
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index ca9a78f51b3..d8874c2fda0 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -106,7 +106,6 @@ static_files! {
     license_mit => "static/LICENSE-MIT.txt",
     rust_logo_svg => "static/images/rust-logo.svg",
     rust_favicon_svg => "static/images/favicon.svg",
-    rust_favicon_png_16 => "static/images/favicon-16x16.png",
     rust_favicon_png_32 => "static/images/favicon-32x32.png",
     fira_sans_regular => "static/fonts/FiraSans-Regular.woff2",
     fira_sans_medium => "static/fonts/FiraSans-Medium.woff2",
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 0f3debae66c..0941f758de5 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -6,13 +6,10 @@
     <meta name="generator" content="rustdoc"> {# #}
     <meta name="description" content="{{page.description}}"> {# #}
     <title>{{page.title}}</title> {# #}
-    <script> if (window.location.protocol !== "file:") document.write(` {# Hack to skip preloading fonts locally - see #98769 #}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_serif_4_regular}}"> {# #}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.fira_sans_regular}}"> {# #}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.fira_sans_medium}}"> {# #}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_code_pro_regular}}"> {# #}
-    <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_code_pro_semibold}}"> {# #}
-    `)</script> {# #}
+    <script>if(window.location.protocol!=="file:") {# Hack to skip preloading fonts locally - see #98769 #}
+    for(f of "{{files.source_serif_4_regular}},{{files.fira_sans_regular}},{{files.fira_sans_medium}},{{files.source_code_pro_regular}},{{files.source_code_pro_semibold}}".split(",")) {# #}
+     document.write(`<link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}${f}">`) {# #}
+    </script> {# #}
     <link rel="stylesheet" {#+ #}
           href="{{static_root_path|safe}}{{files.normalize_css}}"> {# #}
     <link rel="stylesheet" {#+ #}
@@ -62,8 +59,6 @@
         <link rel="icon" href="{{layout.favicon}}"> {# #}
     {% else %}
         <link rel="alternate icon" type="image/png" {#+ #}
-            href="{{static_root_path|safe}}{{files.rust_favicon_png_16}}"> {# #}
-        <link rel="alternate icon" type="image/png" {#+ #}
             href="{{static_root_path|safe}}{{files.rust_favicon_png_32}}"> {# #}
         <link rel="icon" type="image/svg+xml" {#+ #}
             href="{{static_root_path|safe}}{{files.rust_favicon_svg}}"> {# #}
@@ -114,13 +109,13 @@
         <div class="version">{{+ display_krate_version_extra}}</div> {# #}
         {% endif %}
         {% else %}
-        <div class="src-sidebar-title">
+        <div class="src-sidebar-title"> {# #}
             <h2>Files</h2> {# #}
         </div> {# #}
         {% endif %}
         {{ sidebar|safe }}
     </nav> {# #}
-    <div class="sidebar-resizer"></div>
+    <div class="sidebar-resizer"></div> {# #}
     <main> {# #}
         {% if page.css_class != "src" %}<div class="width-limiter">{% endif %}
             <nav class="sub"> {# #}
@@ -142,8 +137,7 @@
                     </div> {# #}
                     <div id="settings-menu" tabindex="-1"> {# #}
                         <a href="{{page.root_path|safe}}settings.html" title="settings"> {# #}
-                            <img width="22" height="22" alt="Change settings" {#+ #}
-                            src="{{static_root_path|safe}}{{files.wheel_svg}}"> {# #}
+                            Settings {# #}
                         </a> {# #}
                     </div> {# #}
                 </form> {# #}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index 1d215c26968..76e770453b6 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -7,9 +7,7 @@
         {% endfor %}
         <a class="{{item_type}}" href="#">{{name}}</a> {# #}
         <button id="copy-path" title="Copy item path to clipboard"> {# #}
-        <img src="{{static_root_path|safe}}{{clipboard_svg}}" {#+ #}
-                width="19" height="18" {#+ #}
-                alt="Copy item path"> {# #}
+            Copy item path {# #}
         </button> {# #}
     </h1> {# #}
     <span class="out-of-band">
diff --git a/src/librustdoc/html/templates/sidebar.html b/src/librustdoc/html/templates/sidebar.html
index d982134181c..3251b4c14c9 100644
--- a/src/librustdoc/html/templates/sidebar.html
+++ b/src/librustdoc/html/templates/sidebar.html
@@ -5,7 +5,7 @@
 {% endif %}
 <div class="sidebar-elems">
     {% if is_crate %}
-        <ul class="block">
+        <ul class="block"> {# #}
             <li><a id="all-types" href="all.html">All Items</a></li> {# #}
         </ul>
     {% endif %}
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index a60a40a2a47..2bb63ec2b04 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -294,8 +294,7 @@ fn elision_suggestions(
                         let span = cx
                             .sess()
                             .source_map()
-                            .span_extend_while(usage.ident.span, |ch| ch.is_ascii_whitespace())
-                            .unwrap_or(usage.ident.span);
+                            .span_extend_while_whitespace(usage.ident.span);
 
                         (span, String::new())
                     },
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 626841cb1bd..ec944cb7fb4 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -819,6 +819,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "needs-dynamic-linking",
     "needs-git-hash",
     "needs-llvm-components",
+    "needs-matching-clang",
     "needs-profiler-support",
     "needs-relocation-model-pic",
     "needs-run-enabled",
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index 217da36ccc7..5a5b008a7cb 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -86,6 +86,18 @@ impl Rustc {
         self
     }
 
+    /// This flag defers LTO optimizations to the linker.
+    pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self {
+        self.cmd.arg(format!("-Clinker-plugin-lto={option}"));
+        self
+    }
+
+    /// Specify what happens when the code panics.
+    pub fn panic(&mut self, option: &str) -> &mut Self {
+        self.cmd.arg(format!("-Cpanic={option}"));
+        self
+    }
+
     /// Specify number of codegen units
     pub fn codegen_units(&mut self, units: usize) -> &mut Self {
         self.cmd.arg(format!("-Ccodegen-units={units}"));
@@ -183,6 +195,18 @@ impl Rustc {
         output
     }
 
+    #[track_caller]
+    pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
+        let caller_location = std::panic::Location::caller();
+        let caller_line_number = caller_location.line();
+
+        let output = self.cmd.output().unwrap();
+        if output.status.code().unwrap() != code {
+            handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
+        }
+        output
+    }
+
     /// Inspect what the underlying [`Command`] is up to the current construction.
     pub fn inspect(&mut self, f: impl FnOnce(&Command)) -> &mut Self {
         f(&self.cmd);
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
index 9607ff02f96..1fb4b589d76 100644
--- a/src/tools/run-make-support/src/rustdoc.rs
+++ b/src/tools/run-make-support/src/rustdoc.rs
@@ -1,4 +1,5 @@
 use std::env;
+use std::ffi::OsStr;
 use std::path::Path;
 use std::process::{Command, Output};
 
@@ -58,9 +59,8 @@ impl Rustdoc {
         self
     }
 
-    /// Fallback argument provider. Consider adding meaningfully named methods instead of using
-    /// this method.
-    pub fn arg(&mut self, arg: &str) -> &mut Self {
+    /// Generic command argument provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`.
+    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
         self.cmd.arg(arg);
         self
     }
@@ -77,4 +77,16 @@ impl Rustdoc {
         }
         output
     }
+
+    #[track_caller]
+    pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
+        let caller_location = std::panic::Location::caller();
+        let caller_line_number = caller_location.line();
+
+        let output = self.cmd.output().unwrap();
+        if output.status.code().unwrap() != code {
+            handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
+        }
+        output
+    }
 }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index dfd30d79abc..3914feb3499 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -59,7 +59,6 @@ run-make/emit/Makefile
 run-make/env-dep-info/Makefile
 run-make/error-found-staticlib-instead-crate/Makefile
 run-make/error-writing-dependencies/Makefile
-run-make/exit-code/Makefile
 run-make/export-executable-symbols/Makefile
 run-make/extern-diff-internal-name/Makefile
 run-make/extern-flag-disambiguates/Makefile
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 4fae7572ffb..78de8c0537d 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -18,7 +18,7 @@ const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 
 const ISSUES_ENTRY_LIMIT: usize = 1722;
-const ROOT_ENTRY_LIMIT: usize = 861;
+const ROOT_ENTRY_LIMIT: usize = 859;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
@@ -49,6 +49,9 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
     "tests/ui/shell-argfiles/shell-argfiles-badquotes.args", // passing args via a file
     "tests/ui/shell-argfiles/shell-argfiles-via-argfile-shell.args", // passing args via a file
     "tests/ui/shell-argfiles/shell-argfiles-via-argfile.args", // passing args via a file
+    "tests/ui/std/windows-bat-args1.bat", // tests escaping arguments through batch files
+    "tests/ui/std/windows-bat-args2.bat", // tests escaping arguments through batch files
+    "tests/ui/std/windows-bat-args3.bat", // tests escaping arguments through batch files
 ];
 
 fn check_entries(tests_path: &Path, bad: &mut bool) {
diff --git a/tests/codegen/riscv-target-abi.rs b/tests/codegen/riscv-target-abi.rs
new file mode 100644
index 00000000000..5d545af9c76
--- /dev/null
+++ b/tests/codegen/riscv-target-abi.rs
@@ -0,0 +1,20 @@
+//@ revisions:riscv64gc riscv32gc riscv32imac
+
+//@[riscv64gc] compile-flags: --target=riscv64gc-unknown-linux-gnu
+//@[riscv64gc] needs-llvm-components: riscv
+// riscv64gc: !{i32 1, !"target-abi", !"lp64d"}
+
+//@[riscv32gc] compile-flags: --target=riscv32gc-unknown-linux-musl
+//@[riscv32gc] needs-llvm-components: riscv
+// riscv32gc: !{i32 1, !"target-abi", !"ilp32d"}
+
+//@[riscv32imac] compile-flags: --target=riscv32imac-unknown-none-elf
+//@[riscv32imac] needs-llvm-components: riscv
+// riscv32imac-NOT: !"target-abi"
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
diff --git a/tests/run-make/cross-lang-lto-riscv-abi/cstart.c b/tests/run-make/cross-lang-lto-riscv-abi/cstart.c
new file mode 100644
index 00000000000..660469b75a8
--- /dev/null
+++ b/tests/run-make/cross-lang-lto-riscv-abi/cstart.c
@@ -0,0 +1,5 @@
+extern void hello();
+
+void _start() {
+    hello();
+}
diff --git a/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs b/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs
new file mode 100644
index 00000000000..c31cf27f9ae
--- /dev/null
+++ b/tests/run-make/cross-lang-lto-riscv-abi/riscv-xlto.rs
@@ -0,0 +1,9 @@
+#![allow(internal_features)]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[no_mangle]
+pub fn hello() {}
diff --git a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
new file mode 100644
index 00000000000..2f13cf17169
--- /dev/null
+++ b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs
@@ -0,0 +1,74 @@
+//! Make sure that cross-language LTO works on riscv targets,
+//! which requires extra abi metadata to be emitted.
+//@ needs-matching-clang
+//@ needs-llvm-components riscv
+extern crate run_make_support;
+
+use run_make_support::{bin_name, rustc, tmp_dir};
+use std::{
+    env,
+    path::PathBuf,
+    process::{Command, Output},
+    str,
+};
+
+fn handle_failed_output(output: Output) {
+    eprintln!("output status: `{}`", output.status);
+    eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap());
+    eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap());
+    std::process::exit(1)
+}
+
+fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float: bool) {
+    eprintln!("Checking target {target}");
+    // Rust part
+    rustc()
+        .input("riscv-xlto.rs")
+        .crate_type("rlib")
+        .target(target)
+        .panic("abort")
+        .linker_plugin_lto("on")
+        .run();
+    // C part
+    let clang = env::var("CLANG").unwrap();
+    let mut cmd = Command::new(clang);
+    let executable = tmp_dir().join("riscv-xlto");
+    cmd.arg("-target")
+        .arg(clang_target)
+        .arg(format!("-march={carch}"))
+        .arg(format!("-flto=thin"))
+        .arg(format!("-fuse-ld=lld"))
+        .arg("-nostdlib")
+        .arg("-o")
+        .arg(&executable)
+        .arg("cstart.c")
+        .arg(tmp_dir().join("libriscv_xlto.rlib"));
+    eprintln!("{cmd:?}");
+    let output = cmd.output().unwrap();
+    if !output.status.success() {
+        handle_failed_output(output);
+    }
+    // Check that the built binary has correct float abi
+    let llvm_readobj =
+        PathBuf::from(env::var("LLVM_BIN_DIR").unwrap()).join(bin_name("llvm-readobj"));
+    let mut cmd = Command::new(llvm_readobj);
+    cmd.arg("--file-header").arg(executable);
+    eprintln!("{cmd:?}");
+    let output = cmd.output().unwrap();
+    if output.status.success() {
+        assert!(
+            !(is_double_float
+                ^ dbg!(str::from_utf8(&output.stdout).unwrap())
+                    .contains("EF_RISCV_FLOAT_ABI_DOUBLE"))
+        )
+    } else {
+        handle_failed_output(output);
+    }
+}
+
+fn main() {
+    check_target("riscv64gc-unknown-linux-gnu", "riscv64-linux-gnu", "rv64gc", true);
+    check_target("riscv64imac-unknown-none-elf", "riscv64-unknown-elf", "rv64imac", false);
+    check_target("riscv32imac-unknown-none-elf", "riscv32-unknown-elf", "rv32imac", false);
+    check_target("riscv32gc-unknown-linux-gnu", "riscv32-linux-gnu", "rv32gc", true);
+}
diff --git a/tests/run-make/exit-code/Makefile b/tests/run-make/exit-code/Makefile
deleted file mode 100644
index 155e5cd1123..00000000000
--- a/tests/run-make/exit-code/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) success.rs; [ $$? -eq 0 ]
-	$(RUSTC) --invalid-arg-foo; [ $$? -eq 1 ]
-	$(RUSTC) compile-error.rs; [ $$? -eq 1 ]
-	RUSTC_ICE=0 $(RUSTC) -Ztreat-err-as-bug compile-error.rs; [ $$? -eq 101 ]
-	$(RUSTDOC) -o $(TMPDIR)/exit-code success.rs; [ $$? -eq 0 ]
-	$(RUSTDOC) --invalid-arg-foo; [ $$? -eq 1 ]
-	$(RUSTDOC) compile-error.rs; [ $$? -eq 1 ]
-	$(RUSTDOC) lint-failure.rs; [ $$? -eq 1 ]
diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs
new file mode 100644
index 00000000000..f387626287e
--- /dev/null
+++ b/tests/run-make/exit-code/rmake.rs
@@ -0,0 +1,43 @@
+// Test that we exit with the correct exit code for successful / unsuccessful / ICE compilations
+
+extern crate run_make_support;
+
+use run_make_support::{rustc, rustdoc, tmp_dir};
+
+fn main() {
+    rustc()
+        .arg("success.rs")
+        .run();
+
+    rustc()
+        .arg("--invalid-arg-foo")
+        .run_fail_assert_exit_code(1);
+
+    rustc()
+        .arg("compile-error.rs")
+        .run_fail_assert_exit_code(1);
+
+    rustc()
+        .env("RUSTC_ICE", "0")
+        .arg("-Ztreat-err-as-bug")
+        .arg("compile-error.rs")
+        .run_fail_assert_exit_code(101);
+
+    rustdoc()
+        .arg("success.rs")
+        .arg("-o")
+        .arg(tmp_dir().join("exit-code"))
+        .run();
+
+    rustdoc()
+        .arg("--invalid-arg-foo")
+        .run_fail_assert_exit_code(1);
+
+    rustdoc()
+        .arg("compile-error.rs")
+        .run_fail_assert_exit_code(1);
+
+    rustdoc()
+        .arg("lint-failure.rs")
+        .run_fail_assert_exit_code(1);
+}
diff --git a/tests/rustdoc-gui/search-result-go-to-first.goml b/tests/rustdoc-gui/search-result-go-to-first.goml
index a0bc2bb16ba..f4cfe096386 100644
--- a/tests/rustdoc-gui/search-result-go-to-first.goml
+++ b/tests/rustdoc-gui/search-result-go-to-first.goml
@@ -3,17 +3,17 @@
 // First, we check that the first page doesn't have the string we're looking for to ensure
 // that the feature is changing page as expected.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert-text-false: (".main-heading h1", "Struct test_docs::Foo")
+assert-text-false: (".main-heading h1", "Struct test_docs::FooCopy item path")
 
 // We now check that we land on the search result page if "go_to_first" isn't set.
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=struct%3AFoo"
 // Waiting for the search results to appear...
 wait-for: "#search-tabs"
-assert-text-false: (".main-heading h1", "Struct test_docs::Foo")
+assert-text-false: (".main-heading h1", "Struct test_docs::FooCopy item path")
 // Ensure that the search results are displayed, not the "normal" content.
 assert-css: ("#main-content", {"display": "none"})
 
 // Now we can check that the feature is working as expected!
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=struct%3AFoo&go_to_first=true"
 // Waiting for the page to load...
-wait-for-text: (".main-heading h1", "Struct test_docs::Foo")
+wait-for-text: (".main-heading h1", "Struct test_docs::FooCopy item path")
diff --git a/tests/rustdoc-gui/toggle-click-deadspace.goml b/tests/rustdoc-gui/toggle-click-deadspace.goml
index f115f63ab6b..37bc3f7c372 100644
--- a/tests/rustdoc-gui/toggle-click-deadspace.goml
+++ b/tests/rustdoc-gui/toggle-click-deadspace.goml
@@ -12,4 +12,4 @@ assert-attribute-false: (".impl-items .toggle", {"open": ""})
 
 // Click the "Trait" part of "impl Trait" and verify it navigates.
 click: "#impl-Trait-for-Foo h3 a:first-of-type"
-assert-text: (".main-heading h1", "Trait lib2::Trait")
+assert-text: (".main-heading h1", "Trait lib2::TraitCopy item path")
diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr
index 06a52691310..66622a7654c 100644
--- a/tests/rustdoc-ui/ice-bug-report-url.stderr
+++ b/tests/rustdoc-ui/ice-bug-report-url.stderr
@@ -12,6 +12,8 @@ error: the compiler unexpectedly panicked. this is a bug.
 
 note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md
 
+note: please make sure that you have updated to the latest nightly
+
 note: rustc {version} running on {platform}
 
 query stack during panic:
diff --git a/tests/ui-fulldeps/stable-mir/check_intrinsics.rs b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
new file mode 100644
index 00000000000..171850b89bb
--- /dev/null
+++ b/tests/ui-fulldeps/stable-mir/check_intrinsics.rs
@@ -0,0 +1,115 @@
+//@ run-pass
+//! Test information regarding intrinsics and ensure we can retrieve the fallback body if it exists.
+//!
+//! This tests relies on the intrinsics implementation, and requires one intrinsic with and one
+//! without a body. It doesn't matter which intrinsic is called here, and feel free to update that
+//! if needed.
+
+//@ ignore-stage1
+//@ ignore-cross-compile
+//@ ignore-remote
+//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
+
+#![feature(rustc_private)]
+
+extern crate rustc_hir;
+#[macro_use]
+extern crate rustc_smir;
+extern crate rustc_driver;
+extern crate rustc_interface;
+extern crate stable_mir;
+
+use rustc_smir::rustc_internal;
+use stable_mir::mir::mono::{Instance, InstanceKind};
+use stable_mir::mir::visit::{Location, MirVisitor};
+use stable_mir::mir::{LocalDecl, Terminator, TerminatorKind};
+use stable_mir::ty::{RigidTy, TyKind};
+use std::collections::HashSet;
+use std::convert::TryFrom;
+use std::io::Write;
+use std::ops::ControlFlow;
+
+/// This function tests that we can correctly get type information from binary operations.
+fn test_intrinsics() -> ControlFlow<()> {
+    // Find items in the local crate.
+    let main_def = stable_mir::all_local_items()[0];
+    let main_instance = Instance::try_from(main_def).unwrap();
+    let main_body = main_instance.body().unwrap();
+    let mut visitor = CallsVisitor { locals: main_body.locals(), calls: Default::default() };
+    visitor.visit_body(&main_body);
+
+    let calls = visitor.calls;
+    assert_eq!(calls.len(), 2, "Expected 2 calls, but found: {calls:?}");
+    for intrinsic in &calls {
+        check_intrinsic(intrinsic)
+    }
+
+    ControlFlow::Continue(())
+}
+
+/// This check is unfortunately tight to the implementation of intrinsics.
+///
+/// We want to ensure that StableMIR can handle intrinsics with and without fallback body.
+///
+/// If by any chance this test breaks because you changed how an intrinsic is implemented, please
+/// update the test to invoke a different intrinsic.
+fn check_intrinsic(intrinsic: &Instance) {
+    assert_eq!(intrinsic.kind, InstanceKind::Intrinsic);
+    let name = intrinsic.intrinsic_name().unwrap();
+    if intrinsic.has_body() {
+        let Some(body) = intrinsic.body() else { unreachable!("Expected a body") };
+        assert!(!body.blocks.is_empty());
+        assert_eq!(&name, "likely");
+    } else {
+        assert!(intrinsic.body().is_none());
+        assert_eq!(&name, "size_of_val");
+    }
+}
+
+struct CallsVisitor<'a> {
+    locals: &'a [LocalDecl],
+    calls: HashSet<Instance>,
+}
+
+impl<'a> MirVisitor for CallsVisitor<'a> {
+    fn visit_terminator(&mut self, term: &Terminator, _loc: Location) {
+        match &term.kind {
+            TerminatorKind::Call { func, .. } => {
+                let TyKind::RigidTy(RigidTy::FnDef(def, args)) =
+                    func.ty(self.locals).unwrap().kind()
+                    else {
+                        return;
+                    };
+                self.calls.insert(Instance::resolve(def, &args).unwrap());
+            }
+            _ => {}
+        }
+    }
+}
+
+/// This test will generate and analyze a dummy crate using the stable mir.
+/// For that, it will first write the dummy crate into a file.
+/// Then it will create a `StableMir` using custom arguments and then
+/// it will run the compiler.
+fn main() {
+    let path = "binop_input.rs";
+    generate_input(&path).unwrap();
+    let args = vec!["rustc".to_string(), "--crate-type=lib".to_string(), path.to_string()];
+    run!(args, test_intrinsics).unwrap();
+}
+
+fn generate_input(path: &str) -> std::io::Result<()> {
+    let mut file = std::fs::File::create(path)?;
+    write!(
+        file,
+        r#"
+        #![feature(core_intrinsics)]
+        use std::intrinsics::*;
+        pub fn use_intrinsics(init: bool) -> bool {{
+            let sz = unsafe {{ size_of_val("hi") }};
+            likely(init && sz == 2)
+        }}
+        "#
+    )?;
+    Ok(())
+}
diff --git a/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs
new file mode 100644
index 00000000000..2313db506be
--- /dev/null
+++ b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+//@ edition: 2021
+// issue: rust-lang/rust#123697
+
+#![feature(async_closure)]
+
+struct S { t: i32 }
+
+fn test(s: &S, t: &i32) {
+    async || {
+        println!("{}", s.t);
+        println!("{}", t);
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/conditional-compilation/cfg-generic-params.rs b/tests/ui/conditional-compilation/cfg-generic-params.rs
index 76ba7f9b86e..2a83be21498 100644
--- a/tests/ui/conditional-compilation/cfg-generic-params.rs
+++ b/tests/ui/conditional-compilation/cfg-generic-params.rs
@@ -1,36 +1,36 @@
 //@ compile-flags:--cfg yes
 
-fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(no)] T>() {}
-fn f_ty<#[cfg(no)] 'a: 'a, #[cfg(yes)] T>() {}
+fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(FALSE)] T>() {}
+fn f_ty<#[cfg(FALSE)] 'a: 'a, #[cfg(yes)] T>() {}
 
-type FnGood = for<#[cfg(yes)] 'a, #[cfg(no)] T> fn(); // OK
-type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
+type FnGood = for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> fn(); // OK
+type FnBad = for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> fn();
 //~^ ERROR only lifetime parameters can be used in this context
 
-type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(no)] T> Copy; // OK
-type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
+type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> Copy; // OK
+type PolyBad = dyn for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> Copy;
 //~^ ERROR only lifetime parameters can be used in this context
 
-struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(no)] T> u8: Copy; // OK
-struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
+struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(FALSE)] T> u8: Copy; // OK
+struct WhereBad where for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> u8: Copy;
 //~^ ERROR only lifetime parameters can be used in this context
 
-fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK
+fn f_lt_no<#[cfg_attr(FALSE, unknown)] 'a>() {} // OK
 fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
 //~^ ERROR cannot find attribute `unknown` in this scope
-fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK
+fn f_ty_no<#[cfg_attr(FALSE, unknown)] T>() {} // OK
 fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
 //~^ ERROR cannot find attribute `unknown` in this scope
 
-type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK
+type FnNo = for<#[cfg_attr(FALSE, unknown)] 'a> fn(); // OK
 type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
 //~^ ERROR cannot find attribute `unknown` in this scope
 
-type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK
+type PolyNo = dyn for<#[cfg_attr(FALSE, unknown)] 'a> Copy; // OK
 type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
 //~^ ERROR cannot find attribute `unknown` in this scope
 
-struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK
+struct WhereNo where for<#[cfg_attr(FALSE, unknown)] 'a> u8: Copy; // OK
 struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
 //~^ ERROR cannot find attribute `unknown` in this scope
 
diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr
index 4143e2019ae..563616be36b 100644
--- a/tests/ui/conditional-compilation/cfg-generic-params.stderr
+++ b/tests/ui/conditional-compilation/cfg-generic-params.stderr
@@ -29,30 +29,30 @@ LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
    |                                           ^^^^^^^
 
 error[E0658]: only lifetime parameters can be used in this context
-  --> $DIR/cfg-generic-params.rs:7:45
+  --> $DIR/cfg-generic-params.rs:7:48
    |
-LL | type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn();
-   |                                             ^
+LL | type FnBad = for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> fn();
+   |                                                ^
    |
    = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
    = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: only lifetime parameters can be used in this context
-  --> $DIR/cfg-generic-params.rs:11:51
+  --> $DIR/cfg-generic-params.rs:11:54
    |
-LL | type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy;
-   |                                                   ^
+LL | type PolyBad = dyn for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> Copy;
+   |                                                      ^
    |
    = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
    = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: only lifetime parameters can be used in this context
-  --> $DIR/cfg-generic-params.rs:15:54
+  --> $DIR/cfg-generic-params.rs:15:57
    |
-LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
-   |                                                      ^
+LL | struct WhereBad where for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> u8: Copy;
+   |                                                         ^
    |
    = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
    = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs
index 6d30943ab7e..27b74489fe8 100644
--- a/tests/ui/const-generics/const-arg-in-const-arg.rs
+++ b/tests/ui/const-generics/const-arg-in-const-arg.rs
@@ -2,8 +2,8 @@
 // we use a single revision because this should have a `full` revision
 // but right now that ICEs and I(@BoxyUwU) could not get stderr normalization to work
 
-#![cfg_attr(full, feature(generic_const_exprs))]
-#![cfg_attr(full, allow(incomplete_features))]
+// #![cfg_attr(full, feature(generic_const_exprs))]
+// #![cfg_attr(full, allow(incomplete_features))]
 
 const fn foo<T>() -> usize { std::mem::size_of::<T>() }
 const fn bar<const N: usize>() -> usize { N }
diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
index 96fd9ed5f04..0a28c5b80bf 100644
--- a/tests/ui/consts/const-eval/const-eval-query-stack.stderr
+++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -4,6 +4,8 @@ error: internal compiler error[E0080]: evaluation of constant value failed
 LL | const X: i32 = 1 / 0;
    |                ^^^^^ attempt to divide `1_i32` by zero
 
+note: please make sure that you have updated to the latest nightly
+
 query stack during panic:
 #0 [eval_to_allocation_raw] const-evaluating + checking `X`
 #1 [eval_to_const_value_raw] simplifying constant for the type system `X`
diff --git a/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs b/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs
new file mode 100644
index 00000000000..65da2c3f5c7
--- /dev/null
+++ b/tests/ui/debuginfo/auxiliary/line-tables-only-helper.rs
@@ -0,0 +1,22 @@
+//@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only
+
+#[no_mangle]
+pub fn baz<F>(mut cb: F, data: u32) where F: FnMut(u32) {
+    cb(data);
+}
+
+#[no_mangle]
+pub fn bar<F>(cb: F, data: u32) where F: FnMut(u32) {
+    baz(cb, data);
+}
+
+#[no_mangle]
+pub fn foo<F>(cb: F, data: u32) where F: FnMut(u32) {
+    bar(cb, data);
+}
+
+pub fn capture_backtrace() -> std::backtrace::Backtrace {
+    let mut bt = None;
+    foo(|_| bt = Some(std::backtrace::Backtrace::capture()), 42);
+    bt.unwrap()
+}
diff --git a/tests/ui/debuginfo/backtrace-line-tables-only.rs b/tests/ui/debuginfo/backtrace-line-tables-only.rs
new file mode 100644
index 00000000000..044f59e483a
--- /dev/null
+++ b/tests/ui/debuginfo/backtrace-line-tables-only.rs
@@ -0,0 +1,49 @@
+// Test that when debug info only includes line tables that backtrace is still generated
+// successfully.
+// Original test:
+// <https://github.com/rust-lang/backtrace-rs/tree/6fa4b85b9962c3e1be8c2e5cc605cd078134152b/crates/line-tables-only>.
+// Part of <https://github.com/rust-lang/rust/issues/122899> porting some backtrace tests to rustc.
+// This test diverges from the original test in that it now uses a Rust library auxiliary because
+// rustc now has `-Cdebuginfo=line-tables-only`.
+// ignore-tidy-linelength
+//@ run-pass
+//@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only
+//@ ignore-android FIXME #17520
+//@ ignore-fuchsia Backtraces not symbolized
+//@ needs-unwind
+//@ aux-build: line-tables-only-helper.rs
+
+#![feature(backtrace_frames)]
+
+extern crate line_tables_only_helper;
+
+use std::backtrace::Backtrace;
+
+fn assert_contains(
+    backtrace: &Backtrace,
+    expected_name: &str,
+    expected_file: &str,
+    expected_line: u32,
+) {
+    // FIXME(jieyouxu): fix this ugly fragile test when `BacktraceFrame` has accessors like...
+    // `symbols()`.
+    let backtrace = format!("{:#?}", backtrace);
+    eprintln!("{}", backtrace);
+    assert!(backtrace.contains(expected_name), "backtrace does not contain expected name {}", expected_name);
+    assert!(backtrace.contains(expected_file), "backtrace does not contain expected file {}", expected_file);
+    assert!(backtrace.contains(&expected_line.to_string()), "backtrace does not contain expected line {}", expected_line);
+}
+
+fn main() {
+    std::env::set_var("RUST_BACKTRACE", "1");
+    let backtrace = line_tables_only_helper::capture_backtrace();
+
+    // FIXME(jieyouxu): for some forsaken reason on i686-msvc `foo` doesn't have an entry in the
+    // line tables?
+    #[cfg(not(all(target_pointer_width = "32", target_env = "msvc")))]
+    {
+        assert_contains(&backtrace, "foo", "line-tables-only-helper.rs", 5);
+    }
+    assert_contains(&backtrace, "bar", "line-tables-only-helper.rs", 10);
+    assert_contains(&backtrace, "baz", "line-tables-only-helper.rs", 15);
+}
diff --git a/tests/ui/does-nothing.rs b/tests/ui/does-nothing.rs
deleted file mode 100644
index e4992e2cfd3..00000000000
--- a/tests/ui/does-nothing.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-fn main() { println!("doing"); this_does_nothing_what_the; println!("boing"); }
-//~^ ERROR cannot find value `this_does_nothing_what_the` in this scope
diff --git a/tests/ui/does-nothing.stderr b/tests/ui/does-nothing.stderr
deleted file mode 100644
index d5ea3626e81..00000000000
--- a/tests/ui/does-nothing.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find value `this_does_nothing_what_the` in this scope
-  --> $DIR/does-nothing.rs:1:32
-   |
-LL | fn main() { println!("doing"); this_does_nothing_what_the; println!("boing"); }
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs b/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
index 6fe51330118..33fda822baa 100644
--- a/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
+++ b/tests/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: --edition 2021
 
 pub fn demo() -> Option<i32> {
-    #[cfg(nope)]
+    #[cfg(FALSE)]
     {
         do yeet //~ ERROR `do yeet` expression is experimental
     }
@@ -9,7 +9,7 @@ pub fn demo() -> Option<i32> {
     Some(1)
 }
 
-#[cfg(nope)]
+#[cfg(FALSE)]
 pub fn alternative() -> Result<(), String> {
     do yeet "hello"; //~ ERROR `do yeet` expression is experimental
 }
diff --git a/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs
index a3f3b1a6d4d..e06341ddf31 100644
--- a/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs
+++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs
@@ -1,8 +1,7 @@
-#![warn(unused_lifetimes)]
+#![warn(unused_lifetimes, redundant_lifetimes)]
 
 pub trait X {
-    type Y<'a: 'static>;
-    //~^ WARNING unnecessary lifetime parameter
+    type Y<'a: 'static>; //~ WARN unnecessary lifetime parameter `'a`
 }
 
 impl X for () {
diff --git a/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr
index 8d21b9172c8..4f41ec025fc 100644
--- a/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr
+++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr
@@ -1,18 +1,5 @@
-warning: unnecessary lifetime parameter `'a`
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:4:12
-   |
-LL |     type Y<'a: 'static>;
-   |            ^^
-   |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
-note: the lint level is defined here
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:1:9
-   |
-LL | #![warn(unused_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^
-
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:9:18
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:8:18
    |
 LL |     type Y<'a: 'static>;
    |     ------------------- definition of `Y` from trait
@@ -21,7 +8,7 @@ LL |     type Y<'a> = &'a ();
    |                  ^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:9:12
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:8:12
    |
 LL |     type Y<'a> = &'a ();
    |            ^^
@@ -32,44 +19,57 @@ LL |     type Y<'a> = &'a () where 'a: 'static;
    |                         +++++++++++++++++
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:14:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:13:8
    |
 LL |     f: <T as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:13:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:12:10
    |
 LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:19:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:18:8
    |
 LL |     f: <T as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:18:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:17:10
    |
 LL | struct C<'a, T: X> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:24:8
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:23:8
    |
 LL |     f: <() as X>::Y<'a>,
    |        ^^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/unsatisfied-item-lifetime-bound.rs:23:10
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:22:10
    |
 LL | struct D<'a> {
    |          ^^
    = note: but lifetime parameter must outlive the static lifetime
 
+warning: unnecessary lifetime parameter `'a`
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:4:12
+   |
+LL |     type Y<'a: 'static>;
+   |            ^^
+   |
+   = note: you can use the `'static` lifetime directly, in place of `'a`
+note: the lint level is defined here
+  --> $DIR/unsatisfied-item-lifetime-bound.rs:1:27
+   |
+LL | #![warn(unused_lifetimes, redundant_lifetimes)]
+   |                           ^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 4 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0478`.
diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr
index 82b61e43f44..23b863568bc 100644
--- a/tests/ui/panics/default-backtrace-ice.stderr
+++ b/tests/ui/panics/default-backtrace-ice.stderr
@@ -20,6 +20,8 @@ error: the compiler unexpectedly panicked. this is a bug.
 
 
 
+
+
 query stack during panic:
 #0 [resolver_for_lowering_raw] getting the resolver for lowering
 end of query stack
diff --git a/tests/ui/proc-macro/derive-helper-configured.rs b/tests/ui/proc-macro/derive-helper-configured.rs
index 74d5d827f16..45e6e64d392 100644
--- a/tests/ui/proc-macro/derive-helper-configured.rs
+++ b/tests/ui/proc-macro/derive-helper-configured.rs
@@ -1,17 +1,15 @@
 // Derive helpers are resolved successfully inside `cfg_attr`.
 
 //@ check-pass
-// compile-flats:--cfg TRUE
 //@ aux-build:test-macros.rs
 
 #[macro_use]
 extern crate test_macros;
 
-#[cfg_attr(TRUE, empty_helper)]
 #[derive(Empty)]
-#[cfg_attr(TRUE, empty_helper)]
+#[cfg_attr(all(), empty_helper)]
 struct S {
-    #[cfg_attr(TRUE, empty_helper)]
+    #[cfg_attr(all(), empty_helper)]
     field: u8,
 }
 
diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
index f6a628e97f5..bef0d70c776 100644
--- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
+++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs
@@ -8,10 +8,10 @@
 //
 //     'a : 'b
 
-#![warn(unused_lifetimes)]
+#![warn(redundant_lifetimes)]
 
-fn test<'a,'b>(x: &'a i32) -> &'b i32
-    where 'a: 'static //~ WARN unnecessary lifetime parameter `'a`
+fn test<'a,'b>(x: &'a i32) -> &'b i32 //~ WARN unnecessary lifetime parameter `'a`
+    where 'a: 'static
 {
     x
 }
diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
index 9f03a6553ba..d97cfd59f2b 100644
--- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
+++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr
@@ -1,15 +1,15 @@
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:14:11
+  --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:13:9
    |
-LL |     where 'a: 'static
-   |           ^^
+LL | fn test<'a,'b>(x: &'a i32) -> &'b i32
+   |         ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
+   = note: you can use the `'static` lifetime directly, in place of `'a`
 note: the lint level is defined here
   --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:11:9
    |
-LL | #![warn(unused_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^
+LL | #![warn(redundant_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/regions/regions-static-bound-rpass.rs b/tests/ui/regions/regions-static-bound-rpass.rs
index 27da42882f3..f4177f835b1 100644
--- a/tests/ui/regions/regions-static-bound-rpass.rs
+++ b/tests/ui/regions/regions-static-bound-rpass.rs
@@ -1,18 +1,19 @@
 //@ run-pass
 
-#![warn(unused_lifetimes)]
+#![warn(redundant_lifetimes)]
 
 fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
-    where 'a: 'static { t }
 //~^ WARN unnecessary lifetime parameter `'a`
+    where 'a: 'static { t }
 
 fn static_id<'a>(t: &'a ()) -> &'static ()
-    where 'a: 'static { t }
 //~^ WARN unnecessary lifetime parameter `'a`
+    where 'a: 'static { t }
 
 fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+//~^ WARN unnecessary lifetime parameter `'a`
+//~| WARN unnecessary lifetime parameter `'b`
     where 'a: 'b, 'b: 'static { t }
-//~^ WARN unnecessary lifetime parameter `'b`
 
 fn ref_id<'a>(t: &'a ()) -> &'a () where 'static: 'a { t }
 
diff --git a/tests/ui/regions/regions-static-bound-rpass.stderr b/tests/ui/regions/regions-static-bound-rpass.stderr
index f0f3a4c5261..4199ac7bb3d 100644
--- a/tests/ui/regions/regions-static-bound-rpass.stderr
+++ b/tests/ui/regions/regions-static-bound-rpass.stderr
@@ -1,31 +1,39 @@
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound-rpass.rs:6:11
+  --> $DIR/regions-static-bound-rpass.rs:5:17
    |
-LL |     where 'a: 'static { t }
-   |           ^^
+LL | fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a ()
+   |                 ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
+   = note: you can use the `'static` lifetime directly, in place of `'a`
 note: the lint level is defined here
   --> $DIR/regions-static-bound-rpass.rs:3:9
    |
-LL | #![warn(unused_lifetimes)]
-   |         ^^^^^^^^^^^^^^^^
+LL | #![warn(redundant_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^
 
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound-rpass.rs:10:11
+  --> $DIR/regions-static-bound-rpass.rs:9:14
    |
-LL |     where 'a: 'static { t }
-   |           ^^
+LL | fn static_id<'a>(t: &'a ()) -> &'static ()
+   |              ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
+   = note: you can use the `'static` lifetime directly, in place of `'a`
+
+warning: unnecessary lifetime parameter `'a`
+  --> $DIR/regions-static-bound-rpass.rs:13:23
+   |
+LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+   |                       ^^
+   |
+   = note: you can use the `'static` lifetime directly, in place of `'a`
 
 warning: unnecessary lifetime parameter `'b`
-  --> $DIR/regions-static-bound-rpass.rs:14:19
+  --> $DIR/regions-static-bound-rpass.rs:13:26
    |
-LL |     where 'a: 'b, 'b: 'static { t }
-   |                   ^^
+LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+   |                          ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'b`
+   = note: you can use the `'static` lifetime directly, in place of `'b`
 
-warning: 3 warnings emitted
+warning: 4 warnings emitted
 
diff --git a/tests/ui/regions/regions-static-bound.rs b/tests/ui/regions/regions-static-bound.rs
index e7aa8795f01..32fa2536533 100644
--- a/tests/ui/regions/regions-static-bound.rs
+++ b/tests/ui/regions/regions-static-bound.rs
@@ -1,12 +1,13 @@
-#![warn(unused_lifetimes)]
+#![warn(unused_lifetimes, redundant_lifetimes)]
 
 fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
-//~^ WARN lifetime parameter `'b` never used
-//~| WARN unnecessary lifetime parameter `'a`
+//~^ WARN unnecessary lifetime parameter `'a`
+//~| WARN lifetime parameter `'b` never used
 
 fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+//~^ WARN unnecessary lifetime parameter `'a`
+//~| WARN unnecessary lifetime parameter `'b`
     where 'a: 'b, 'b: 'static { t }
-//~^ WARN unnecessary lifetime parameter `'b`
 
 fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
     t
diff --git a/tests/ui/regions/regions-static-bound.stderr b/tests/ui/regions/regions-static-bound.stderr
index b314e9fe85d..48aa8f32329 100644
--- a/tests/ui/regions/regions-static-bound.stderr
+++ b/tests/ui/regions/regions-static-bound.stderr
@@ -9,27 +9,40 @@ LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
 note: the lint level is defined here
   --> $DIR/regions-static-bound.rs:1:9
    |
-LL | #![warn(unused_lifetimes)]
+LL | #![warn(unused_lifetimes, redundant_lifetimes)]
    |         ^^^^^^^^^^^^^^^^
 
 warning: unnecessary lifetime parameter `'a`
-  --> $DIR/regions-static-bound.rs:3:53
+  --> $DIR/regions-static-bound.rs:3:14
    |
 LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t }
-   |                                                     ^^
+   |              ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'a`
+   = note: you can use the `'static` lifetime directly, in place of `'a`
+note: the lint level is defined here
+  --> $DIR/regions-static-bound.rs:1:27
+   |
+LL | #![warn(unused_lifetimes, redundant_lifetimes)]
+   |                           ^^^^^^^^^^^^^^^^^^^
+
+warning: unnecessary lifetime parameter `'a`
+  --> $DIR/regions-static-bound.rs:7:23
+   |
+LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+   |                       ^^
+   |
+   = note: you can use the `'static` lifetime directly, in place of `'a`
 
 warning: unnecessary lifetime parameter `'b`
-  --> $DIR/regions-static-bound.rs:8:19
+  --> $DIR/regions-static-bound.rs:7:26
    |
-LL |     where 'a: 'b, 'b: 'static { t }
-   |                   ^^
+LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
+   |                          ^^
    |
-   = help: you can use the `'static` lifetime directly, in place of `'b`
+   = note: you can use the `'static` lifetime directly, in place of `'b`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-static-bound.rs:12:5
+  --> $DIR/regions-static-bound.rs:13:5
    |
 LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
    |                        -- lifetime `'a` defined here
@@ -37,7 +50,7 @@ LL |     t
    |     ^ returning this value requires that `'a` must outlive `'static`
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/regions-static-bound.rs:17:5
+  --> $DIR/regions-static-bound.rs:18:5
    |
 LL | fn error(u: &(), v: &()) {
    |          -  - let's call the lifetime of this reference `'1`
@@ -50,7 +63,7 @@ LL |     static_id(&u);
    |     argument requires that `'1` must outlive `'static`
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/regions-static-bound.rs:19:5
+  --> $DIR/regions-static-bound.rs:20:5
    |
 LL | fn error(u: &(), v: &()) {
    |                  -  - let's call the lifetime of this reference `'2`
@@ -63,6 +76,6 @@ LL |     static_id_indirect(&v);
    |     `v` escapes the function body here
    |     argument requires that `'2` must outlive `'static`
 
-error: aborting due to 3 previous errors; 3 warnings emitted
+error: aborting due to 3 previous errors; 4 warnings emitted
 
 For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/regions/transitively-redundant-lifetimes.rs b/tests/ui/regions/transitively-redundant-lifetimes.rs
new file mode 100644
index 00000000000..9c29f66e54c
--- /dev/null
+++ b/tests/ui/regions/transitively-redundant-lifetimes.rs
@@ -0,0 +1,20 @@
+#![deny(redundant_lifetimes)]
+
+fn a<'a, 'b>(x: &'a &'b &'a ()) {} //~ ERROR unnecessary lifetime parameter `'b`
+
+fn b<'a: 'b, 'b: 'a>() {} //~ ERROR unnecessary lifetime parameter `'b`
+
+struct Foo<T: 'static>(T);
+fn c<'a>(_: Foo<&'a ()>) {} //~ ERROR unnecessary lifetime parameter `'a`
+
+struct Bar<'a>(&'a ());
+impl<'a> Bar<'a> {
+    fn d<'b: 'a>(&'b self) {} //~ ERROR unnecessary lifetime parameter `'b`
+}
+
+fn ok(x: &'static &()) {}
+
+trait Tr<'a> {}
+impl<'a: 'static> Tr<'a> for () {} //~ ERROR unnecessary lifetime parameter `'a`
+
+fn main() {}
diff --git a/tests/ui/regions/transitively-redundant-lifetimes.stderr b/tests/ui/regions/transitively-redundant-lifetimes.stderr
new file mode 100644
index 00000000000..2d8fc433b24
--- /dev/null
+++ b/tests/ui/regions/transitively-redundant-lifetimes.stderr
@@ -0,0 +1,47 @@
+error: unnecessary lifetime parameter `'b`
+  --> $DIR/transitively-redundant-lifetimes.rs:3:10
+   |
+LL | fn a<'a, 'b>(x: &'a &'b &'a ()) {}
+   |          ^^
+   |
+   = note: you can use the `'a` lifetime directly, in place of `'b`
+note: the lint level is defined here
+  --> $DIR/transitively-redundant-lifetimes.rs:1:9
+   |
+LL | #![deny(redundant_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary lifetime parameter `'b`
+  --> $DIR/transitively-redundant-lifetimes.rs:5:14
+   |
+LL | fn b<'a: 'b, 'b: 'a>() {}
+   |              ^^
+   |
+   = note: you can use the `'a` lifetime directly, in place of `'b`
+
+error: unnecessary lifetime parameter `'a`
+  --> $DIR/transitively-redundant-lifetimes.rs:8:6
+   |
+LL | fn c<'a>(_: Foo<&'a ()>) {}
+   |      ^^
+   |
+   = note: you can use the `'static` lifetime directly, in place of `'a`
+
+error: unnecessary lifetime parameter `'a`
+  --> $DIR/transitively-redundant-lifetimes.rs:18:6
+   |
+LL | impl<'a: 'static> Tr<'a> for () {}
+   |      ^^
+   |
+   = note: you can use the `'static` lifetime directly, in place of `'a`
+
+error: unnecessary lifetime parameter `'b`
+  --> $DIR/transitively-redundant-lifetimes.rs:12:10
+   |
+LL |     fn d<'b: 'a>(&'b self) {}
+   |          ^^
+   |
+   = note: you can use the `'a` lifetime directly, in place of `'b`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
index 17817a460d7..cd5fa609947 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
@@ -1,7 +1,7 @@
 //@ known-bug: #110395
 #![feature(const_trait_impl)]
 #![feature(const_mut_refs)]
-#![cfg_attr(precise, feature(const_precise_live_drops))]
+// #![cfg_attr(precise, feature(const_precise_live_drops))]
 
 use std::marker::{Destruct, PhantomData};
 
diff --git a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
index 75b3918be1d..f4506dd929e 100644
--- a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
+++ b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
@@ -1,6 +1,6 @@
 //@ aux-build:edition-lint-paths.rs
 //@ run-rustfix
-//@ compile-flags:--extern edition_lint_paths --cfg blandiloquence
+//@ compile-flags:--extern edition_lint_paths
 //@ edition:2018
 
 #![deny(rust_2018_idioms)]
diff --git a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs
index eff03c6fbe6..4f1cb71dc51 100644
--- a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs
+++ b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs
@@ -1,6 +1,6 @@
 //@ aux-build:edition-lint-paths.rs
 //@ run-rustfix
-//@ compile-flags:--extern edition_lint_paths --cfg blandiloquence
+//@ compile-flags:--extern edition_lint_paths
 //@ edition:2018
 
 #![deny(rust_2018_idioms)]
@@ -8,7 +8,7 @@
 
 // The suggestion span should include the attribute.
 
-#[cfg(blandiloquence)] //~ HELP remove it
+#[cfg(not(FALSE))] //~ HELP remove it
 extern crate edition_lint_paths;
 //~^ ERROR unused extern crate
 
diff --git a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr
index 801d16af82d..038a9dd967b 100644
--- a/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr
+++ b/tests/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr
@@ -1,7 +1,7 @@
 error: unused extern crate
   --> $DIR/issue-54400-unused-extern-crate-attr-span.rs:12:1
    |
-LL | / #[cfg(blandiloquence)]
+LL | / #[cfg(not(FALSE))]
 LL | | extern crate edition_lint_paths;
    | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
    | |________________________________|
diff --git a/tests/ui/std/windows-bat-args.rs b/tests/ui/std/windows-bat-args.rs
new file mode 100644
index 00000000000..a9b6252b78c
--- /dev/null
+++ b/tests/ui/std/windows-bat-args.rs
@@ -0,0 +1,90 @@
+//@ only-windows
+//@ run-pass
+//@ run-flags:--parent-process
+
+use std::env;
+use std::io::ErrorKind::{self, InvalidInput};
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+fn main() {
+    if env::args().nth(1).as_deref() == Some("--parent-process") {
+        parent();
+    } else {
+        child();
+    }
+}
+
+fn child() {
+    if env::args().len() == 1 {
+        panic!("something went wrong :/");
+    }
+    for arg in env::args().skip(1) {
+        print!("{arg}\0");
+    }
+}
+
+fn parent() {
+    let mut bat = PathBuf::from(file!());
+    bat.set_file_name("windows-bat-args1.bat");
+    let bat1 = String::from(bat.to_str().unwrap());
+    bat.set_file_name("windows-bat-args2.bat");
+    let bat2 = String::from(bat.to_str().unwrap());
+    bat.set_file_name("windows-bat-args3.bat");
+    let bat3 = String::from(bat.to_str().unwrap());
+    let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str()];
+
+    check_args(&bat, &["a", "b"]).unwrap();
+    check_args(&bat, &["c is for cat", "d is for dog"]).unwrap();
+    check_args(&bat, &["\"", " \""]).unwrap();
+    check_args(&bat, &["\\", "\\"]).unwrap();
+    check_args(&bat, &[">file.txt"]).unwrap();
+    check_args(&bat, &["whoami.exe"]).unwrap();
+    check_args(&bat, &["&a.exe"]).unwrap();
+    check_args(&bat, &["&echo hello "]).unwrap();
+    check_args(&bat, &["&echo hello", "&whoami", ">file.txt"]).unwrap();
+    check_args(&bat, &["!TMP!"]).unwrap();
+    check_args(&bat, &["key=value"]).unwrap();
+    check_args(&bat, &["\"key=value\""]).unwrap();
+    check_args(&bat, &["key = value"]).unwrap();
+    check_args(&bat, &["key=[\"value\"]"]).unwrap();
+    check_args(&bat, &["", "a=b"]).unwrap();
+    check_args(&bat, &["key=\"foo bar\""]).unwrap();
+    check_args(&bat, &["key=[\"my_value]"]).unwrap();
+    check_args(&bat, &["key=[\"my_value\",\"other-value\"]"]).unwrap();
+    check_args(&bat, &["key\\=value"]).unwrap();
+    check_args(&bat, &["key=\"&whoami\""]).unwrap();
+    check_args(&bat, &["key=\"value\"=5"]).unwrap();
+    check_args(&bat, &["key=[\">file.txt\"]"]).unwrap();
+    assert_eq!(check_args(&bat, &["\n"]), Err(InvalidInput));
+    assert_eq!(check_args(&bat, &["\r"]), Err(InvalidInput));
+    check_args(&bat, &["%hello"]).unwrap();
+    check_args(&bat, &["%PATH%"]).unwrap();
+    check_args(&bat, &["%%cd:~,%"]).unwrap();
+    check_args(&bat, &["%PATH%PATH%"]).unwrap();
+    check_args(&bat, &["\">file.txt"]).unwrap();
+    check_args(&bat, &["abc\"&echo hello"]).unwrap();
+    check_args(&bat, &["123\">file.txt"]).unwrap();
+    check_args(&bat, &["\"&echo hello&whoami.exe"]).unwrap();
+    check_args(&bat, &[r#"hello^"world"#, "hello &echo oh no >file.txt"]).unwrap();
+}
+
+// Check if the arguments roundtrip through a bat file and back into a Rust process.
+// Our Rust process outptuts the arguments as null terminated strings.
+#[track_caller]
+fn check_args(bats: &[&str], args: &[&str]) -> Result<(), ErrorKind> {
+    for bat in bats {
+        let output = Command::new(&bat).args(args).output().map_err(|e| e.kind())?;
+        assert!(output.status.success());
+        let child_args = String::from_utf8(output.stdout).unwrap();
+        let mut child_args: Vec<&str> =
+            child_args.strip_suffix('\0').unwrap().split('\0').collect();
+        // args3.bat can append spurious empty arguments, so trim them here.
+        child_args.truncate(
+            child_args.iter().rposition(|s| !s.is_empty()).unwrap_or(child_args.len() - 1) + 1,
+        );
+        assert_eq!(&child_args, &args);
+        assert!(!Path::new("file.txt").exists());
+    }
+    Ok(())
+}
diff --git a/tests/ui/std/windows-bat-args1.bat b/tests/ui/std/windows-bat-args1.bat
new file mode 100644
index 00000000000..edd36bd5530
--- /dev/null
+++ b/tests/ui/std/windows-bat-args1.bat
@@ -0,0 +1 @@
+@a.exe %*
diff --git a/tests/ui/std/windows-bat-args2.bat b/tests/ui/std/windows-bat-args2.bat
new file mode 100644
index 00000000000..8d5a7dd8a9e
--- /dev/null
+++ b/tests/ui/std/windows-bat-args2.bat
@@ -0,0 +1 @@
+@a.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/tests/ui/std/windows-bat-args3.bat b/tests/ui/std/windows-bat-args3.bat
new file mode 100644
index 00000000000..7fe360a6d36
--- /dev/null
+++ b/tests/ui/std/windows-bat-args3.bat
@@ -0,0 +1 @@
+@a.exe "%~1" "%~2" "%~3" "%~4" "%~5" "%~6" "%~7" "%~8" "%~9"
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr
index 54b1ea2764a..436f9ecf93d 100644
--- a/tests/ui/track-diagnostics/track.stderr
+++ b/tests/ui/track-diagnostics/track.stderr
@@ -30,6 +30,8 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
 
+note: please make sure that you have updated to the latest nightly
+
 note: rustc $VERSION running on $TARGET
 
 note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics
diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs
new file mode 100644
index 00000000000..5bc6fd54e0f
--- /dev/null
+++ b/tests/ui/type/pattern_types/const_generics.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+#![feature(pattern_types)]
+#![feature(core_pattern_types)]
+#![feature(core_pattern_type)]
+
+use std::pat::pattern_type;
+
+trait Foo {}
+
+impl<const START: u32, const END: u32> Foo for pattern_type!(u32 is START..=END) {}
+
+fn main() {}
diff --git a/tests/ui/typeck/remove-semi-but-confused-char.rs b/tests/ui/typeck/remove-semi-but-confused-char.rs
new file mode 100644
index 00000000000..ccc6f59344c
--- /dev/null
+++ b/tests/ui/typeck/remove-semi-but-confused-char.rs
@@ -0,0 +1,11 @@
+// Ensures our "remove semicolon" suggestion isn't hardcoded with a character width,
+// in case it was accidentally mixed up with a greek question mark.
+// issue: rust-lang/rust#123607
+
+pub fn square(num: i32) -> i32 {
+    //~^ ERROR mismatched types
+    num * num;
+    //~^ ERROR unknown start of token
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/remove-semi-but-confused-char.stderr b/tests/ui/typeck/remove-semi-but-confused-char.stderr
new file mode 100644
index 00000000000..2d0b53a60ce
--- /dev/null
+++ b/tests/ui/typeck/remove-semi-but-confused-char.stderr
@@ -0,0 +1,25 @@
+error: unknown start of token: \u{37e}
+  --> $DIR/remove-semi-but-confused-char.rs:7:14
+   |
+LL |     num * num;
+   |              ^
+   |
+help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+   |
+LL |     num * num;
+   |              ~
+
+error[E0308]: mismatched types
+  --> $DIR/remove-semi-but-confused-char.rs:5:28
+   |
+LL | pub fn square(num: i32) -> i32 {
+   |        ------              ^^^ expected `i32`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+LL |
+LL |     num * num;
+   |              - help: remove this semicolon to return this value
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.