about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_abi/src/extern_abi/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs59
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/opaque_types.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs6
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs12
-rw-r--r--compiler/rustc_feature/src/lib.rs12
-rw-r--r--compiler/rustc_feature/src/tests.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs95
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs6
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs4
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs21
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs24
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs1
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs22
-rw-r--r--compiler/rustc_middle/src/util/mod.rs2
-rw-r--r--compiler/rustc_passes/messages.ftl3
-rw-r--r--compiler/rustc_passes/src/errors.rs19
-rw-r--r--compiler/rustc_passes/src/liveness.rs81
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs78
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs29
-rw-r--r--compiler/rustc_target/src/callconv/x86_win64.rs20
-rw-r--r--compiler/rustc_target/src/spec/mod.rs15
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs (renamed from compiler/rustc_middle/src/util/call_kind.rs)104
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs7
-rw-r--r--library/alloc/src/vec/mod.rs16
-rw-r--r--library/std/src/path.rs15
-rw-r--r--library/std/src/rt.rs47
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs21
-rw-r--r--library/std/src/sys/pal/uefi/process.rs2
-rw-r--r--library/std/src/sys/path/sgx.rs4
-rw-r--r--library/std/src/sys/path/unix.rs11
-rw-r--r--library/std/src/sys/path/unsupported_backslash.rs4
-rw-r--r--library/std/src/sys/path/windows.rs4
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs6
m---------src/doc/book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr6
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-std.stderr2
-rw-r--r--tests/assembly/simd-intrinsic-gather.rs2
-rw-r--r--tests/assembly/simd-intrinsic-scatter.rs2
-rw-r--r--tests/codegen/abi-win64-zst.rs52
-rw-r--r--tests/debuginfo/closures.rs155
-rw-r--r--tests/debuginfo/coroutine-closure.rs29
-rw-r--r--tests/debuginfo/fn_ptr.rs51
-rw-r--r--tests/debuginfo/lexical-scope-in-if-let.rs25
-rw-r--r--tests/debuginfo/step-into-match.rs6
-rw-r--r--tests/debuginfo/type-names.rs77
-rw-r--r--tests/mir-opt/building/dump_mir_cycle.rs19
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-pre-optimizations.after.mir4
-rw-r--r--tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff6
-rw-r--r--tests/ui/abi/win64-zst.rs24
-rw-r--r--tests/ui/abi/win64-zst.x86_64-linux.stderr69
-rw-r--r--tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr80
-rw-r--r--tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr69
-rw-r--r--tests/ui/const-generics/normalizing_with_unconstrained_impl_params.rs18
-rw-r--r--tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr60
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed22
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs22
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr69
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.rs10
-rw-r--r--tests/ui/impl-trait/precise-capturing/redundant.stderr16
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs (renamed from tests/crashes/114484.rs)10
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr86
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.stderr3
-rw-r--r--tests/ui/structs/ice-struct-tail-normalization-113272.rs1
-rw-r--r--tests/ui/structs/ice-struct-tail-normalization-113272.stderr13
80 files changed, 1236 insertions, 596 deletions
diff --git a/compiler/rustc_abi/src/extern_abi/mod.rs b/compiler/rustc_abi/src/extern_abi/mod.rs
index 390f2dbc10f..28860afb37a 100644
--- a/compiler/rustc_abi/src/extern_abi/mod.rs
+++ b/compiler/rustc_abi/src/extern_abi/mod.rs
@@ -192,6 +192,10 @@ pub fn is_enabled(
     s
 }
 
+/// Returns whether the ABI is stable to use.
+///
+/// Note that there is a separate check determining whether the ABI is even supported
+/// on the current target; see `fn is_abi_supported` in `rustc_target::spec`.
 pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
     match name {
         // Stable
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 4d19d89b3ce..da59f9f9ebd 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -20,7 +20,7 @@ use rustc_middle::bug;
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
-    self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
+    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
     FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
     Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
     TerminatorKind, VarBindingForm, VarDebugInfoContents,
@@ -30,13 +30,13 @@ use rustc_middle::ty::{
     self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
     suggest_constraining_type_params,
 };
-use rustc_middle::util::CallKind;
 use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
 use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
+use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
@@ -46,7 +46,7 @@ use super::explain_borrow::{BorrowExplanation, LaterUseKind};
 use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans};
 use crate::borrow_set::{BorrowData, TwoPhaseActivation};
 use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
-use crate::diagnostics::{CapturedMessageOpt, Instance, find_all_local_uses};
+use crate::diagnostics::{CapturedMessageOpt, call_kind, find_all_local_uses};
 use crate::prefixes::IsPrefixOf;
 use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors};
 
@@ -305,7 +305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             }
 
             if let UseSpans::FnSelfUse {
-                kind: CallKind::DerefCoercion { deref_target, deref_target_ty, .. },
+                kind: CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. },
                 ..
             } = use_spans
             {
@@ -315,8 +315,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 ));
 
                 // Check first whether the source is accessible (issue #87060)
-                if self.infcx.tcx.sess.source_map().is_span_accessible(deref_target) {
-                    err.span_note(deref_target, "deref defined here");
+                if let Some(deref_target_span) = deref_target_span
+                    && self.infcx.tcx.sess.source_map().is_span_accessible(deref_target_span)
+                {
+                    err.span_note(deref_target_span, "deref defined here");
                 }
             }
 
@@ -3765,38 +3767,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
 
     fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) {
         let tcx = self.infcx.tcx;
-        if let (
-            Some(Terminator {
-                kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
-                ..
-            }),
-            Some((method_did, method_args)),
-        ) = (
-            &self.body[loan.reserve_location.block].terminator,
-            rustc_middle::util::find_self_call(
+        if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
+            &self.body[loan.reserve_location.block].terminator
+            && let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
                 tcx,
                 self.body,
                 loan.assigned_place.local,
                 loan.reserve_location.block,
-            ),
-        ) {
-            if tcx.is_diagnostic_item(sym::deref_method, method_did) {
-                let deref_target =
-                    tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
-                        Instance::try_resolve(
-                            tcx,
-                            self.infcx.typing_env(self.infcx.param_env),
-                            deref_target,
-                            method_args,
-                        )
-                        .transpose()
-                    });
-                if let Some(Ok(instance)) = deref_target {
-                    let deref_target_ty =
-                        instance.ty(tcx, self.infcx.typing_env(self.infcx.param_env));
-                    err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
-                    err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
-                }
+            )
+            && let CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. } = call_kind(
+                self.infcx.tcx,
+                self.infcx.typing_env(self.infcx.param_env),
+                method_did,
+                method_args,
+                *fn_span,
+                call_source.from_hir_call(),
+                Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
+            )
+        {
+            err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
+            if let Some(deref_target_span) = deref_target_span {
+                err.span_note(deref_target_span, "deref defined here");
             }
         }
     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index a52dc447d76..5c0c1d0eb86 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -16,9 +16,9 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
-use rustc_middle::util::CallKind;
 use rustc_span::{DesugaringKind, Span, kw, sym};
 use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
+use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
 use tracing::{debug, instrument};
 
 use super::{RegionName, UseSpans, find_use};
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index d9d9ea75994..bd6f77156ca 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -20,13 +20,13 @@ use rustc_middle::mir::{
     StatementKind, Terminator, TerminatorKind,
 };
 use rustc_middle::ty::print::Print;
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
-use rustc_middle::util::{CallDesugaringKind, call_kind};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
+use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{
     FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
@@ -63,7 +63,7 @@ pub(crate) use mutability_errors::AccessKind;
 pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
 pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
 pub(crate) use region_name::{RegionName, RegionNameSource};
-pub(crate) use rustc_middle::util::CallKind;
+pub(crate) use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
 
 pub(super) struct DescribePlaceOpt {
     including_downcast: bool,
diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
index edf3b1ae092..ad4e006c21a 100644
--- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs
@@ -25,8 +25,8 @@ pub(super) fn take_opaques_and_register_member_constraints<'tcx>(
     let opaque_types = infcx
         .take_opaque_types()
         .into_iter()
-        .map(|(opaque_type_key, decl)| {
-            let hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
+        .map(|(opaque_type_key, hidden_type)| {
+            let hidden_type = infcx.resolve_vars_if_possible(hidden_type);
             register_member_constraints(
                 typeck,
                 &mut member_constraints,
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 08b774f8d6e..78c759bbe8c 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -1,7 +1,6 @@
 use std::collections::BTreeMap;
 use std::ffi::{CStr, CString};
 use std::fs::File;
-use std::mem::ManuallyDrop;
 use std::path::Path;
 use std::sync::Arc;
 use std::{io, iter, slice};
@@ -9,7 +8,7 @@ use std::{io, iter, slice};
 use object::read::archive::ArchiveFile;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
 use rustc_codegen_ssa::back::symbol_export;
-use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, TargetMachineFactoryConfig};
+use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
 use rustc_data_structures::fx::FxHashMap;
@@ -706,18 +705,15 @@ pub(crate) unsafe fn optimize_thin_module(
     let dcx = dcx.handle();
 
     let module_name = &thin_module.shared.module_names[thin_module.idx];
-    let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
-    let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(dcx, e))?;
 
     // Right now the implementation we've got only works over serialized
     // modules, so we create a fresh new LLVM context and parse the module
     // into that context. One day, however, we may do this for upstream
     // crates but for locally codegened modules we may be able to reuse
     // that LLVM Context and Module.
-    let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) };
-    let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _;
+    let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx)?;
     let mut module = ModuleCodegen {
-        module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
+        module_llvm,
         name: thin_module.name().to_string(),
         kind: ModuleKind::Regular,
     };
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index e4b3ad19801..df35b5e8426 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2451,10 +2451,10 @@ fn add_order_independent_options(
     }
 
     if sess.target.os == "emscripten" {
-        cmd.cc_arg(if sess.panic_strategy() == PanicStrategy::Abort {
-            "-sDISABLE_EXCEPTION_CATCHING=1"
-        } else if sess.opts.unstable_opts.emscripten_wasm_eh {
+        cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh {
             "-fwasm-exceptions"
+        } else if sess.panic_strategy() == PanicStrategy::Abort {
+            "-sDISABLE_EXCEPTION_CATCHING=1"
         } else {
             "-sDISABLE_EXCEPTION_CATCHING=0"
         });
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 6707ebe7d1c..7d103055a7c 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -14,9 +14,11 @@ use rustc_middle::ty::{
     self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
     suggest_constraining_type_param,
 };
-use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
 use rustc_session::parse::add_feature_diagnostics;
 use rustc_span::{BytePos, Pos, Span, Symbol, sym};
+use rustc_trait_selection::error_reporting::traits::call_kind::{
+    CallDesugaringKind, CallKind, call_kind,
+};
 use rustc_trait_selection::traits::SelectionContext;
 use tracing::debug;
 
@@ -324,10 +326,12 @@ fn build_error_for_const_call<'tcx>(
             note_trait_if_possible(&mut err, self_ty, trait_id);
             err
         }
-        CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
+        CallKind::DerefCoercion { deref_target_span, deref_target_ty, self_ty } => {
             // Check first whether the source is accessible (issue #87060)
-            let target = if tcx.sess.source_map().is_span_accessible(deref_target) {
-                Some(deref_target)
+            let target = if let Some(deref_target_span) = deref_target_span
+                && tcx.sess.source_map().is_span_accessible(deref_target_span)
+            {
+                Some(deref_target_span)
             } else {
                 None
             };
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 6db512ace1b..0b034a2ae10 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -68,6 +68,16 @@ impl UnstableFeatures {
     /// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
     /// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
     pub fn from_environment(krate: Option<&str>) -> Self {
+        Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"))
+    }
+
+    /// Avoid unsafe `std::env::set_var()` by allowing tests to inject
+    /// `std::env::var("RUSTC_BOOTSTRAP")` with the `env_var_rustc_bootstrap`
+    /// arg.
+    fn from_environment_value(
+        krate: Option<&str>,
+        env_var_rustc_bootstrap: Result<String, std::env::VarError>,
+    ) -> Self {
         // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
         let disable_unstable_features =
             option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
@@ -75,7 +85,7 @@ impl UnstableFeatures {
         let is_unstable_crate =
             |var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
 
-        let bootstrap = std::env::var("RUSTC_BOOTSTRAP").ok();
+        let bootstrap = env_var_rustc_bootstrap.ok();
         if let Some(val) = bootstrap.as_deref() {
             match val {
                 val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,
diff --git a/compiler/rustc_feature/src/tests.rs b/compiler/rustc_feature/src/tests.rs
index cc0e1f31209..a5d589171d1 100644
--- a/compiler/rustc_feature/src/tests.rs
+++ b/compiler/rustc_feature/src/tests.rs
@@ -2,9 +2,11 @@ use super::UnstableFeatures;
 
 #[test]
 fn rustc_bootstrap_parsing() {
-    let is_bootstrap = |env, krate| {
-        std::env::set_var("RUSTC_BOOTSTRAP", env);
-        matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat)
+    let is_bootstrap = |env: &str, krate: Option<&str>| {
+        matches!(
+            UnstableFeatures::from_environment_value(krate, Ok(env.to_string())),
+            UnstableFeatures::Cheat
+        )
     };
     assert!(is_bootstrap("1", None));
     assert!(is_bootstrap("1", Some("x")));
@@ -22,9 +24,11 @@ fn rustc_bootstrap_parsing() {
     assert!(!is_bootstrap("0", None));
 
     // `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed.
-    let is_force_stable = |krate| {
-        std::env::set_var("RUSTC_BOOTSTRAP", "-1");
-        matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Disallow)
+    let is_force_stable = |krate: Option<&str>| {
+        matches!(
+            UnstableFeatures::from_environment_value(krate, Ok("-1".to_string())),
+            UnstableFeatures::Disallow
+        )
     };
     assert!(is_force_stable(None));
     // Does not support specifying any crate.
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 974a8648bc0..ec82644ea5b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -436,9 +436,9 @@ fn check_opaque_meets_bounds<'tcx>(
     } else {
         // Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
         for (mut key, mut ty) in infcx.take_opaque_types() {
-            ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
+            ty.ty = infcx.resolve_vars_if_possible(ty.ty);
             key = infcx.resolve_vars_if_possible(key);
-            sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
+            sanity_check_found_hidden_type(tcx, key, ty)?;
         }
         Ok(())
     }
@@ -1873,7 +1873,7 @@ pub(super) fn check_coroutine_obligations(
         // Check that any hidden types found when checking these stalled coroutine obligations
         // are valid.
         for (key, ty) in infcx.take_opaque_types() {
-            let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
+            let hidden_type = infcx.resolve_vars_if_possible(ty);
             let key = infcx.resolve_vars_if_possible(key);
             sanity_check_found_hidden_type(tcx, key, hidden_type)?;
         }
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 56f7a2c1150..367e7c6de95 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -85,6 +85,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.annotate_expected_due_to_let_ty(err, expr, error);
         self.annotate_loop_expected_due_to_inference(err, expr, error);
+        if self.annotate_mut_binding_to_immutable_binding(err, expr, error) {
+            return;
+        }
 
         // FIXME(#73154): For now, we do leak check when coercing function
         // pointers in typeck, instead of only during borrowck. This can lead
@@ -795,6 +798,98 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Detect the following case
+    ///
+    /// ```text
+    /// fn change_object(mut a: &Ty) {
+    ///     let a = Ty::new();
+    ///     b = a;
+    /// }
+    /// ```
+    ///
+    /// where the user likely meant to modify the value behind there reference, use `a` as an out
+    /// parameter, instead of mutating the local binding. When encountering this we suggest:
+    ///
+    /// ```text
+    /// fn change_object(a: &'_ mut Ty) {
+    ///     let a = Ty::new();
+    ///     *b = a;
+    /// }
+    /// ```
+    fn annotate_mut_binding_to_immutable_binding(
+        &self,
+        err: &mut Diag<'_>,
+        expr: &hir::Expr<'_>,
+        error: Option<TypeError<'tcx>>,
+    ) -> bool {
+        if let Some(TypeError::Sorts(ExpectedFound { expected, found })) = error
+            && let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()
+
+            // The difference between the expected and found values is one level of borrowing.
+            && self.can_eq(self.param_env, *inner, found)
+
+            // We have an `ident = expr;` assignment.
+            && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
+                self.tcx.parent_hir_node(expr.hir_id)
+            && rhs.hir_id == expr.hir_id
+
+            // We are assigning to some binding.
+            && let hir::ExprKind::Path(hir::QPath::Resolved(
+                None,
+                hir::Path { res: hir::def::Res::Local(hir_id), .. },
+            )) = lhs.kind
+            && let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id)
+
+            // The pattern we have is an fn argument.
+            && let hir::Node::Param(hir::Param { ty_span, .. }) =
+                self.tcx.parent_hir_node(pat.hir_id)
+            && let item = self.tcx.hir().get_parent_item(pat.hir_id)
+            && let item = self.tcx.hir_owner_node(item)
+            && let Some(fn_decl) = item.fn_decl()
+
+            // We have a mutable binding in the argument.
+            && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind
+
+            // Look for the type corresponding to the argument pattern we have in the argument list.
+            && let Some(ty_sugg) = fn_decl
+                .inputs
+                .iter()
+                .filter_map(|ty| {
+                    if ty.span == *ty_span
+                        && let hir::TyKind::Ref(lt, x) = ty.kind
+                    {
+                        // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
+                        Some((
+                            x.ty.span.shrink_to_lo(),
+                            format!(
+                                "{}mut ",
+                                if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }
+                            ),
+                        ))
+                    } else {
+                        None
+                    }
+                })
+                .next()
+        {
+            let sugg = vec![
+                ty_sugg,
+                (pat.span.until(ident.span), String::new()),
+                (lhs.span.shrink_to_lo(), "*".to_string()),
+            ];
+            // We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
+            // assignment from `ident = val;` to `*ident = val;`.
+            err.multipart_suggestion_verbose(
+                "you might have meant to mutate the pointed at value being passed in, instead of \
+                changing the reference in the local binding",
+                sugg,
+                Applicability::MaybeIncorrect,
+            );
+            return true;
+        }
+        false
+    }
+
     fn annotate_alternative_method_deref(
         &self,
         err: &mut Diag<'_>,
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 7c5838db586..683cacdff7d 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -562,9 +562,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         // types or by using this function at the end of writeback and running it as a
         // fixpoint.
         let opaque_types = self.fcx.infcx.clone_opaque_types();
-        for (opaque_type_key, decl) in opaque_types {
-            let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span);
-            let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span);
+        for (opaque_type_key, hidden_type) in opaque_types {
+            let hidden_type = self.resolve(hidden_type, &hidden_type.span);
+            let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);
 
             if !self.fcx.next_trait_solver() {
                 if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index d5aab4781de..23f63af778d 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -155,12 +155,12 @@ impl<'tcx> InferCtxt<'tcx> {
             .opaque_type_storage
             .opaque_types
             .iter()
-            .map(|(k, v)| (*k, v.hidden_type.ty))
+            .map(|(k, v)| (*k, v.ty))
             .collect()
     }
 
     fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
-        self.take_opaque_types().into_iter().map(|(k, v)| (k, v.hidden_type.ty)).collect()
+        self.take_opaque_types().into_iter().map(|(k, v)| (k, v.ty)).collect()
     }
 
     /// Given the (canonicalized) result to a canonical query,
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1f7180fb80a..283ebdfa236 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -234,7 +234,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
     pub fn iter_opaque_types(
         &self,
     ) -> impl Iterator<Item = (ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>)> + '_ {
-        self.opaque_type_storage.opaque_types.iter().map(|(&k, v)| (k, v.hidden_type))
+        self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v))
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 137d438a479..f6ef3f40e62 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -19,20 +19,9 @@ use crate::traits::{self, Obligation, PredicateObligations};
 
 mod table;
 
-pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
+pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>;
 pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
 
-/// Information about the opaque types whose values we
-/// are inferring in this function (these are the `impl Trait` that
-/// appear in the return type).
-#[derive(Clone, Debug)]
-pub struct OpaqueTypeDecl<'tcx> {
-    /// The hidden types that have been inferred for this opaque type.
-    /// There can be multiple, but they are all `lub`ed together at the end
-    /// to obtain the canonical hidden type.
-    pub hidden_type: OpaqueHiddenType<'tcx>,
-}
-
 impl<'tcx> InferCtxt<'tcx> {
     /// This is a backwards compatibility hack to prevent breaking changes from
     /// lazy TAIT around RPIT handling.
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index 047d8edad3d..ba6cc0d783d 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -3,7 +3,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
 use tracing::instrument;
 
-use super::{OpaqueTypeDecl, OpaqueTypeMap};
+use super::OpaqueTypeMap;
 use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
 
 #[derive(Default, Debug, Clone)]
@@ -11,15 +11,19 @@ pub(crate) struct OpaqueTypeStorage<'tcx> {
     /// Opaque types found in explicit return types and their
     /// associated fresh inference variable. Writeback resolves these
     /// variables to get the concrete type, which can be used to
-    /// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
+    /// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
     pub opaque_types: OpaqueTypeMap<'tcx>,
 }
 
 impl<'tcx> OpaqueTypeStorage<'tcx> {
     #[instrument(level = "debug")]
-    pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
-        if let Some(idx) = idx {
-            self.opaque_types.get_mut(&key).unwrap().hidden_type = idx;
+    pub(crate) fn remove(
+        &mut self,
+        key: OpaqueTypeKey<'tcx>,
+        prev: Option<OpaqueHiddenType<'tcx>>,
+    ) {
+        if let Some(prev) = prev {
+            *self.opaque_types.get_mut(&key).unwrap() = prev;
         } else {
             // FIXME(#120456) - is `swap_remove` correct?
             match self.opaque_types.swap_remove(&key) {
@@ -59,13 +63,12 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
         key: OpaqueTypeKey<'tcx>,
         hidden_type: OpaqueHiddenType<'tcx>,
     ) -> Option<Ty<'tcx>> {
-        if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
-            let prev = std::mem::replace(&mut decl.hidden_type, hidden_type);
+        if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
+            let prev = std::mem::replace(entry, hidden_type);
             self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
             return Some(prev.ty);
         }
-        let decl = OpaqueTypeDecl { hidden_type };
-        self.storage.opaque_types.insert(key, decl);
+        self.storage.opaque_types.insert(key, hidden_type);
         self.undo_log.push(UndoLog::OpaqueTypes(key, None));
         None
     }
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 7f603f6a655..44f86535527 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -99,7 +99,7 @@ declare_lint! {
     /// To fix this, remove the `use<'a>`, since the lifetime is already captured
     /// since it is in scope.
     pub IMPL_TRAIT_REDUNDANT_CAPTURES,
-    Warn,
+    Allow,
     "redundant precise-capturing `use<...>` syntax on an `impl Trait`",
 }
 
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 47522f00bb1..24d2478f770 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1555,16 +1555,22 @@ pub fn write_allocations<'tcx>(
                 write!(w, " (vtable: impl {dyn_ty} for {ty})")?
             }
             Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
-                match tcx.eval_static_initializer(did) {
-                    Ok(alloc) => {
-                        write!(w, " (static: {}, ", tcx.def_path_str(did))?;
-                        write_allocation_track_relocs(w, alloc)?;
+                write!(w, " (static: {}", tcx.def_path_str(did))?;
+                if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup)
+                    && tcx.hir().body_const_context(body.source.def_id()).is_some()
+                {
+                    // Statics may be cyclic and evaluating them too early
+                    // in the MIR pipeline may cause cycle errors even though
+                    // normal compilation is fine.
+                    write!(w, ")")?;
+                } else {
+                    match tcx.eval_static_initializer(did) {
+                        Ok(alloc) => {
+                            write!(w, ", ")?;
+                            write_allocation_track_relocs(w, alloc)?;
+                        }
+                        Err(_) => write!(w, ", error during initializer evaluation)")?,
                     }
-                    Err(_) => write!(
-                        w,
-                        " (static: {}, error during initializer evaluation)",
-                        tcx.def_path_str(did)
-                    )?,
                 }
             }
             Some(GlobalAlloc::Static(did)) => {
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 3337f7ceee7..2cb6f6d8c6e 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -548,7 +548,6 @@ macro_rules! define_feedable {
                         let dep_node_index = tcx.dep_graph.with_feed_task(
                             dep_node,
                             tcx,
-                            key,
                             &value,
                             hash_result!([$($modifiers)*]),
                         );
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 49b5588e261..e4ded2c30f5 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -5,7 +5,7 @@ use std::path::PathBuf;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
-use rustc_hir::def::Namespace;
+use rustc_hir::def::{CtorKind, DefKind, Namespace};
 use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::FiniteBitSet;
@@ -498,7 +498,8 @@ impl<'tcx> Instance<'tcx> {
 
     /// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
     /// this is used to find the precise code that will run for a trait method invocation,
-    /// if known.
+    /// if known. This should only be used for functions and consts. If you want to
+    /// resolve an associated type, use [`TyCtxt::try_normalize_erasing_regions`].
     ///
     /// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance.
     /// For example, in a context like this,
@@ -527,6 +528,23 @@ impl<'tcx> Instance<'tcx> {
         def_id: DefId,
         args: GenericArgsRef<'tcx>,
     ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
+        assert_matches!(
+            tcx.def_kind(def_id),
+            DefKind::Fn
+                | DefKind::AssocFn
+                | DefKind::Const
+                | DefKind::AssocConst
+                | DefKind::AnonConst
+                | DefKind::InlineConst
+                | DefKind::Static { .. }
+                | DefKind::Ctor(_, CtorKind::Fn)
+                | DefKind::Closure
+                | DefKind::SyntheticCoroutineBody,
+            "`Instance::try_resolve` should only be used to resolve instances of \
+            functions, statics, and consts; to resolve associated types, use \
+            `try_normalize_erasing_regions`."
+        );
+
         // Rust code can easily create exponentially-long types using only a
         // polynomial recursion depth. Even with the default recursion
         // depth, you can easily get cases that take >2^60 steps to run,
diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs
index 8dafc422644..097a868191c 100644
--- a/compiler/rustc_middle/src/util/mod.rs
+++ b/compiler/rustc_middle/src/util/mod.rs
@@ -1,9 +1,7 @@
 pub mod bug;
-pub mod call_kind;
 pub mod common;
 pub mod find_self_call;
 
-pub use call_kind::{CallDesugaringKind, CallKind, call_kind};
 pub use find_self_call::find_self_call;
 
 #[derive(Default, Copy, Clone)]
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 9df396cbf7a..3ed600a717f 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -799,6 +799,9 @@ passes_unused_assign = value assigned to `{$name}` is never read
 passes_unused_assign_passed = value passed to `{$name}` is never read
     .help = maybe it is overwritten before being read?
 
+passes_unused_assign_suggestion =
+    you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
+
 passes_unused_capture_maybe_capture_ref = value captured by `{$name}` is never read
     .help = did you mean to capture by reference instead?
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 13da021c614..c3043ac60aa 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1787,9 +1787,26 @@ pub(crate) struct IneffectiveUnstableImpl;
 
 #[derive(LintDiagnostic)]
 #[diag(passes_unused_assign)]
-#[help]
 pub(crate) struct UnusedAssign {
     pub name: String,
+    #[subdiagnostic]
+    pub suggestion: Option<UnusedAssignSuggestion>,
+    #[help]
+    pub help: bool,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(passes_unused_assign_suggestion, applicability = "maybe-incorrect")]
+pub(crate) struct UnusedAssignSuggestion {
+    pub pre: &'static str,
+    #[suggestion_part(code = "{pre}mut ")]
+    pub ty_span: Span,
+    #[suggestion_part(code = "")]
+    pub ty_ref_span: Span,
+    #[suggestion_part(code = "*")]
+    pub ident_span: Span,
+    #[suggestion_part(code = "")]
+    pub expr_ref_span: Span,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index b85a987c641..426899a4d5c 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1360,7 +1360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
     fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) {
         self.check_unused_vars_in_pat(local.pat, None, None, |spans, hir_id, ln, var| {
             if local.init.is_some() {
-                self.warn_about_dead_assign(spans, hir_id, ln, var);
+                self.warn_about_dead_assign(spans, hir_id, ln, var, None);
             }
         });
 
@@ -1460,7 +1460,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
                     // as being used.
                     let ln = self.live_node(expr.hir_id, expr.span);
                     let var = self.variable(var_hid, expr.span);
-                    self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var);
+                    let sugg = self.annotate_mut_binding_to_immutable_binding(var_hid, expr);
+                    self.warn_about_dead_assign(vec![expr.span], expr.hir_id, ln, var, sugg);
                 }
             }
             _ => {
@@ -1585,6 +1586,70 @@ impl<'tcx> Liveness<'_, 'tcx> {
         }
     }
 
+    /// Detect the following case
+    ///
+    /// ```text
+    /// fn change_object(mut a: &Ty) {
+    ///     let a = Ty::new();
+    ///     b = &a;
+    /// }
+    /// ```
+    ///
+    /// where the user likely meant to modify the value behind there reference, use `a` as an out
+    /// parameter, instead of mutating the local binding. When encountering this we suggest:
+    ///
+    /// ```text
+    /// fn change_object(a: &'_ mut Ty) {
+    ///     let a = Ty::new();
+    ///     *b = a;
+    /// }
+    /// ```
+    fn annotate_mut_binding_to_immutable_binding(
+        &self,
+        var_hid: HirId,
+        expr: &'tcx Expr<'tcx>,
+    ) -> Option<errors::UnusedAssignSuggestion> {
+        if let hir::Node::Expr(parent) = self.ir.tcx.parent_hir_node(expr.hir_id)
+            && let hir::ExprKind::Assign(_, rhs, _) = parent.kind
+            && let hir::ExprKind::AddrOf(borrow_kind, _mut, inner) = rhs.kind
+            && let hir::BorrowKind::Ref = borrow_kind
+            && let hir::Node::Pat(pat) = self.ir.tcx.hir_node(var_hid)
+            && let hir::Node::Param(hir::Param { ty_span, .. }) =
+                self.ir.tcx.parent_hir_node(pat.hir_id)
+            && let item_id = self.ir.tcx.hir().get_parent_item(pat.hir_id)
+            && let item = self.ir.tcx.hir_owner_node(item_id)
+            && let Some(fn_decl) = item.fn_decl()
+            && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind
+            && let Some((ty_span, pre)) = fn_decl
+                .inputs
+                .iter()
+                .filter_map(|ty| {
+                    if ty.span == *ty_span
+                        && let hir::TyKind::Ref(lt, mut_ty) = ty.kind
+                    {
+                        // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
+                        Some((
+                            mut_ty.ty.span.shrink_to_lo(),
+                            if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " },
+                        ))
+                    } else {
+                        None
+                    }
+                })
+                .next()
+        {
+            Some(errors::UnusedAssignSuggestion {
+                ty_span,
+                pre,
+                ty_ref_span: pat.span.until(ident.span),
+                ident_span: expr.span.shrink_to_lo(),
+                expr_ref_span: rhs.span.until(inner.span),
+            })
+        } else {
+            None
+        }
+    }
+
     #[instrument(skip(self), level = "INFO")]
     fn report_unused(
         &self,
@@ -1738,15 +1803,23 @@ impl<'tcx> Liveness<'_, 'tcx> {
         suggs
     }
 
-    fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
+    fn warn_about_dead_assign(
+        &self,
+        spans: Vec<Span>,
+        hir_id: HirId,
+        ln: LiveNode,
+        var: Variable,
+        suggestion: Option<errors::UnusedAssignSuggestion>,
+    ) {
         if !self.live_on_exit(ln, var)
             && let Some(name) = self.should_warn(var)
         {
+            let help = suggestion.is_none();
             self.ir.tcx.emit_node_span_lint(
                 lint::builtin::UNUSED_ASSIGNMENTS,
                 hir_id,
                 spans,
-                errors::UnusedAssign { name },
+                errors::UnusedAssign { name, suggestion, help },
             );
         }
     }
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 4b47ce8389c..fa095b10884 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -376,25 +376,8 @@ impl<D: Deps> DepGraphData<D> {
         };
 
         let dcx = cx.dep_context();
-        let hashing_timer = dcx.profiler().incr_result_hashing();
-        let current_fingerprint =
-            hash_result.map(|f| dcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, &result)));
-
-        // Intern the new `DepNode`.
-        let (dep_node_index, prev_and_color) =
-            self.current.intern_node(&self.previous, key, edges, current_fingerprint);
-
-        hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-        if let Some((prev_index, color)) = prev_and_color {
-            debug_assert!(
-                self.colors.get(prev_index).is_none(),
-                "DepGraph::with_task() - Duplicate DepNodeColor \
-                            insertion for {key:?}"
-            );
-
-            self.colors.insert(prev_index, color);
-        }
+        let dep_node_index =
+            self.hash_result_and_intern_node(dcx, key, edges, &result, hash_result);
 
         (result, dep_node_index)
     }
@@ -462,6 +445,38 @@ impl<D: Deps> DepGraphData<D> {
 
         (result, dep_node_index)
     }
+
+    /// Intern the new `DepNode` with the dependencies up-to-now.
+    fn hash_result_and_intern_node<Ctxt: DepContext<Deps = D>, R>(
+        &self,
+        cx: &Ctxt,
+        node: DepNode,
+        edges: EdgesVec,
+        result: &R,
+        hash_result: Option<fn(&mut StableHashingContext<'_>, &R) -> Fingerprint>,
+    ) -> DepNodeIndex {
+        let hashing_timer = cx.profiler().incr_result_hashing();
+        let current_fingerprint = hash_result.map(|hash_result| {
+            cx.with_stable_hashing_context(|mut hcx| hash_result(&mut hcx, result))
+        });
+
+        // Intern the new `DepNode` with the dependencies up-to-now.
+        let (dep_node_index, prev_and_color) =
+            self.current.intern_node(&self.previous, node, edges, current_fingerprint);
+
+        hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
+
+        if let Some((prev_index, color)) = prev_and_color {
+            debug_assert!(
+                self.colors.get(prev_index).is_none(),
+                "DepGraph::with_task() - Duplicate DepNodeColor insertion for {node:?}",
+            );
+
+            self.colors.insert(prev_index, color);
+        }
+
+        dep_node_index
+    }
 }
 
 impl<D: Deps> DepGraph<D> {
@@ -536,11 +551,10 @@ impl<D: Deps> DepGraph<D> {
     /// FIXME: If the code is changed enough for this node to be marked before requiring the
     /// caller's node, we suppose that those changes will be enough to mark this node red and
     /// force a recomputation using the "normal" way.
-    pub fn with_feed_task<Ctxt: DepContext<Deps = D>, A: Debug, R: Debug>(
+    pub fn with_feed_task<Ctxt: DepContext<Deps = D>, R: Debug>(
         &self,
         node: DepNode,
         cx: Ctxt,
-        key: A,
         result: &R,
         hash_result: Option<fn(&mut StableHashingContext<'_>, &R) -> Fingerprint>,
     ) -> DepNodeIndex {
@@ -588,27 +602,7 @@ impl<D: Deps> DepGraph<D> {
                 }
             });
 
-            let hashing_timer = cx.profiler().incr_result_hashing();
-            let current_fingerprint = hash_result.map(|hash_result| {
-                cx.with_stable_hashing_context(|mut hcx| hash_result(&mut hcx, result))
-            });
-
-            // Intern the new `DepNode` with the dependencies up-to-now.
-            let (dep_node_index, prev_and_color) =
-                data.current.intern_node(&data.previous, node, edges, current_fingerprint);
-
-            hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
-
-            if let Some((prev_index, color)) = prev_and_color {
-                debug_assert!(
-                    data.colors.get(prev_index).is_none(),
-                    "DepGraph::with_task() - Duplicate DepNodeColor insertion for {key:?}",
-                );
-
-                data.colors.insert(prev_index, color);
-            }
-
-            dep_node_index
+            data.hash_result_and_intern_node(&cx, node, edges, result, hash_result)
         } else {
             // Incremental compilation is turned off. We just execute the task
             // without tracking. We still provide a dep-node index that uniquely
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 746e8173807..6a3899e66e7 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -1,7 +1,7 @@
 use std::str::FromStr;
 use std::{fmt, iter};
 
-pub use rustc_abi::{Reg, RegKind};
+pub use rustc_abi::{ExternAbi, Reg, RegKind};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
 
@@ -9,8 +9,7 @@ use crate::abi::{
     self, AddressSpace, Align, BackendRepr, HasDataLayout, Pointer, Size, TyAbiInterface,
     TyAndLayout,
 };
-use crate::spec::abi::Abi as SpecAbi;
-use crate::spec::{self, HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi};
+use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi};
 
 mod aarch64;
 mod amdgpu;
@@ -627,20 +626,20 @@ impl<'a, Ty: fmt::Display> fmt::Debug for FnAbi<'a, Ty> {
 #[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub enum AdjustForForeignAbiError {
     /// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs.
-    Unsupported { arch: Symbol, abi: spec::abi::Abi },
+    Unsupported { arch: Symbol, abi: ExternAbi },
 }
 
 impl<'a, Ty> FnAbi<'a, Ty> {
     pub fn adjust_for_foreign_abi<C>(
         &mut self,
         cx: &C,
-        abi: spec::abi::Abi,
+        abi: ExternAbi,
     ) -> Result<(), AdjustForForeignAbiError>
     where
         Ty: TyAbiInterface<'a, C> + Copy,
         C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt + HasX86AbiOpt,
     {
-        if abi == spec::abi::Abi::X86Interrupt {
+        if abi == ExternAbi::X86Interrupt {
             if let Some(arg) = self.args.first_mut() {
                 arg.pass_by_stack_offset(None);
             }
@@ -651,12 +650,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         match &spec.arch[..] {
             "x86" => {
                 let (flavor, regparm) = match abi {
-                    spec::abi::Abi::Fastcall { .. } | spec::abi::Abi::Vectorcall { .. } => {
+                    ExternAbi::Fastcall { .. } | ExternAbi::Vectorcall { .. } => {
                         (x86::Flavor::FastcallOrVectorcall, None)
                     }
-                    spec::abi::Abi::C { .. }
-                    | spec::abi::Abi::Cdecl { .. }
-                    | spec::abi::Abi::Stdcall { .. } => {
+                    ExternAbi::C { .. } | ExternAbi::Cdecl { .. } | ExternAbi::Stdcall { .. } => {
                         (x86::Flavor::General, cx.x86_abi_opt().regparm)
                     }
                     _ => (x86::Flavor::General, None),
@@ -666,8 +663,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
                 x86::compute_abi_info(cx, self, opts);
             }
             "x86_64" => match abi {
-                spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
-                spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(cx, self),
+                ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
+                ExternAbi::Win64 { .. } | ExternAbi::Vectorcall { .. } => {
+                    x86_win64::compute_abi_info(cx, self)
+                }
                 _ => {
                     if cx.target_spec().is_like_windows {
                         x86_win64::compute_abi_info(cx, self)
@@ -701,7 +700,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "sparc" => sparc::compute_abi_info(cx, self),
             "sparc64" => sparc64::compute_abi_info(cx, self),
             "nvptx64" => {
-                if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::PtxKernel {
+                if cx.target_spec().adjust_abi(abi, self.c_variadic) == ExternAbi::PtxKernel {
                     nvptx64::compute_ptx_kernel_abi_info(cx, self)
                 } else {
                     nvptx64::compute_abi_info(self)
@@ -730,7 +729,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         Ok(())
     }
 
-    pub fn adjust_for_rust_abi<C>(&mut self, cx: &C, abi: SpecAbi)
+    pub fn adjust_for_rust_abi<C>(&mut self, cx: &C, abi: ExternAbi)
     where
         Ty: TyAbiInterface<'a, C> + Copy,
         C: HasDataLayout + HasTargetSpec,
@@ -821,7 +820,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
                 // that's how we connect up to LLVM and it's unstable
                 // anyway, we control all calls to it in libstd.
                 BackendRepr::Vector { .. }
-                    if abi != SpecAbi::RustIntrinsic && spec.simd_types_indirect =>
+                    if abi != ExternAbi::RustIntrinsic && spec.simd_types_indirect =>
                 {
                     arg.make_indirect();
                     continue;
diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs
index 83d94cb11ba..0944bda2687 100644
--- a/compiler/rustc_target/src/callconv/x86_win64.rs
+++ b/compiler/rustc_target/src/callconv/x86_win64.rs
@@ -5,7 +5,7 @@ use crate::spec::HasTargetSpec;
 
 // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
 
-pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
+pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
     let fixup = |a: &mut ArgAbi<'_, Ty>| {
         match a.layout.backend_repr {
             BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
@@ -40,16 +40,18 @@ pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'
         fixup(&mut fn_abi.ret);
     }
     for arg in fn_abi.args.iter_mut() {
-        if arg.is_ignore() {
-            // x86_64-pc-windows-gnu doesn't ignore ZSTs.
-            if cx.target_spec().os == "windows"
-                && cx.target_spec().env == "gnu"
-                && arg.layout.is_zst()
-            {
-                arg.make_indirect_from_ignore();
-            }
+        if arg.is_ignore() && arg.layout.is_zst() {
+            // Windows ABIs do not talk about ZST since such types do not exist in MSVC.
+            // In that sense we can do whatever we want here, and maybe we should throw an error
+            // (but of course that would be a massive breaking change now).
+            // We try to match clang and gcc (which allow ZST is their windows-gnu targets), so we
+            // pass ZST via pointer indirection.
+            arg.make_indirect_from_ignore();
             continue;
         }
         fixup(arg);
     }
+    // FIXME: We should likely also do something about ZST return types, similar to above.
+    // However, that's non-trivial due to `()`.
+    // See <https://github.com/rust-lang/unsafe-code-guidelines/issues/552>.
 }
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index a149f682c56..beb59f1d5c5 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2815,12 +2815,17 @@ impl Target {
             Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false },
             Abi::EfiApi => Abi::C { unwind: false },
 
-            // See commentary in `is_abi_supported`.
-            Abi::Stdcall { .. } | Abi::Thiscall { .. } if self.arch == "x86" => abi,
-            Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => Abi::C { unwind },
-            Abi::Fastcall { .. } if self.arch == "x86" => abi,
+            // See commentary in `is_abi_supported`: we map these ABIs to "C" when they do not make sense.
+            Abi::Stdcall { .. } | Abi::Thiscall { .. } | Abi::Fastcall { .. }
+                if self.arch == "x86" =>
+            {
+                abi
+            }
             Abi::Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi,
-            Abi::Fastcall { unwind } | Abi::Vectorcall { unwind } => Abi::C { unwind },
+            Abi::Stdcall { unwind }
+            | Abi::Thiscall { unwind }
+            | Abi::Fastcall { unwind }
+            | Abi::Vectorcall { unwind } => Abi::C { unwind },
 
             // The Windows x64 calling convention we use for `extern "Rust"`
             // <https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions#register-volatility-and-preservation>
diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
index 0e395331687..1c3e570b676 100644
--- a/compiler/rustc_middle/src/util/call_kind.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
@@ -2,12 +2,14 @@
 //! as well as errors when attempting to call a non-const function in a const
 //! context.
 
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, lang_items};
+use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
 use rustc_span::{DesugaringKind, Ident, Span, sym};
 use tracing::debug;
 
-use crate::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
+use crate::traits::specialization_graph;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub enum CallDesugaringKind {
@@ -55,7 +57,7 @@ pub enum CallKind<'tcx> {
     DerefCoercion {
         /// The `Span` of the `Target` associated type
         /// in the `Deref` impl we are using.
-        deref_target: Span,
+        deref_target_span: Option<Span>,
         /// The type `T::Deref` we are dereferencing to
         deref_target_ty: Ty<'tcx>,
         self_ty: Ty<'tcx>,
@@ -89,61 +91,65 @@ pub fn call_kind<'tcx>(
         None
     };
 
-    let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did);
-
     // Check for a 'special' use of 'self' -
     // an FnOnce call, an operator (e.g. `<<`), or a
     // deref coercion.
-    let kind = if let Some(trait_id) = fn_call {
-        Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) })
+    if let Some(trait_id) = fn_call {
+        return CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_args.type_at(0) };
     } else if let Some(trait_id) = operator {
-        Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) })
-    } else if is_deref {
-        let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
-            Instance::try_resolve(tcx, typing_env, deref_target, method_args).transpose()
-        });
-        if let Some(Ok(instance)) = deref_target {
-            let deref_target_ty = instance.ty(tcx, typing_env);
-            Some(CallKind::DerefCoercion {
-                deref_target: tcx.def_span(instance.def_id()),
-                deref_target_ty,
-                self_ty: method_args.type_at(0),
-            })
+        return CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) };
+    } else if !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did) {
+        let deref_target_def_id =
+            tcx.get_diagnostic_item(sym::deref_target).expect("deref method but no deref target");
+        let deref_target_ty = tcx.normalize_erasing_regions(
+            typing_env,
+            Ty::new_projection(tcx, deref_target_def_id, method_args),
+        );
+        let deref_target_span = if let Ok(Some(instance)) =
+            Instance::try_resolve(tcx, typing_env, method_did, method_args)
+            && let instance_parent_def_id = tcx.parent(instance.def_id())
+            && matches!(tcx.def_kind(instance_parent_def_id), DefKind::Impl { .. })
+            && let Ok(instance) =
+                specialization_graph::assoc_def(tcx, instance_parent_def_id, deref_target_def_id)
+            && instance.is_final()
+        {
+            Some(tcx.def_span(instance.item.def_id))
+        } else {
+            None
+        };
+        return CallKind::DerefCoercion {
+            deref_target_ty,
+            deref_target_span,
+            self_ty: method_args.type_at(0),
+        };
+    }
+
+    // This isn't a 'special' use of `self`
+    debug!(?method_did, ?fn_call_span);
+    let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter)
+        && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
+    {
+        Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
+    } else if tcx.is_lang_item(method_did, LangItem::IteratorNext)
+        && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
+    {
+        Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0)))
+    } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
+        if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) {
+            Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
+        } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) {
+            Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
         } else {
             None
         }
+    } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput)
+        && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
+    {
+        Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))
+    } else if fn_call_span.is_desugaring(DesugaringKind::Await) {
+        Some((CallDesugaringKind::Await, method_args.type_at(0)))
     } else {
         None
     };
-
-    kind.unwrap_or_else(|| {
-        // This isn't a 'special' use of `self`
-        debug!(?method_did, ?fn_call_span);
-        let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter)
-            && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
-        {
-            Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
-        } else if tcx.is_lang_item(method_did, LangItem::IteratorNext)
-            && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
-        {
-            Some((CallDesugaringKind::ForLoopNext, method_args.type_at(0)))
-        } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
-            if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) {
-                Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
-            } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) {
-                Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
-            } else {
-                None
-            }
-        } else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput)
-            && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
-        {
-            Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))
-        } else if fn_call_span.is_desugaring(DesugaringKind::Await) {
-            Some((CallDesugaringKind::Await, method_args.type_at(0)))
-        } else {
-            None
-        };
-        CallKind::Normal { self_arg, desugaring, method_did, method_args }
-    })
+    CallKind::Normal { self_arg, desugaring, method_did, method_args }
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index b108a9352a5..cd4f77bb4cf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -1,4 +1,5 @@
 pub mod ambiguity;
+pub mod call_kind;
 mod fulfillment_errors;
 pub mod on_unimplemented;
 mod overflow;
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 69b7d5cff1e..aae0e34ddf3 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1148,7 +1148,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         // If returned by `struct_tail` this is the empty tuple.
                         | ty::Tuple(..)
                         // Integers and floats are always Sized, and so have unit type metadata.
-                        | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
+                        | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..))
+                        // This happens if we reach the recursion limit when finding the struct tail.
+                        | ty::Error(..) => true,
 
                         // We normalize from `Wrapper<Tail>::Metadata` to `Tail::Metadata` if able.
                         // Otherwise, type parameters, opaques, and unnormalized projections have
@@ -1179,8 +1181,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         | ty::Alias(..)
                         | ty::Bound(..)
                         | ty::Placeholder(..)
-                        | ty::Infer(..)
-                        | ty::Error(_) => {
+                        | ty::Infer(..) => {
                             if tail.has_infer_types() {
                                 candidate_set.mark_ambiguous();
                             }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 3a706d5f36b..cd2afd7a473 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -3587,7 +3587,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// with the given `replace_with` iterator and yields the removed items.
     /// `replace_with` does not need to be the same length as `range`.
     ///
-    /// `range` is removed even if the iterator is not consumed until the end.
+    /// `range` is removed even if the `Splice` iterator is not consumed before it is dropped.
     ///
     /// It is unspecified how many elements are removed from the vector
     /// if the `Splice` value is leaked.
@@ -3613,8 +3613,18 @@ impl<T, A: Allocator> Vec<T, A> {
     /// let mut v = vec![1, 2, 3, 4];
     /// let new = [7, 8, 9];
     /// let u: Vec<_> = v.splice(1..3, new).collect();
-    /// assert_eq!(v, &[1, 7, 8, 9, 4]);
-    /// assert_eq!(u, &[2, 3]);
+    /// assert_eq!(v, [1, 7, 8, 9, 4]);
+    /// assert_eq!(u, [2, 3]);
+    /// ```
+    ///
+    /// Using `splice` to insert new items into a vector efficiently at a specific position
+    /// indicated by an empty range:
+    ///
+    /// ```
+    /// let mut v = vec![1, 5];
+    /// let new = [2, 3, 4];
+    /// v.splice(1..1, new);
+    /// assert_eq!(v, [1, 2, 3, 4, 5]);
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 35e920ab344..7fd08a97f1f 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -298,7 +298,7 @@ where
 }
 
 // Detect scheme on Redox
-fn has_redox_scheme(s: &[u8]) -> bool {
+pub(crate) fn has_redox_scheme(s: &[u8]) -> bool {
     cfg!(target_os = "redox") && s.contains(&b':')
 }
 
@@ -2155,7 +2155,7 @@ impl Path {
         unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) }
     }
     // The following (private!) function reveals the byte encoding used for OsStr.
-    fn as_u8_slice(&self) -> &[u8] {
+    pub(crate) fn as_u8_slice(&self) -> &[u8] {
         self.inner.as_encoded_bytes()
     }
 
@@ -2323,14 +2323,7 @@ impl Path {
     #[must_use]
     #[allow(deprecated)]
     pub fn is_absolute(&self) -> bool {
-        if cfg!(target_os = "redox") {
-            // FIXME: Allow Redox prefixes
-            self.has_root() || has_redox_scheme(self.as_u8_slice())
-        } else {
-            self.has_root()
-                && (cfg!(any(unix, target_os = "hermit", target_os = "wasi"))
-                    || self.prefix().is_some())
-        }
+        sys::path::is_absolute(self)
     }
 
     /// Returns `true` if the `Path` is relative, i.e., not absolute.
@@ -2353,7 +2346,7 @@ impl Path {
         !self.is_absolute()
     }
 
-    fn prefix(&self) -> Option<Prefix<'_>> {
+    pub(crate) fn prefix(&self) -> Option<Prefix<'_>> {
         self.components().prefix
     }
 
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index b2492238bd3..24a362072ab 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -67,7 +67,7 @@ macro_rules! rtunwrap {
     };
 }
 
-fn handle_rt_panic(e: Box<dyn Any + Send>) {
+fn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T {
     mem::forget(e);
     rtabort!("initialization or cleanup bug");
 }
@@ -157,7 +157,7 @@ fn lang_start_internal(
     argc: isize,
     argv: *const *const u8,
     sigpipe: u8,
-) -> Result<isize, !> {
+) -> isize {
     // Guard against the code called by this function from unwinding outside of the Rust-controlled
     // code, which is UB. This is a requirement imposed by a combination of how the
     // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
@@ -168,19 +168,33 @@ fn lang_start_internal(
     // panic is a std implementation bug. A quite likely one too, as there isn't any way to
     // prevent std from accidentally introducing a panic to these functions. Another is from
     // user code from `main` or, more nefariously, as described in e.g. issue #86030.
-    // SAFETY: Only called once during runtime initialization.
-    panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) })
-        .unwrap_or_else(handle_rt_panic);
-    let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
-        .map_err(move |e| {
-            mem::forget(e);
-            rtabort!("drop of the panic payload panicked");
+    //
+    // We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in
+    // case of a panic a bit nicer.
+    panic::catch_unwind(move || {
+        // SAFETY: Only called once during runtime initialization.
+        unsafe { init(argc, argv, sigpipe) };
+
+        let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| {
+            // Carefully dispose of the panic payload.
+            let payload = panic::AssertUnwindSafe(payload);
+            panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| {
+                mem::forget(e); // do *not* drop the 2nd payload
+                rtabort!("drop of the panic payload panicked");
+            });
+            // Return error code for panicking programs.
+            101
         });
-    panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic);
-    // Guard against multiple threads calling `libc::exit` concurrently.
-    // See the documentation for `unique_thread_exit` for more information.
-    panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic);
-    ret_code
+        let ret_code = ret_code as isize;
+
+        cleanup();
+        // Guard against multiple threads calling `libc::exit` concurrently.
+        // See the documentation for `unique_thread_exit` for more information.
+        crate::sys::exit_guard::unique_thread_exit();
+
+        ret_code
+    })
+    .unwrap_or_else(handle_rt_panic)
 }
 
 #[cfg(not(any(test, doctest)))]
@@ -191,11 +205,10 @@ fn lang_start<T: crate::process::Termination + 'static>(
     argv: *const *const u8,
     sigpipe: u8,
 ) -> isize {
-    let Ok(v) = lang_start_internal(
+    lang_start_internal(
         &move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
         argc,
         argv,
         sigpipe,
-    );
-    v
+    )
 }
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 47d9add72b5..7504a0f7ad7 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -222,14 +222,14 @@ pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>>
     NonNull::new(runtime_services)
 }
 
-pub(crate) struct DevicePath(NonNull<r_efi::protocols::device_path::Protocol>);
+pub(crate) struct OwnedDevicePath(NonNull<r_efi::protocols::device_path::Protocol>);
 
-impl DevicePath {
+impl OwnedDevicePath {
     pub(crate) fn from_text(p: &OsStr) -> io::Result<Self> {
         fn inner(
             p: &OsStr,
             protocol: NonNull<r_efi::protocols::device_path_from_text::Protocol>,
-        ) -> io::Result<DevicePath> {
+        ) -> io::Result<OwnedDevicePath> {
             let path_vec = p.encode_wide().chain(Some(0)).collect::<Vec<u16>>();
             if path_vec[..path_vec.len() - 1].contains(&0) {
                 return Err(const_error!(
@@ -242,7 +242,7 @@ impl DevicePath {
                 unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) };
 
             NonNull::new(path)
-                .map(DevicePath)
+                .map(OwnedDevicePath)
                 .ok_or_else(|| const_error!(io::ErrorKind::InvalidFilename, "Invalid Device Path"))
         }
 
@@ -275,12 +275,12 @@ impl DevicePath {
         ))
     }
 
-    pub(crate) fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
+    pub(crate) const fn as_ptr(&self) -> *mut r_efi::protocols::device_path::Protocol {
         self.0.as_ptr()
     }
 }
 
-impl Drop for DevicePath {
+impl Drop for OwnedDevicePath {
     fn drop(&mut self) {
         if let Some(bt) = boot_services() {
             let bt: NonNull<r_efi::efi::BootServices> = bt.cast();
@@ -291,6 +291,15 @@ impl Drop for DevicePath {
     }
 }
 
+impl crate::fmt::Debug for OwnedDevicePath {
+    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
+        match device_path_to_text(self.0) {
+            Ok(p) => p.fmt(f),
+            Err(_) => f.debug_struct("OwnedDevicePath").finish_non_exhaustive(),
+        }
+    }
+}
+
 pub(crate) struct OwnedProtocol<T> {
     guid: r_efi::efi::Guid,
     handle: NonNull<crate::ffi::c_void>,
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index 95707ebb7f0..1a0754134df 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -326,7 +326,7 @@ mod uefi_command_internal {
 
     impl Image {
         pub fn load_image(p: &OsStr) -> io::Result<Self> {
-            let path = helpers::DevicePath::from_text(p)?;
+            let path = helpers::OwnedDevicePath::from_text(p)?;
             let boot_services: NonNull<r_efi::efi::BootServices> = boot_services()
                 .ok_or_else(|| const_error!(io::ErrorKind::NotFound, "Boot Services not found"))?
                 .cast();
diff --git a/library/std/src/sys/path/sgx.rs b/library/std/src/sys/path/sgx.rs
index c805c15e702..32c7752f605 100644
--- a/library/std/src/sys/path/sgx.rs
+++ b/library/std/src/sys/path/sgx.rs
@@ -23,3 +23,7 @@ pub const MAIN_SEP: char = '/';
 pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
     unsupported()
 }
+
+pub(crate) fn is_absolute(path: &Path) -> bool {
+    path.has_root() && path.prefix().is_some()
+}
diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs
index 2a7c025c3c4..361e99964f1 100644
--- a/library/std/src/sys/path/unix.rs
+++ b/library/std/src/sys/path/unix.rs
@@ -60,3 +60,14 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
 
     Ok(normalized)
 }
+
+pub(crate) fn is_absolute(path: &Path) -> bool {
+    if cfg!(target_os = "redox") {
+        // FIXME: Allow Redox prefixes
+        path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice())
+    } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) {
+        path.has_root()
+    } else {
+        path.has_root() && path.prefix().is_some()
+    }
+}
diff --git a/library/std/src/sys/path/unsupported_backslash.rs b/library/std/src/sys/path/unsupported_backslash.rs
index 855f443678c..30b06c132c9 100644
--- a/library/std/src/sys/path/unsupported_backslash.rs
+++ b/library/std/src/sys/path/unsupported_backslash.rs
@@ -24,3 +24,7 @@ pub const MAIN_SEP: char = '\\';
 pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
     unsupported()
 }
+
+pub(crate) fn is_absolute(path: &Path) -> bool {
+    path.has_root() && path.prefix().is_some()
+}
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index de042fa3f82..1c534721916 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -346,3 +346,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
         os2path,
     )
 }
+
+pub(crate) fn is_absolute(path: &Path) -> bool {
+    path.has_root() && path.prefix().is_some()
+}
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 5322f079214..71c56c4e85e 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -65,7 +65,7 @@ xz2 = "0.1"
 # Dependencies needed by the build-metrics feature
 sysinfo = { version = "0.33.0", default-features = false, optional = true, features = ["system"] }
 
-# Dependencies needed by the `logging` feature
+# Dependencies needed by the `tracing` feature
 tracing = { version = "0.1", optional = true, features = ["attributes"] }
 tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] }
 tracing-tree = { version = "0.4.0", optional = true }
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index d0058eeb43d..9ae03ac7fe0 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -334,7 +334,11 @@ macro_rules! bootstrap_tool {
 }
 
 bootstrap_tool!(
-    Rustbook, "src/tools/rustbook", "rustbook", submodules = SUBMODULES_FOR_RUSTBOOK;
+    // This is marked as an external tool because it includes dependencies
+    // from submodules. Trying to keep the lints in sync between all the repos
+    // is a bit of a pain. Unfortunately it means the rustbook source itself
+    // doesn't deny warnings, but it is a relatively small piece of code.
+    Rustbook, "src/tools/rustbook", "rustbook", is_external_tool = true, submodules = SUBMODULES_FOR_RUSTBOOK;
     UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
     Tidy, "src/tools/tidy", "tidy";
     Linkchecker, "src/tools/linkchecker", "linkchecker";
diff --git a/src/doc/book b/src/doc/book
-Subproject 04d06dfe541607e6419f3d028c3f9b245f3be4d
+Subproject 5a65e2af063ff701ae858f1f7536ee347b3cfe6
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 7ef05b9777c94836bc92f50f23e6e00981521a8
+Subproject 625b200e5b33a5af35589db0bc454203a3d46d2
diff --git a/src/doc/reference b/src/doc/reference
-Subproject acd6794e712d5e2ef6f5c84fb95688d32a69b81
+Subproject 293af991003772bdccf2d6b980182d84dd05594
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 093397535b48ae13ec76bc526b7e6eb8c096a85
+Subproject 054259ed1bf01cdee4309ee764c7e103f6df3de
diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
index b416f0eb689..5061c9e8dc3 100644
--- a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
+++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
@@ -15,9 +15,9 @@ LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
    = note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
-   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#1}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
+   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#0}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
    = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC
 
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
index 48d9649c920..1ee5298f17d 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
@@ -10,7 +10,7 @@ RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
 RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
-RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#1})
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0})
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
 RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
index 667ee04e624..26cdee18e3c 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
@@ -14,7 +14,7 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
    7: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-   8: std::rt::lang_start_internal::{closure#1}
+   8: std::rt::lang_start_internal::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
    9: std::panicking::r#try::do_call
  at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
index b3a3a9d654a..d89ae3837b9 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
@@ -22,7 +22,7 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
   11: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-  12: std::rt::lang_start_internal::{closure#1}
+  12: std::rt::lang_start_internal::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
   13: std::panicking::r#try::do_call
  at RUSTLIB/std/src/panicking.rs:LL:CC
diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs
index 2cbb6cfbb50..d2b5a1507f0 100644
--- a/tests/assembly/simd-intrinsic-gather.rs
+++ b/tests/assembly/simd-intrinsic-gather.rs
@@ -38,6 +38,6 @@ pub unsafe extern "C" fn gather_f64x4(mask: m64x4, ptrs: pf64x4) -> f64x4 {
     // x86-avx512: vpsllq ymm0, ymm0, 63
     // x86-avx512-NEXT: vpmovq2m k1, ymm0
     // x86-avx512-NEXT: vpxor xmm0, xmm0, xmm0
-    // x86-avx512-NEXT: vgatherqpd ymm0 {k1}, ymmword ptr [1*ymm1]
+    // x86-avx512-NEXT: vgatherqpd ymm0 {k1}, {{(ymmword)|(qword)}} ptr [1*ymm1]
     simd_gather(f64x4([0_f64, 0_f64, 0_f64, 0_f64]), ptrs, mask)
 }
diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs
index 679972d9b86..f7e08e33faa 100644
--- a/tests/assembly/simd-intrinsic-scatter.rs
+++ b/tests/assembly/simd-intrinsic-scatter.rs
@@ -34,6 +34,6 @@ extern "rust-intrinsic" {
 pub unsafe extern "C" fn scatter_f64x4(values: f64x4, ptrs: pf64x4, mask: m64x4) {
     // x86-avx512: vpsllq ymm2, ymm2, 63
     // x86-avx512-NEXT: vpmovq2m k1, ymm2
-    // x86-avx512-NEXT: vscatterqpd ymmword ptr [1*ymm1] {k1}, ymm0
+    // x86-avx512-NEXT: vscatterqpd {{(ymmword)|(qword)}} ptr [1*ymm1] {k1}, ymm0
     simd_scatter(values, ptrs, mask)
 }
diff --git a/tests/codegen/abi-win64-zst.rs b/tests/codegen/abi-win64-zst.rs
new file mode 100644
index 00000000000..dd361898144
--- /dev/null
+++ b/tests/codegen/abi-win64-zst.rs
@@ -0,0 +1,52 @@
+//@ compile-flags: -Z merge-functions=disabled
+
+//@ revisions: windows-gnu
+//@[windows-gnu] compile-flags: --target x86_64-pc-windows-gnu
+//@[windows-gnu] needs-llvm-components: x86
+
+//@ revisions: windows-msvc
+//@[windows-msvc] compile-flags: --target x86_64-pc-windows-msvc
+//@[windows-msvc] needs-llvm-components: x86
+
+// Also test what happens when using a Windows ABI on Linux.
+//@ revisions: linux
+//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[linux] needs-llvm-components: x86
+
+#![feature(no_core, lang_items, rustc_attrs, abi_vectorcall)]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+// Make sure the argument is always passed when explicitly requesting a Windows ABI.
+// Our goal here is to match clang: <https://clang.godbolt.org/z/Wr4jMWq3P>.
+
+// CHECK: define win64cc void @pass_zst_win64(ptr {{[^,]*}})
+#[no_mangle]
+extern "win64" fn pass_zst_win64(_: ()) {}
+
+// CHECK: define x86_vectorcallcc void @pass_zst_vectorcall(ptr {{[^,]*}})
+#[no_mangle]
+extern "vectorcall" fn pass_zst_vectorcall(_: ()) {}
+
+// windows-gnu: define void @pass_zst_fastcall(ptr {{[^,]*}})
+// windows-msvc: define void @pass_zst_fastcall(ptr {{[^,]*}})
+#[no_mangle]
+#[cfg(windows)] // "fastcall" is not valid on 64bit Linux
+extern "fastcall" fn pass_zst_fastcall(_: ()) {}
+
+// The sysv64 ABI ignores ZST.
+
+// CHECK: define x86_64_sysvcc void @pass_zst_sysv64()
+#[no_mangle]
+extern "sysv64" fn pass_zst_sysv64(_: ()) {}
+
+// For `extern "C"` functions, ZST are ignored on Linux put passed on Windows.
+
+// linux: define void @pass_zst_c()
+// windows-msvc: define void @pass_zst_c(ptr {{[^,]*}})
+// windows-gnu: define void @pass_zst_c(ptr {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_zst_c(_: ()) {}
diff --git a/tests/debuginfo/closures.rs b/tests/debuginfo/closures.rs
new file mode 100644
index 00000000000..f5220a49e29
--- /dev/null
+++ b/tests/debuginfo/closures.rs
@@ -0,0 +1,155 @@
+//@ only-cdb
+//@ compile-flags:-g
+
+// === CDB TESTS ===================================================================================
+// Generic functions cause ambigious breakpoints.
+// cdb-command:dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true;
+// cdb-command:bp `closures.rs:57`
+// cdb-command:g
+// cdb-command:dx add_closure
+// cdb-check:add_closure      [Type: closures::main::closure_env$0]
+// cdb-check:     [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *]
+// cdb-command:dx increment
+// cdb-check:increment        [Type: closures::main::closure_env$1]
+// cdb-check:     [+0x[...]] _ref__count      : 0x[...] : 2 [Type: int *]
+// cdb-command:dx consume_closure
+// cdb-check:consume_closure  [Type: closures::main::closure_env$2]
+// cdb-check:     [+0x[...]] x                : [...] [Type: alloc::string::String]
+// cdb-check:     [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *]
+// cdb-command:dx simple_closure
+// cdb-checksimple_closure   [Type: closures::main::closure_env$5]
+// cdb-check:     [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *]
+// cdb-command:g
+// cdb-command:dx first_closure
+// cdb-check:first_closure    [Type: closures::main::closure_env$6]
+// cdb-check:     [+0x[...]] _ref__variable   : 0x[...] : 1 [Type: int *]
+// cdb-check:     [+0x[...]] _ref__constant   : 0x[...] : 2 [Type: int *]
+// cdb-check:     [+0x[...]] _ref__a_struct   : 0x[...] [Type: closures::Struct *]
+// cdb-check:     [+0x[...]] _ref__struct_ref : 0x[...] [Type: closures::Struct * *]
+// cdb-check:     [+0x[...]] _ref__owned_value : 0x[...] [Type: int * *]
+// cdb-command:g
+// cdb-command:dx many_param_closure
+// cdb-check:many_param_closure [Type: closures::main::closure_env$7]
+// cdb-check:     [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *]
+// cdb-command:g
+// cdb-command:dv
+// cdb-command:dx generic_closure
+// cdb-check:generic_closure  [Type: closures::generic_func::closure_env$0<i32>]
+// cdb-check:     [+0x[...]] _ref__x          : 0x[...] : 42 [Type: int *]
+// cdb-command:g
+// cdb-command:dx generic_closure
+// cdb-check:generic_closure  [Type: closures::generic_func::closure_env$0<ref$<str$> >]
+// cdb-check:     [+0x000] _ref__x          : 0x[...] : "base_value" [Type: ref$<str$> *]
+// cdb-command:g
+// cdb-command:dx second_closure
+// cdb-check:second_closure   [Type: closures::main::closure_env$8]
+// cdb-check:     [+0x[...]] _ref__variable   : 0x[...] : 2 [Type: int *]
+// cdb-check:     [+0x[...]] _ref__constant   : 0x[...] : 2 [Type: int *]
+// cdb-check:     [+0x[...]] _ref__a_struct   : 0x[...] [Type: closures::Struct *]
+// cdb-check:     [+0x[...]] _ref__struct_ref : 0x[...] [Type: closures::Struct * *]
+// cdb-check:     [+0x[...]] _ref__owned_value : 0x[...] [Type: int * *]
+
+#[inline(never)]
+fn generic_func<Tfunc: std::fmt::Debug>(x: Tfunc) {
+    let generic_closure = |a: i32| {
+        println!("{:?} {}", x, a);
+    };
+
+    _zzz(); // #break
+
+    // rustc really wants to inline this closure, so we use black_box instead of calling it
+    std::hint::black_box(generic_closure);
+}
+
+struct Struct {
+    a: isize,
+    b: f64,
+    c: usize,
+}
+
+fn main() {
+    let base_value: i32 = 42;
+    let mut count: i32 = 0;
+
+    let add_closure = |a: i32, b: i32| a + b + base_value;
+
+    add_closure(40, 2);
+
+    let mut increment = || {
+        count += 1;
+    };
+
+    increment(); // count: 1
+    increment(); // count: 2
+
+    let x = String::from("hello");
+
+    // Define a closure that consumes the captured variable `x`
+    let consume_closure = move || {
+        drop(x);
+        base_value + 1
+    };
+
+    consume_closure();
+
+    let paramless_closure = || 42_i32;
+
+    let void_closure = |a: i32| {
+        println!("Closure with arg: {:?}", a);
+    };
+
+    let simple_closure = || {
+        let incremented_value = base_value + 1;
+        incremented_value
+    };
+
+    let result = /*42; */ add_closure(40, 2);
+    println!("Result: {:?}", result);
+    void_closure(result);
+    let result = simple_closure();
+    println!("Result: {:?}", result);
+
+    let mut variable: i32 = 1;
+    let constant: i32 = 2;
+
+    let a_struct = Struct { a: -3, b: 4.5, c: 5 };
+
+    _zzz(); // #break
+
+    let struct_ref = &a_struct;
+    let owned_value: Box<i32> = Box::new(6);
+
+    {
+        let mut first_closure = || {
+            variable = constant + a_struct.a as i32 + struct_ref.a as i32 + *owned_value;
+        };
+
+        _zzz(); // #break
+
+        first_closure();
+    }
+
+    let many_param_closure =
+        |a: i32, b: f64, c: usize, d: Struct| base_value + a + b as i32 + c as i32 + d.c as i32;
+
+    _zzz(); // #break
+
+    many_param_closure(1, 2.0, 3, Struct { a: 4, b: 5.0, c: 6 });
+
+    generic_func(42);
+    generic_func("base_value");
+
+    {
+        let mut second_closure = || {
+            variable = constant + a_struct.a as i32 + struct_ref.a as i32 + *owned_value;
+        };
+
+        _zzz(); // #break
+
+        second_closure();
+    }
+}
+
+fn _zzz() {
+    ()
+}
diff --git a/tests/debuginfo/coroutine-closure.rs b/tests/debuginfo/coroutine-closure.rs
new file mode 100644
index 00000000000..ffb6ae68a2b
--- /dev/null
+++ b/tests/debuginfo/coroutine-closure.rs
@@ -0,0 +1,29 @@
+#![feature(async_closure)]
+//@ only-cdb
+//@ compile-flags:-g --edition=2021
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+// cdb-command: dx closure
+// cdb-check:closure          [Type: coroutine_closure::main::closure_env$0]
+// cdb-check:     [+0x[...]] y                : "" [Type: alloc::string::String]
+// cdb-check:     [+0x[...]] x                : "" [Type: alloc::string::String]
+#![allow(unused)]
+fn main() {
+    let x = String::new();
+    let y = String::new();
+    let closure = async move || {
+        drop(y);
+        println!("{x}");
+    };
+
+    _zzz(); // #break
+
+    std::hint::black_box(closure);
+}
+
+#[inline(never)]
+fn _zzz() {
+    ()
+}
diff --git a/tests/debuginfo/fn_ptr.rs b/tests/debuginfo/fn_ptr.rs
new file mode 100644
index 00000000000..b6eb0f11a25
--- /dev/null
+++ b/tests/debuginfo/fn_ptr.rs
@@ -0,0 +1,51 @@
+//@ only-cdb
+//@ compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+// cdb-command: dx basic
+// cdb-check: basic            : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$0,tuple$<i32,i32> >+0x0 [Type: int (__cdecl*)(int,int)]
+// cdb-check: a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$0,tuple$<i32,i32> >+0x0 [Type: int __cdecl(int,int)]
+
+// cdb-command: dx paramless
+// cdb-check: paramless        : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$1,tuple$<> >+0x0 [Type: int (__cdecl*)()]
+// cdb-check: a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$1,tuple$<> >+0x0 [Type: int __cdecl()]
+
+// cdb-command: dx my_struct
+// cdb-check: my_struct        [Type: fn_ptr::MyStruct]
+// cdb-check:   [+0x000] my_field         : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$2,tuple$<ref$<fn_ptr::MyStruct> > >+0x0 [Type: int (__cdecl*)(fn_ptr::MyStruct *)]
+
+// cdb-command: dx non_rec_struct
+// cdb-check: non_rec_struct   [Type: fn_ptr::NonRecStruct]
+// cdb-check:  [+0x000] my_field         : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$3,tuple$<i32> >+0x0 [Type: int (__cdecl*)(int)]
+
+type BasicFnPtr = fn(i32, i32) -> i32;
+
+pub type ParamlessFnPtr = fn() -> i32;
+
+type MyFnPtr = fn(b: &MyStruct) -> i32;
+
+type NonRecFnPtr = fn(i: i32) -> i32;
+
+struct MyStruct {
+    my_field: MyFnPtr,
+}
+
+struct NonRecStruct {
+    my_field: NonRecFnPtr,
+}
+
+fn main() {
+    let basic: BasicFnPtr = |a, b| a + b;
+    let paramless: ParamlessFnPtr = || 1;
+    let my_struct = MyStruct { my_field: |_| 1 };
+    let non_rec_struct = NonRecStruct { my_field: |i| i };
+
+    _zzz(); // #break
+}
+
+#[inline(never)]
+fn _zzz() {
+    ()
+}
diff --git a/tests/debuginfo/lexical-scope-in-if-let.rs b/tests/debuginfo/lexical-scope-in-if-let.rs
index 6e5e9900abe..b2c7790eab2 100644
--- a/tests/debuginfo/lexical-scope-in-if-let.rs
+++ b/tests/debuginfo/lexical-scope-in-if-let.rs
@@ -47,30 +47,33 @@
 
 // === CDB TESTS ==================================================================================
 
+// Note: `/n` causes the the output to be sorted to avoid depending on the order in PDB which may
+// be arbitrary.
+
 // cdb-command: g
-// cdb-command: dv
+// cdb-command: dv /n
 // cdb-check:[...]a = 0n123
 
 // cdb-command: g
-// cdb-command: dv
+// cdb-command: dv /n
 // cdb-check:[...]a = 0n123
 // cdb-check:[...]x = 0n42
 
 // cdb-command: g
-// cdb-command: dv
+// cdb-command: dv /n
 // cdb-check:[...]a = 0n123
-// cdb-check:[...]x = 0n42
 // cdb-check:[...]b = 0n456
+// cdb-check:[...]x = 0n42
 // cdb-check:[...]y = true
 
 // cdb-command: g
-// cdb-command: dv
-// cdb-check:[...]z = 0n10
-// cdb-check:[...]c = 0n789
+// cdb-command: dv /n
 // cdb-check:[...]a = 0n123
-// cdb-check:[...]x = 0n42
 // cdb-check:[...]b = 0n456
+// cdb-check:[...]c = 0n789
+// cdb-check:[...]x = 0n42
 // cdb-check:[...]y = true
+// cdb-check:[...]z = 0n10
 
 fn main() {
     let a = id(123);
@@ -95,6 +98,8 @@ fn main() {
 }
 
 #[inline(never)]
-fn id<T>(value: T) -> T { value }
+fn id<T>(value: T) -> T {
+    value
+}
 
-fn zzz() { }
+fn zzz() {}
diff --git a/tests/debuginfo/step-into-match.rs b/tests/debuginfo/step-into-match.rs
index f702b116b20..577e553c119 100644
--- a/tests/debuginfo/step-into-match.rs
+++ b/tests/debuginfo/step-into-match.rs
@@ -117,7 +117,7 @@
 // gdb-check:[...]match (a, b) {
 
 // gdb-command: s
-// gdb-check:[...](_, _) => 5
+// gdb-check:[...](_, _) => 5,
 
 // gdb-command: s
 // gdb-check:[...]}
@@ -300,7 +300,7 @@
 // cdb-check:   [...]:     match (a, b) {
 
 // cdb-command: t
-// cdb-check:   [...]:         (_, _) => 5
+// cdb-check:   [...]:         (_, _) => 5,
 
 // cdb-command: t
 // cdb-check:   [...]: }
@@ -378,6 +378,6 @@ fn match_tuple(a: u8, b: i8) -> u32 {
         (29, _) => 2,
         (5, 12) => 3,
         (_, 9) => 4,
-        (_, _) => 5
+        (_, _) => 5,
     }
 }
diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs
index 4caaf3fc97f..4df6daf7b6e 100644
--- a/tests/debuginfo/type-names.rs
+++ b/tests/debuginfo/type-names.rs
@@ -5,7 +5,7 @@
 
 //@ compile-flags:-g
 
-// === GDB TESTS ===================================================================================
+// === GDB TESTS ==================================================================================
 
 // gdb-command:run
 
@@ -17,7 +17,7 @@
 // gdb-check:type = type_names::GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
 
 // gdb-command:whatis generic_struct2
-// gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "system" fn(isize) -> usize>
+// gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
 
 // gdb-command:whatis mod_struct
 // gdb-check:type = type_names::mod1::Struct2
@@ -169,81 +169,85 @@
 
 // === CDB TESTS ==================================================================================
 
+// Note: `/n` causes the wildcard matches to be sorted to avoid depending on order in PDB which
+// can be arbitrary.
+
 // cdb-command: g
 
 // STRUCTS
 // 0-sized structs appear to be optimized away in some cases, so only check the structs that do
 // actually appear.
-// cdb-command:dv /t *_struct
+// cdb-command:dv /t /n *_struct
 
 // ENUMS
-// cdb-command:dv /t *_enum_*
+// cdb-command:dv /t /n *_enum_*
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
+// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
 // cdb-check:union enum2$<type_names::Enum1> simple_enum_1 = [...]
 // cdb-check:union enum2$<type_names::Enum1> simple_enum_2 = [...]
 // cdb-check:union enum2$<type_names::mod1::Enum2> simple_enum_3 = [...]
-// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...]
-// cdb-check:union enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...]
 
 // TUPLES
-// cdb-command:dv /t tuple*
+// cdb-command:dv /t /n tuple*
 // cdb-check:struct tuple$<u32,type_names::Struct1,enum2$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
 // cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum2$<type_names::mod1::Enum2>,char> tuple2 = [...]
 
 // BOX
-// cdb-command:dv /t box*
+// cdb-command:dv /t /n box*
 // cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
 // cdb-check:struct tuple$<alloc::boxed::Box<enum2$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
 
 // REFERENCES
-// cdb-command:dv /t *ref*
-// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
-// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
+// cdb-command:dv /t /n *ref*
 // cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
 // cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum2$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
+// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
 
 // RAW POINTERS
-// cdb-command:dv /t *_ptr*
-// cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
-// cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
-// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-command:dv /t /n *_ptr*
 // cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
 // cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
 // cdb-check:struct tuple$<ptr_const$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
+// cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum2$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
 
 // VECTORS
-// cdb-command:dv /t *vec*
+// cdb-command:dv /t /n *vec*
 // cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
 // cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
 // cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
 // cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
-// cdb-command:dv /t slice*
+// cdb-command:dv /t /n slice*
 // cdb-check:struct ref$<slice2$<usize> > slice1 = [...]
 // cdb-check:struct ref_mut$<slice2$<enum2$<type_names::mod1::Enum2> > > slice2 = [...]
 
 // TRAITS
-// cdb-command:dv /t *_trait
+// cdb-command:dv /t /n *_trait
+
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
 // cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3,type_names::GenericStruct<usize,isize> > > > generic_mut_ref_trait = [...]
 // cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1,type_names::Struct1> > > generic_ref_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > > has_associated_type_but_no_generics_trait = struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > >
+// cdb-check:struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> >
 // cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
 // cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send,core::marker::Sync>,alloc::alloc::Global> no_principal_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> >
-// cdb-check:struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > > has_associated_type_but_no_generics_trait = struct ref$<dyn$<type_names::TraitNoGenericsButWithAssocType<assoc$<Output,isize> > > >
+// cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
 
 // BARE FUNCTIONS
-// cdb-command:dv /t *_fn*
-// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
+// cdb-command:dv /t /n *_fn*
+// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
 // cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
+// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
 // cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
 // cdb-check:struct tuple$<void (*)(enum2$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
-// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >),usize> rust_fn = [...]
-// cdb-command:dv /t *_function*
-// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
-// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
+// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
+// cdb-command:dv /t /n *_function*
 // cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
+// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
+// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
 // cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
 // cdb-check:Return Type: void
 // cdb-check:Parameter Types: enum2$<core::option::Option<isize> >,enum2$<core::option::Option<ref$<type_names::mod1::Struct2> > >
@@ -255,24 +259,25 @@
 // cdb-check:Parameter Types:
 
 // CLOSURES
-// cdb-command:dv /t closure*
-// cdb-check:struct tuple$<type_names::main::closure_env$1,usize> closure2 = [...]
+// cdb-command:dv /t /n closure*
 // cdb-check:struct tuple$<type_names::main::closure_env$0,usize> closure1 = [...]
+// cdb-check:struct tuple$<type_names::main::closure_env$1,usize> closure2 = [...]
 
 // FOREIGN TYPES
-// cdb-command:dv /t foreign*
-// cdb-check:struct type_names::mod1::extern$0::ForeignType2 * foreign2 = [...]
+// cdb-command:dv /t /n foreign*
 // cdb-check:struct type_names::extern$0::ForeignType1 * foreign1 = [...]
+// cdb-check:struct type_names::mod1::extern$0::ForeignType2 * foreign2 = [...]
 
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 #![feature(extern_types)]
 
-use self::Enum1::{Variant1, Variant2};
 use std::marker::PhantomData;
 use std::ptr;
 
+use self::Enum1::{Variant1, Variant2};
+
 pub struct Struct1;
 struct GenericStruct<T1, T2>(PhantomData<(T1, T2)>);
 
@@ -372,7 +377,7 @@ fn main() {
     let simple_struct = Struct1;
     let generic_struct1: GenericStruct<mod1::Struct2, mod1::mod2::Struct3> =
         GenericStruct(PhantomData);
-    let generic_struct2: GenericStruct<Struct1, extern "system" fn(isize) -> usize> =
+    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
         GenericStruct(PhantomData);
     let mod_struct = mod1::Struct2;
 
diff --git a/tests/mir-opt/building/dump_mir_cycle.rs b/tests/mir-opt/building/dump_mir_cycle.rs
new file mode 100644
index 00000000000..8e13420aed7
--- /dev/null
+++ b/tests/mir-opt/building/dump_mir_cycle.rs
@@ -0,0 +1,19 @@
+#[derive(Debug)]
+pub struct Thing {
+    pub next: &'static Thing,
+}
+
+pub static THING: Thing = Thing { next: &THING };
+// CHECK: alloc{{.+}} (static: THING)
+
+const fn thing() -> &'static Thing {
+    &MUTUALLY_RECURSIVE
+}
+
+pub static MUTUALLY_RECURSIVE: Thing = Thing { next: thing() };
+// CHECK: alloc{{.+}} (static: MUTUALLY_RECURSIVE)
+
+fn main() {
+    // Generate optimized MIR for the const fn, too.
+    thing();
+}
diff --git a/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-pre-optimizations.after.mir b/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-pre-optimizations.after.mir
index 7affbf6dd40..344851bb088 100644
--- a/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-pre-optimizations.after.mir
+++ b/tests/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-pre-optimizations.after.mir
@@ -15,6 +15,4 @@ const BAR::promoted[0]: &[&i32; 1] = {
     }
 }
 
-ALLOC0 (static: Y, size: 4, align: 4) {
-    2a 00 00 00                                     │ *...
-}
+ALLOC0 (static: Y)
diff --git a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index 487f68a8d4d..5f8f84244af 100644
--- a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -38,9 +38,7 @@
       bb2 (cleanup): {
           resume;
       }
-- }
-- 
-- ALLOC0 (static: Y, size: 4, align: 4) {
--     2a 00 00 00                                     │ *...
   }
+- 
+- ALLOC0 (static: Y)
   
diff --git a/tests/ui/abi/win64-zst.rs b/tests/ui/abi/win64-zst.rs
deleted file mode 100644
index bc4e0e629eb..00000000000
--- a/tests/ui/abi/win64-zst.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN"
-//@ only-x86_64
-
-//@ revisions: x86_64-linux
-//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu
-//@[x86_64-linux] needs-llvm-components: x86
-
-//@ revisions: x86_64-windows-gnu
-//@[x86_64-windows-gnu] compile-flags: --target x86_64-pc-windows-gnu
-//@[x86_64-windows-gnu] needs-llvm-components: x86
-
-//@ revisions: x86_64-windows-msvc
-//@[x86_64-windows-msvc] compile-flags: --target x86_64-pc-windows-msvc
-//@[x86_64-windows-msvc] needs-llvm-components: x86
-
-#![feature(no_core, lang_items, rustc_attrs)]
-#![no_core]
-#![crate_type = "lib"]
-
-#[lang = "sized"]
-trait Sized {}
-
-#[rustc_abi(debug)]
-extern "win64" fn pass_zst(_: ()) {} //~ ERROR: fn_abi
diff --git a/tests/ui/abi/win64-zst.x86_64-linux.stderr b/tests/ui/abi/win64-zst.x86_64-linux.stderr
deleted file mode 100644
index a28a59fdd8d..00000000000
--- a/tests/ui/abi/win64-zst.x86_64-linux.stderr
+++ /dev/null
@@ -1,69 +0,0 @@
-error: fn_abi_of(pass_zst) = FnAbi {
-           args: [
-               ArgAbi {
-                   layout: TyAndLayout {
-                       ty: (),
-                       layout: Layout {
-                           size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
-                               abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
-                           },
-                           abi: Memory {
-                               sized: true,
-                           },
-                           fields: Arbitrary {
-                               offsets: [],
-                               memory_index: [],
-                           },
-                           largest_niche: None,
-                           variants: Single {
-                               index: 0,
-                           },
-                           max_repr_align: None,
-                           unadjusted_abi_align: $SOME_ALIGN,
-                           randomization_seed: 0,
-                       },
-                   },
-                   mode: Ignore,
-               },
-           ],
-           ret: ArgAbi {
-               layout: TyAndLayout {
-                   ty: (),
-                   layout: Layout {
-                       size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
-                           abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
-                       },
-                       abi: Memory {
-                           sized: true,
-                       },
-                       fields: Arbitrary {
-                           offsets: [],
-                           memory_index: [],
-                       },
-                       largest_niche: None,
-                       variants: Single {
-                           index: 0,
-                       },
-                       max_repr_align: None,
-                       unadjusted_abi_align: $SOME_ALIGN,
-                       randomization_seed: 0,
-                   },
-               },
-               mode: Ignore,
-           },
-           c_variadic: false,
-           fixed_count: 1,
-           conv: X86_64Win64,
-           can_unwind: false,
-       }
-  --> $DIR/win64-zst.rs:24:1
-   |
-LL | extern "win64" fn pass_zst(_: ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr b/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr
deleted file mode 100644
index cf0cc00c5ed..00000000000
--- a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr
+++ /dev/null
@@ -1,80 +0,0 @@
-error: fn_abi_of(pass_zst) = FnAbi {
-           args: [
-               ArgAbi {
-                   layout: TyAndLayout {
-                       ty: (),
-                       layout: Layout {
-                           size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
-                               abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
-                           },
-                           abi: Memory {
-                               sized: true,
-                           },
-                           fields: Arbitrary {
-                               offsets: [],
-                               memory_index: [],
-                           },
-                           largest_niche: None,
-                           variants: Single {
-                               index: 0,
-                           },
-                           max_repr_align: None,
-                           unadjusted_abi_align: $SOME_ALIGN,
-                           randomization_seed: 0,
-                       },
-                   },
-                   mode: Indirect {
-                       attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
-                           arg_ext: None,
-                           pointee_size: Size(0 bytes),
-                           pointee_align: Some(
-                               Align(1 bytes),
-                           ),
-                       },
-                       meta_attrs: None,
-                       on_stack: false,
-                   },
-               },
-           ],
-           ret: ArgAbi {
-               layout: TyAndLayout {
-                   ty: (),
-                   layout: Layout {
-                       size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
-                           abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
-                       },
-                       abi: Memory {
-                           sized: true,
-                       },
-                       fields: Arbitrary {
-                           offsets: [],
-                           memory_index: [],
-                       },
-                       largest_niche: None,
-                       variants: Single {
-                           index: 0,
-                       },
-                       max_repr_align: None,
-                       unadjusted_abi_align: $SOME_ALIGN,
-                       randomization_seed: 0,
-                   },
-               },
-               mode: Ignore,
-           },
-           c_variadic: false,
-           fixed_count: 1,
-           conv: X86_64Win64,
-           can_unwind: false,
-       }
-  --> $DIR/win64-zst.rs:24:1
-   |
-LL | extern "win64" fn pass_zst(_: ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr b/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr
deleted file mode 100644
index a28a59fdd8d..00000000000
--- a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr
+++ /dev/null
@@ -1,69 +0,0 @@
-error: fn_abi_of(pass_zst) = FnAbi {
-           args: [
-               ArgAbi {
-                   layout: TyAndLayout {
-                       ty: (),
-                       layout: Layout {
-                           size: Size(0 bytes),
-                           align: AbiAndPrefAlign {
-                               abi: $SOME_ALIGN,
-                               pref: $SOME_ALIGN,
-                           },
-                           abi: Memory {
-                               sized: true,
-                           },
-                           fields: Arbitrary {
-                               offsets: [],
-                               memory_index: [],
-                           },
-                           largest_niche: None,
-                           variants: Single {
-                               index: 0,
-                           },
-                           max_repr_align: None,
-                           unadjusted_abi_align: $SOME_ALIGN,
-                           randomization_seed: 0,
-                       },
-                   },
-                   mode: Ignore,
-               },
-           ],
-           ret: ArgAbi {
-               layout: TyAndLayout {
-                   ty: (),
-                   layout: Layout {
-                       size: Size(0 bytes),
-                       align: AbiAndPrefAlign {
-                           abi: $SOME_ALIGN,
-                           pref: $SOME_ALIGN,
-                       },
-                       abi: Memory {
-                           sized: true,
-                       },
-                       fields: Arbitrary {
-                           offsets: [],
-                           memory_index: [],
-                       },
-                       largest_niche: None,
-                       variants: Single {
-                           index: 0,
-                       },
-                       max_repr_align: None,
-                       unadjusted_abi_align: $SOME_ALIGN,
-                       randomization_seed: 0,
-                   },
-               },
-               mode: Ignore,
-           },
-           c_variadic: false,
-           fixed_count: 1,
-           conv: X86_64Win64,
-           can_unwind: false,
-       }
-  --> $DIR/win64-zst.rs:24:1
-   |
-LL | extern "win64" fn pass_zst(_: ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.rs b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.rs
new file mode 100644
index 00000000000..ba37087135f
--- /dev/null
+++ b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.rs
@@ -0,0 +1,18 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/122638>.
+//@ check-fail
+#![feature(min_specialization)]
+impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
+    //~^ ERROR not all trait items implemented, missing: `Item` [E0046]
+    fn next(&mut self) -> Option<Self::Item> {}
+    //~^ ERROR mismatched types [E0308]
+}
+struct ConstChunksExact<'a, T: '_, const assert: usize> {}
+//~^ ERROR `'_` cannot be used here [E0637]
+//~| ERROR lifetime parameter `'a` is never used [E0392]
+//~| ERROR type parameter `T` is never used [E0392]
+impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
+    //~^ ERROR mismatched types [E0308]
+    //~| ERROR the const parameter `N` is not constrained by the impl trait, self type, or predicates [E0207]
+    type Item = &'a [T; N]; }
+
+fn main() {}
diff --git a/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr
new file mode 100644
index 00000000000..1ee68647594
--- /dev/null
+++ b/tests/ui/const-generics/normalizing_with_unconstrained_impl_params.stderr
@@ -0,0 +1,60 @@
+error[E0637]: `'_` cannot be used here
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:9:32
+   |
+LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
+   |                                ^^ `'_` is a reserved lifetime name
+
+error[E0308]: mismatched types
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:13:83
+   |
+LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
+   |                                                                                   ^^ expected `usize`, found `()`
+
+error[E0046]: not all trait items implemented, missing: `Item`
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:4:1
+   |
+LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
+   |
+   = help: implement the missing item: `type Item = /* Type */;`
+
+error[E0392]: lifetime parameter `'a` is never used
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:9:25
+   |
+LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
+   |                         ^^ unused lifetime parameter
+   |
+   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:9:29
+   |
+LL | struct ConstChunksExact<'a, T: '_, const assert: usize> {}
+   |                             ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:13:30
+   |
+LL | impl<'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {}> {
+   |                              ^^^^^^^^^^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0308]: mismatched types
+  --> $DIR/normalizing_with_unconstrained_impl_params.rs:6:27
+   |
+LL |     fn next(&mut self) -> Option<Self::Item> {}
+   |        ----               ^^^^^^^^^^^^^^^^^^ expected `Option<_>`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note:   expected enum `Option<_>`
+           found unit type `()`
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0046, E0207, E0308, E0392, E0637.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
new file mode 100644
index 00000000000..914ca1f3a06
--- /dev/null
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
@@ -0,0 +1,22 @@
+//@ run-rustfix
+#![deny(unused_assignments, unused_variables)]
+struct Object;
+
+fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate
+    let object2 = Object;
+    *object = object2; //~ ERROR mismatched types
+}
+
+fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
+    //~^ HELP you might have meant to mutate
+    let object2 = Object;
+    *object = object2;
+    //~^ ERROR `object2` does not live long enough
+    //~| ERROR value assigned to `object` is never read
+}
+
+fn main() {
+    let mut object = Object;
+    change_object(&mut object);
+    change_object2(&mut object);
+}
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
new file mode 100644
index 00000000000..331359a98d1
--- /dev/null
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
@@ -0,0 +1,22 @@
+//@ run-rustfix
+#![deny(unused_assignments, unused_variables)]
+struct Object;
+
+fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate
+    let object2 = Object;
+    object = object2; //~ ERROR mismatched types
+}
+
+fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used
+    //~^ HELP you might have meant to mutate
+    let object2 = Object;
+    object = &object2;
+    //~^ ERROR `object2` does not live long enough
+    //~| ERROR value assigned to `object` is never read
+}
+
+fn main() {
+    let mut object = Object;
+    change_object(&mut object);
+    change_object2(&mut object);
+}
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
new file mode 100644
index 00000000000..e7e4003936a
--- /dev/null
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
@@ -0,0 +1,69 @@
+error[E0308]: mismatched types
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:7:14
+   |
+LL | fn change_object(mut object: &Object) {
+   |                              ------- expected due to this parameter type
+LL |     let object2 = Object;
+LL |     object = object2;
+   |              ^^^^^^^ expected `&Object`, found `Object`
+   |
+help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
+   |
+LL ~ fn change_object(object: &mut Object) {
+LL |     let object2 = Object;
+LL ~     *object = object2;
+   |
+
+error: value assigned to `object` is never read
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:5
+   |
+LL |     object = &object2;
+   |     ^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9
+   |
+LL | #![deny(unused_assignments, unused_variables)]
+   |         ^^^^^^^^^^^^^^^^^^
+help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
+   |
+LL ~ fn change_object2(object: &mut Object) {
+LL |
+LL |     let object2 = Object;
+LL ~     *object = object2;
+   |
+
+error: variable `object` is assigned to, but never used
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:10:23
+   |
+LL | fn change_object2(mut object: &Object) {
+   |                       ^^^^^^
+   |
+   = note: consider using `_object` instead
+note: the lint level is defined here
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:29
+   |
+LL | #![deny(unused_assignments, unused_variables)]
+   |                             ^^^^^^^^^^^^^^^^
+
+error[E0597]: `object2` does not live long enough
+  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:14
+   |
+LL | fn change_object2(mut object: &Object) {
+   |                               - let's call the lifetime of this reference `'1`
+LL |
+LL |     let object2 = Object;
+   |         ------- binding `object2` declared here
+LL |     object = &object2;
+   |     ---------^^^^^^^^
+   |     |        |
+   |     |        borrowed value does not live long enough
+   |     assignment requires that `object2` is borrowed for `'1`
+...
+LL | }
+   | - `object2` dropped here while still borrowed
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0597.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs
index 075d7c70ac6..32dc0927317 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.rs
+++ b/tests/ui/impl-trait/precise-capturing/redundant.rs
@@ -1,24 +1,24 @@
 //@ edition: 2024
-//@ check-pass
 
 #![feature(precise_capturing_in_traits)]
+#![deny(impl_trait_redundant_captures)]
 
 fn hello<'a>() -> impl Sized + use<'a> {}
-//~^ WARN all possible in-scope parameters are already captured
+//~^ ERROR all possible in-scope parameters are already captured
 
 struct Inherent;
 impl Inherent {
     fn inherent(&self) -> impl Sized + use<'_> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 
 trait Test<'a> {
     fn in_trait() -> impl Sized + use<'a, Self>;
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 impl<'a> Test<'a> for () {
     fn in_trait() -> impl Sized + use<'a> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr
index 274d9d2375f..5c8b35c2285 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.stderr
+++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr
@@ -1,4 +1,4 @@
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:6:19
    |
 LL | fn hello<'a>() -> impl Sized + use<'a> {}
@@ -6,9 +6,13 @@ LL | fn hello<'a>() -> impl Sized + use<'a> {}
    |                                |
    |                                help: remove the `use<...>` syntax
    |
-   = note: `#[warn(impl_trait_redundant_captures)]` on by default
+note: the lint level is defined here
+  --> $DIR/redundant.rs:4:9
+   |
+LL | #![deny(impl_trait_redundant_captures)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:11:27
    |
 LL |     fn inherent(&self) -> impl Sized + use<'_> {}
@@ -16,7 +20,7 @@ LL |     fn inherent(&self) -> impl Sized + use<'_> {}
    |                                        |
    |                                        help: remove the `use<...>` syntax
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:16:22
    |
 LL |     fn in_trait() -> impl Sized + use<'a, Self>;
@@ -24,7 +28,7 @@ LL |     fn in_trait() -> impl Sized + use<'a, Self>;
    |                                   |
    |                                   help: remove the `use<...>` syntax
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:20:22
    |
 LL |     fn in_trait() -> impl Sized + use<'a> {}
@@ -32,5 +36,5 @@ LL |     fn in_trait() -> impl Sized + use<'a> {}
    |                                   |
    |                                   help: remove the `use<...>` syntax
 
-warning: 4 warnings emitted
+error: aborting due to 4 previous errors
 
diff --git a/tests/crashes/114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
index 9d90c153624..410862c5326 100644
--- a/tests/crashes/114484.rs
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
@@ -1,4 +1,12 @@
-//@ known-bug: #114484
+//@ build-fail
+
+//@ error-pattern: reached the recursion limit while instantiating
+//@ error-pattern: reached the recursion limit finding the struct tail
+
+// Regression test for #114484: This used to ICE during monomorphization, because we treated
+// `<VirtualWrapper<...> as Pointee>::Metadata` as a rigid projection after reaching the recursion
+// limit when finding the struct tail.
+
 use std::marker::PhantomData;
 
 trait MyTrait {
diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
new file mode 100644
index 00000000000..7c961b79c0c
--- /dev/null
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
@@ -0,0 +1,86 @@
+error: reached the recursion limit finding the struct tail for `[u8; 256]`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+
+error: reached the recursion limit finding the struct tail for `[u8; 256]`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `[u8; 256]`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `[u8; 256]`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+   |
+LL |         unsafe { virtualize_my_trait(L, self) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: reached the recursion limit finding the struct tail for `SomeData<256>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+
+error: reached the recursion limit finding the struct tail for `SomeData<256>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `SomeData<256>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `SomeData<256>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+   |
+LL |         unsafe { virtualize_my_trait(L, self) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+
+error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
+   |
+LL |         unsafe { virtualize_my_trait(L, self) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<..., 1>, 1>, 1>, 1>, 1> as MyTrait>::virtualize`
+   |
+note: `<VirtualWrapper<T, L> as MyTrait>::virtualize` defined here
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5
+   |
+LL |     fn virtualize(&self) -> &dyn MyTrait {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation-struct-tail-ice-114484/infinite-instantiation-struct-tail-ice-114484.long-type.txt'
+
+error: aborting due to 13 previous errors
+
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
index 2c0f25fc6ff..2d6df816bb1 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
@@ -11,7 +11,7 @@ impl Foo {
         //~^ ERROR invalid generic `self` parameter type
         //~| ERROR destructor of `R` cannot be evaluated at compile-time
         self.0
-        //~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
+        //~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions
     }
 }
 
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
index 90b63249eca..e6319d5a2c9 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
@@ -1,9 +1,10 @@
-error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in constant functions
+error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions
   --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
    |
 LL |         self.0
    |         ^^^^^^
    |
+   = note: attempting to deref into `Foo`
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
    = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
    = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.rs b/tests/ui/structs/ice-struct-tail-normalization-113272.rs
index 85d3d1b4886..0ae24a7b71b 100644
--- a/tests/ui/structs/ice-struct-tail-normalization-113272.rs
+++ b/tests/ui/structs/ice-struct-tail-normalization-113272.rs
@@ -13,5 +13,6 @@ struct Other {
 fn main() {
     unsafe {
         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+        //~^ ERROR cannot transmute
     }
 }
diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr
index a205eb80f5c..8c55dbca187 100644
--- a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr
+++ b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr
@@ -13,7 +13,16 @@ LL |     type RefTarget;
 LL | impl Trait for () where Missing: Trait {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation
 
-error: aborting due to 2 previous errors
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/ice-struct-tail-normalization-113272.rs:15:9
+   |
+LL |         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<()>` (8 bits)
+   = note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized)
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0046, E0412.
+Some errors have detailed explanations: E0046, E0412, E0512.
 For more information about an error, try `rustc --explain E0046`.