about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs8
-rw-r--r--compiler/rustc_borrowck/messages.ftl3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs11
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs27
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs24
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/lib.rs14
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs7
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs4
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs4
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs7
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs46
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs9
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs5
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs7
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs4
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs31
-rw-r--r--compiler/rustc_errors/src/lib.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs150
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs46
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs39
-rw-r--r--compiler/rustc_interface/src/passes.rs47
-rw-r--r--compiler/rustc_lint/src/late.rs2
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs17
-rw-r--r--compiler/rustc_macros/src/query.rs26
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs4
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs12
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs7
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs6
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs13
-rw-r--r--compiler/rustc_middle/src/query/mod.rs22
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs81
-rw-r--r--compiler/rustc_middle/src/thir.rs13
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs16
-rw-r--r--compiler/rustc_middle/src/ty/error.rs37
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs93
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_mir_build/messages.ftl14
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs23
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs17
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/category.rs7
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/into.rs7
-rw-r--r--compiler/rustc_mir_build/src/builder/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs31
-rw-r--r--compiler/rustc_mir_build/src/errors.rs42
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs15
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs18
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs8
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs6
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs7
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs12
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs7
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs37
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs24
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs47
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note.rs422
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs10
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs28
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs82
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs11
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs54
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs21
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs8
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--library/core/src/cmp.rs170
-rw-r--r--library/core/src/ptr/const_ptr.rs6
-rw-r--r--library/core/src/ptr/mut_ptr.rs5
-rw-r--r--library/std/src/process.rs12
-rw-r--r--library/std/src/sync/once_lock.rs4
-rw-r--r--library/std/src/sync/poison/mutex.rs32
-rw-r--r--library/std/src/sync/poison/once.rs6
-rw-r--r--src/ci/github-actions/jobs.yml15
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh94
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ctfe.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs4
-rw-r--r--tests/codegen/issues/issue-136329-optnone-noinline.rs21
-rw-r--r--tests/ui/coercion/coerce-expect-unsized-ascribed.stderr6
-rw-r--r--tests/ui/diagnostic-width/E0271.ascii.stderr8
-rw-r--r--tests/ui/diagnostic-width/E0271.rs4
-rw-r--r--tests/ui/diagnostic-width/E0271.unicode.stderr8
-rw-r--r--tests/ui/diagnostic-width/long-E0308.ascii.stderr28
-rw-r--r--tests/ui/diagnostic-width/long-E0308.unicode.stderr28
-rw-r--r--tests/ui/diagnostic-width/long-e0277.rs15
-rw-r--r--tests/ui/diagnostic-width/long-e0277.stderr23
-rw-r--r--tests/ui/diagnostic-width/non-copy-type-moved.stderr4
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.rs2
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.stderr2
-rw-r--r--tests/ui/fn/fn-pointer-mismatch.stderr2
-rw-r--r--tests/ui/force-inlining/cast.stderr4
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr2
-rw-r--r--tests/ui/suggestions/box-future-wrong-output.stderr2
-rw-r--r--tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr2
-rw-r--r--tests/ui/suggestions/issue-107860.stderr2
-rw-r--r--tests/ui/traits/ice-with-dyn-pointee-errors.stderr2
-rw-r--r--tests/ui/traits/object/pretty.stderr4
-rw-r--r--tests/ui/traits/on_unimplemented_long_types.stderr2
-rw-r--r--tests/ui/typeck/issue-107775.stderr2
-rw-r--r--tests/ui/typeck/return_type_containing_closure.rs2
-rw-r--r--tests/ui/typeck/return_type_containing_closure.stderr2
-rw-r--r--tests/ui/unsafe-binders/expr.rs4
-rw-r--r--tests/ui/unsafe-binders/expr.stderr16
-rw-r--r--tests/ui/unsafe-binders/mismatch.rs17
-rw-r--r--tests/ui/unsafe-binders/mismatch.stderr47
-rw-r--r--tests/ui/unsafe-binders/moves.rs41
-rw-r--r--tests/ui/unsafe-binders/moves.stderr85
152 files changed, 1563 insertions, 1310 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index ad942e9b494..b6f331d316c 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1657,7 +1657,7 @@ impl GenBlockKind {
 }
 
 /// Whether we're unwrapping or wrapping an unsafe binder
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum UnsafeBinderCastKind {
     // e.g. `&i32` -> `unsafe<'a> &'a i32`
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b9f1a4220b8..893da930855 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -418,10 +418,10 @@ fn compute_hir_hash(
 pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
     let sess = tcx.sess;
     // Queries that borrow `resolver_for_lowering`.
-    tcx.ensure_with_value().output_filenames(());
-    tcx.ensure_with_value().early_lint_checks(());
-    tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
-    tcx.ensure_with_value().get_lang_items(());
+    tcx.ensure_done().output_filenames(());
+    tcx.ensure_done().early_lint_checks(());
+    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
+    tcx.ensure_done().get_lang_items(());
     let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
 
     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index c00e6dde919..ada20e5c614 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -92,9 +92,6 @@ borrowck_lifetime_constraints_error =
 borrowck_limitations_implies_static =
     due to current limitations in the borrow checker, this implies a `'static` lifetime
 
-borrowck_long_type_consider_verbose = consider using `--verbose` to print the full type name to the console
-borrowck_long_type_full_path = the full type name has been written to '{$path}'
-
 borrowck_move_closure_suggestion =
     consider adding 'move' keyword before the nested closure
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 0118b72962d..dc4e49972ca 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -289,8 +289,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 None => "value".to_owned(),
             };
             if needs_note {
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(ty, &mut path);
+                let ty = self.infcx.tcx.short_string(ty, err.long_ty_path());
                 if let Some(local) = place.as_local() {
                     let span = self.body.local_decls[local].source_info.span;
                     err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
@@ -306,11 +305,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         place: &note_msg,
                     });
                 };
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
             }
 
             if let UseSpans::FnSelfUse {
@@ -3915,7 +3909,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::Subslice { .. }
                         | ProjectionElem::Subtype(_)
-                        | ProjectionElem::Index(_) => kind,
+                        | ProjectionElem::Index(_)
+                        | ProjectionElem::UnwrapUnsafeBinder(_) => kind,
                     },
                     place_ty.projection_ty(tcx, elem),
                 )
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 5fe8eef3460..01ed0464c8a 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -4,7 +4,7 @@ use std::collections::BTreeMap;
 
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan};
+use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify};
 use rustc_hir::def::{CtorKind, Namespace};
 use rustc_hir::{self as hir, CoroutineKind, LangItem};
 use rustc_index::IndexSlice;
@@ -29,7 +29,7 @@ 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,
+    FulfillmentError, FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
 };
 use tracing::debug;
 
@@ -370,6 +370,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 ProjectionElem::Downcast(..) => (),
                 ProjectionElem::OpaqueCast(..) => (),
                 ProjectionElem::Subtype(..) => (),
+                ProjectionElem::UnwrapUnsafeBinder(_) => (),
                 ProjectionElem::Field(field, _ty) => {
                     // FIXME(project-rfc_2229#36): print capture precisely here.
                     if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -450,9 +451,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
                 }
                 ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
-                ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => {
-                    PlaceTy::from_ty(*ty)
-                }
+                ProjectionElem::Subtype(ty)
+                | ProjectionElem::OpaqueCast(ty)
+                | ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty),
                 ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
             },
         };
@@ -1433,17 +1434,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                                             error.obligation.predicate,
                                         )
                                     }
-                                    [errors @ .., last] => {
+                                    _ => {
                                         format!(
                                             "you could `clone` the value and consume it, if the \
-                                             following trait bounds could be satisfied: \
-                                             {} and `{}`",
-                                            errors
-                                                .iter()
-                                                .map(|e| format!("`{}`", e.obligation.predicate))
-                                                .collect::<Vec<_>>()
-                                                .join(", "),
-                                            last.obligation.predicate,
+                                             following trait bounds could be satisfied: {}",
+                                            listify(&errors, |e: &FulfillmentError<'tcx>| format!(
+                                                "`{}`",
+                                                e.obligation.predicate
+                                            ))
+                                            .unwrap(),
                                         )
                                     }
                                 };
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 14a900f38e9..58c5c2fd774 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -596,19 +596,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         self.suggest_cloning(err, place_ty, expr, None);
                     }
 
-                    let mut path = None;
-                    let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
+                    let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path());
                     err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                         is_partial_move: false,
                         ty,
                         place: &place_desc,
                         span,
                     });
-                    if let Some(path) = path {
-                        err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                            path: path.display().to_string(),
-                        });
-                    }
                 } else {
                     binds_to.sort();
                     binds_to.dedup();
@@ -635,19 +629,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     self.suggest_cloning(err, place_ty, expr, Some(use_spans));
                 }
 
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
+                let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path());
                 err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                     is_partial_move: false,
                     ty,
                     place: &place_desc,
                     span: use_span,
                 });
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
 
                 use_spans.args_subdiag(err, |args_span| {
                     crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
@@ -845,19 +833,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                     self.suggest_cloning(err, bind_to.ty, expr, None);
                 }
 
-                let mut path = None;
-                let ty = self.infcx.tcx.short_ty_string(bind_to.ty, &mut path);
+                let ty = self.infcx.tcx.short_string(bind_to.ty, err.long_ty_path());
                 err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
                     is_partial_move: false,
                     ty,
                     place: place_desc,
                     span: binding_span,
                 });
-                if let Some(path) = path {
-                    err.subdiagnostic(crate::session_diagnostics::LongTypePath {
-                        path: path.display().to_string(),
-                    });
-                }
             }
         }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index e841a5e4c94..706dd7135f7 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -167,7 +167,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         | ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::OpaqueCast { .. }
                         | ProjectionElem::Subslice { .. }
-                        | ProjectionElem::Downcast(..),
+                        | ProjectionElem::Downcast(..)
+                        | ProjectionElem::UnwrapUnsafeBinder(_),
                     ],
             } => bug!("Unexpected immutable place."),
         }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index decfab502bb..077d8f49df8 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1398,6 +1398,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     self.consume_operand(location, (operand, span), state);
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(op, _) => {
+                self.consume_operand(location, (op, span), state);
+            }
         }
     }
 
@@ -1770,7 +1774,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 // So it's safe to skip these.
                 ProjectionElem::OpaqueCast(_)
                 | ProjectionElem::Subtype(_)
-                | ProjectionElem::Downcast(_, _) => (),
+                | ProjectionElem::Downcast(_, _)
+                | ProjectionElem::UnwrapUnsafeBinder(_) => (),
             }
 
             place_ty = place_ty.projection_ty(tcx, elem);
@@ -2004,6 +2009,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 // FIXME: is this true even if P is an adt with a dtor?
                 { }
 
+                ProjectionElem::UnwrapUnsafeBinder(_) => {
+                    check_parent_of_field(self, location, place_base, span, state);
+                }
+
                 // assigning to (*P) requires P to be initialized
                 ProjectionElem::Deref => {
                     self.check_if_full_path_is_moved(
@@ -2384,7 +2393,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     | ProjectionElem::Subslice { .. }
                     | ProjectionElem::Subtype(..)
                     | ProjectionElem::OpaqueCast { .. }
-                    | ProjectionElem::Downcast(..) => {
+                    | ProjectionElem::Downcast(..)
+                    | ProjectionElem::UnwrapUnsafeBinder(_) => {
                         let upvar_field_projection = self.is_upvar_field_projection(place);
                         if let Some(field) = upvar_field_projection {
                             let upvar = &self.upvars[field.index()];
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 679e111caa9..cf3e82426e8 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -250,7 +250,8 @@ fn place_components_conflict<'tcx>(
                 | (ProjectionElem::Subslice { .. }, _, _)
                 | (ProjectionElem::OpaqueCast { .. }, _, _)
                 | (ProjectionElem::Subtype(_), _, _)
-                | (ProjectionElem::Downcast { .. }, _, _) => {
+                | (ProjectionElem::Downcast { .. }, _, _)
+                | (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => {
                     // Recursive case. This can still be disjoint on a
                     // further iteration if this a shallow access and
                     // there's a deref later on, e.g., a borrow
@@ -519,5 +520,9 @@ fn place_projection_conflict<'tcx>(
             pi1_elem,
             pi2_elem
         ),
+
+        (ProjectionElem::UnwrapUnsafeBinder(_), _) => {
+            todo!()
+        }
     }
 }
diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
index f79bcf5af55..0d1d8642bca 100644
--- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
@@ -325,6 +325,10 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
                     self.consume_operand(location, operand);
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(op, _) => {
+                self.consume_operand(location, op);
+            }
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index fc7e6e58641..83cca38a5c0 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -66,6 +66,10 @@ impl<'tcx> Iterator for Prefixes<'tcx> {
                             self.next = Some(cursor_base);
                             return Some(cursor);
                         }
+                        ProjectionElem::UnwrapUnsafeBinder(_) => {
+                            self.next = Some(cursor_base);
+                            return Some(cursor);
+                        }
                         ProjectionElem::Downcast(..)
                         | ProjectionElem::Subslice { .. }
                         | ProjectionElem::OpaqueCast { .. }
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 2c37d2bc123..11b30c145c2 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -459,13 +459,6 @@ pub(crate) enum OnClosureNote<'a> {
 }
 
 #[derive(Subdiagnostic)]
-#[note(borrowck_long_type_full_path)]
-#[note(borrowck_long_type_consider_verbose)]
-pub(crate) struct LongTypePath {
-    pub(crate) path: String,
-}
-
-#[derive(Subdiagnostic)]
 pub(crate) enum TypeNoCopy<'a> {
     #[label(borrowck_ty_no_impl_copy)]
     Label {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index a2ef5588f48..92492bfdb8d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -302,6 +302,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     )
                     .unwrap();
             }
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
+                    unreachable!();
+                };
+                let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars(
+                    self.body().source_info(location).span,
+                    BoundRegionConversionTime::HigherRankedType,
+                    binder_ty.into(),
+                );
+                self.typeck
+                    .relate_types(
+                        ty,
+                        context.ambient_variance(),
+                        found_ty,
+                        location.to_locations(),
+                        ConstraintCategory::Boring,
+                    )
+                    .unwrap();
+            }
             ProjectionElem::Subtype(_) => {
                 bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
             }
@@ -2233,6 +2252,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.check_operand(right, location);
             }
 
+            Rvalue::WrapUnsafeBinder(op, ty) => {
+                self.check_operand(op, location);
+                let operand_ty = op.ty(self.body, self.tcx());
+
+                let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
+                    unreachable!();
+                };
+                let expected_ty = self.infcx.instantiate_binder_with_fresh_vars(
+                    self.body().source_info(location).span,
+                    BoundRegionConversionTime::HigherRankedType,
+                    binder_ty.into(),
+                );
+                self.sub_types(
+                    operand_ty,
+                    expected_ty,
+                    location.to_locations(),
+                    ConstraintCategory::Boring,
+                )
+                .unwrap();
+            }
+
             Rvalue::RawPtr(..)
             | Rvalue::ThreadLocalRef(..)
             | Rvalue::Len(..)
@@ -2258,7 +2298,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::NullaryOp(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::UnaryOp(..)
-            | Rvalue::Discriminant(..) => None,
+            | Rvalue::Discriminant(..)
+            | Rvalue::WrapUnsafeBinder(..) => None,
 
             Rvalue::Aggregate(aggregate, _) => match **aggregate {
                 AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
@@ -2450,7 +2491,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 | ProjectionElem::OpaqueCast(..)
                 | ProjectionElem::Index(..)
                 | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Subslice { .. } => {
+                | ProjectionElem::Subslice { .. }
+                | ProjectionElem::UnwrapUnsafeBinder(_) => {
                     // other field access
                 }
                 ProjectionElem::Subtype(_) => {
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 7c746bd719f..90447da6680 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -8,7 +8,9 @@ use rustc_ast::{
     token,
 };
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans};
+use rustc_errors::{
+    Applicability, Diag, MultiSpan, PResult, SingleLabelManySpans, listify, pluralize,
+};
 use rustc_expand::base::*;
 use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, LintId};
@@ -975,15 +977,11 @@ fn report_invalid_references(
         } else {
             MultiSpan::from_spans(invalid_refs.iter().filter_map(|&(_, span, _, _)| span).collect())
         };
-        let arg_list = if let &[index] = &indexes[..] {
-            format!("argument {index}")
-        } else {
-            let tail = indexes.pop().unwrap();
-            format!(
-                "arguments {head} and {tail}",
-                head = indexes.into_iter().map(|i| i.to_string()).collect::<Vec<_>>().join(", ")
-            )
-        };
+        let arg_list = format!(
+            "argument{} {}",
+            pluralize!(indexes.len()),
+            listify(&indexes, |i: &usize| i.to_string()).unwrap_or_default()
+        );
         e = ecx.dcx().struct_span_err(
             span,
             format!("invalid reference to positional {arg_list} ({num_args_desc})"),
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index c7c9c6236d1..7a40d236b92 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -925,6 +925,10 @@ fn codegen_stmt<'tcx>(
                     }
                     crate::discriminant::codegen_set_discriminant(fx, lval, variant_index);
                 }
+                Rvalue::WrapUnsafeBinder(ref operand, _to_ty) => {
+                    let operand = codegen_operand(fx, operand);
+                    lval.write_cvalue_transmute(fx, operand);
+                }
             }
         }
         StatementKind::StorageLive(_)
@@ -993,7 +997,9 @@ pub(crate) fn codegen_place<'tcx>(
                 cplace = cplace.place_deref(fx);
             }
             PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
-            PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)),
+            PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => {
+                cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty));
+            }
             PlaceElem::Field(field, _ty) => {
                 cplace = cplace.place_field(fx, field);
             }
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 27adf6318e2..a52b18573b1 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -692,7 +692,7 @@ pub(crate) fn run_aot(
 
     if tcx.dep_graph.is_fully_enabled() {
         for cgu in cgus {
-            tcx.ensure().codegen_unit(cgu.name());
+            tcx.ensure_ok().codegen_unit(cgu.name());
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
index ae813fe5ebf..92b0ce8ffe1 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs
@@ -4,6 +4,8 @@ use libc::{c_char, c_uint};
 
 use super::ffi::{BasicBlock, Metadata, Module, Type, Value};
 use crate::llvm::Bool;
+
+#[link(name = "llvm-wrapper", kind = "static")]
 extern "C" {
     // Enzyme
     pub fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool;
@@ -12,10 +14,13 @@ extern "C" {
     pub fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>;
     pub fn LLVMRustEraseInstFromParent(V: &Value);
     pub fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value;
-    pub fn LLVMDumpModule(M: &Module);
-    pub fn LLVMDumpValue(V: &Value);
     pub fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool;
+}
 
+extern "C" {
+    // Enzyme
+    pub fn LLVMDumpModule(M: &Module);
+    pub fn LLVMDumpValue(V: &Value);
     pub fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
     pub fn LLVMGetReturnType(T: &Type) -> &Type;
     pub fn LLVMGetParams(Fnc: &Value, parms: *mut &Value);
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 6e0333cf3ce..df945920ee8 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -634,7 +634,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     // unnecessarily.
     if tcx.dep_graph.is_fully_enabled() {
         for cgu in codegen_units {
-            tcx.ensure().codegen_unit(cgu.name());
+            tcx.ensure_ok().codegen_unit(cgu.name());
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index c634f864ffb..73a41676802 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -502,6 +502,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     bug!("encountered OpaqueCast({ty}) in codegen")
                 }
                 mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)),
+                mir::ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                    cg_base.project_type(bx, self.monomorphize(ty))
+                }
                 mir::ProjectionElem::Index(index) => {
                     let index = &mir::Operand::Copy(mir::Place::from(index));
                     let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d7fc5e8e673..85de3238b3e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -823,6 +823,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
                 OperandRef { val: OperandValue::Immediate(val), layout: box_layout }
             }
+            mir::Rvalue::WrapUnsafeBinder(ref operand, binder_ty) => {
+                let operand = self.codegen_operand(bx, operand);
+                let binder_ty = self.monomorphize(binder_ty);
+                let layout = bx.cx().layout_of(binder_ty);
+                OperandRef { val: operand.val, layout }
+            }
         }
     }
 
@@ -1123,7 +1129,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Discriminant(..) |
             mir::Rvalue::NullaryOp(..) |
             mir::Rvalue::ThreadLocalRef(_) |
-            mir::Rvalue::Use(..) => // (*)
+            mir::Rvalue::Use(..) |
+            mir::Rvalue::WrapUnsafeBinder(..) => // (*)
                 true,
             // Arrays are always aggregates, so it's not worth checking anything here.
             // (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 4834fd3d34c..e8052a3c83a 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -728,6 +728,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     );
                 }
             }
+
+            Rvalue::WrapUnsafeBinder(..) => {
+                // Unsafe binders are always trivial to create.
+            }
         }
     }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 5d368b600a0..9c99782d223 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -258,6 +258,8 @@ where
             in_place::<Q, _>(cx, in_local, place.as_ref())
         }
 
+        Rvalue::WrapUnsafeBinder(op, _) => in_operand::<Q, _>(cx, in_local, op),
+
         Rvalue::Aggregate(kind, operands) => {
             // Return early if we know that the struct or enum being constructed is always
             // qualified.
@@ -297,7 +299,8 @@ where
             | ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Downcast(_, _)
-            | ProjectionElem::Index(_) => {}
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {}
         }
 
         let base_ty = place_base.ty(cx.body, cx.tcx);
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 79df63a9e84..8cee282311f 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -202,7 +202,8 @@ where
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
             | mir::Rvalue::Discriminant(..)
-            | mir::Rvalue::Aggregate(..) => {}
+            | mir::Rvalue::Aggregate(..)
+            | mir::Rvalue::WrapUnsafeBinder(..) => {}
         }
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 996142d7b03..8ecb3e13d5c 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -381,6 +381,7 @@ where
             OpaqueCast(ty) => {
                 span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
             }
+            UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?,
             // We don't want anything happening here, this is here as a dummy.
             Subtype(_) => base.transmute(base.layout(), self)?,
             Field(field, _) => self.project_field(base, field.index())?,
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index d9c0ff5acd1..abe73c43d8a 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -277,6 +277,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
                 self.write_immediate(*discr, &dest)?;
             }
+
+            WrapUnsafeBinder(ref op, _ty) => {
+                // Constructing an unsafe binder acts like a transmute
+                // since the operand's layout does not change.
+                let op = self.eval_operand(op, None)?;
+                self.copy_op_allow_transmute(&op, &dest)?;
+            }
         }
 
         trace!("{:?}", self.dump_place(&dest));
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index c9d38a0f932..d4899261487 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -317,7 +317,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
         if let Some(pp_mode) = sess.opts.pretty {
             if pp_mode.needs_ast_map() {
                 create_and_enter_global_ctxt(compiler, krate, |tcx| {
-                    tcx.ensure().early_lint_checks(());
+                    tcx.ensure_ok().early_lint_checks(());
                     pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx });
                     passes::write_dep_info(tcx);
                 });
@@ -365,7 +365,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
                 return early_exit();
             }
 
-            tcx.ensure().analysis(());
+            tcx.ensure_ok().analysis(());
 
             if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
                 return early_exit();
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 699742aa0ea..9ace486fa56 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -222,7 +222,7 @@ impl<'tcx> PrintExtra<'tcx> {
 
 pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
     if ppm.needs_analysis() {
-        ex.tcx().ensure().analysis(());
+        ex.tcx().ensure_ok().analysis(());
     }
 
     let (src, src_name) = get_source(sess);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 797dcd7b4d1..b96df814852 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -4,6 +4,7 @@ use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::ops::{Deref, DerefMut};
 use std::panic;
+use std::path::PathBuf;
 use std::thread::panicking;
 
 use rustc_data_structures::fx::FxIndexMap;
@@ -301,6 +302,7 @@ pub struct DiagInner {
 
     pub is_lint: Option<IsLint>,
 
+    pub long_ty_path: Option<PathBuf>,
     /// With `-Ztrack_diagnostics` enabled,
     /// we print where in rustc this error was emitted.
     pub(crate) emitted_at: DiagLocation,
@@ -324,6 +326,7 @@ impl DiagInner {
             args: Default::default(),
             sort_span: DUMMY_SP,
             is_lint: None,
+            long_ty_path: None,
             emitted_at: DiagLocation::caller(),
         }
     }
@@ -1293,9 +1296,37 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
     /// `cancel`, etc. Afterwards, `drop` is the only code that will be run on
     /// `self`.
     fn take_diag(&mut self) -> DiagInner {
+        if let Some(path) = &self.long_ty_path {
+            self.note(format!(
+                "the full name for the type has been written to '{}'",
+                path.display()
+            ));
+            self.note("consider using `--verbose` to print the full type name to the console");
+        }
         Box::into_inner(self.diag.take().unwrap())
     }
 
+    /// This method allows us to access the path of the file where "long types" are written to.
+    ///
+    /// When calling `Diag::emit`, as part of that we will check if a `long_ty_path` has been set,
+    /// and if it has been then we add a note mentioning the file where the "long types" were
+    /// written to.
+    ///
+    /// When calling `tcx.short_string()` after a `Diag` is constructed, the preferred way of doing
+    /// so is `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that
+    /// keeps the existence of a "long type" anywhere in the diagnostic, so the note telling the
+    /// user where we wrote the file to is only printed once at most, *and* it makes it much harder
+    /// to forget to set it.
+    ///
+    /// If the diagnostic hasn't been created before a "short ty string" is created, then you should
+    /// ensure that this method is called to set it `*diag.long_ty_path() = path`.
+    ///
+    /// As a rule of thumb, if you see or add at least one `tcx.short_string()` call anywhere, in a
+    /// scope, `diag.long_ty_path()` should be called once somewhere close by.
+    pub fn long_ty_path(&mut self) -> &mut Option<PathBuf> {
+        &mut self.long_ty_path
+    }
+
     /// Most `emit_producing_guarantee` functions use this as a starting point.
     fn emit_producing_nothing(mut self) {
         let diag = self.take_diag();
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 549729548f5..a6458c9ffdc 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -65,7 +65,7 @@ pub use rustc_error_messages::{
     SubdiagMessage, fallback_fluent_bundle, fluent_bundle,
 };
 use rustc_lint_defs::LintExpectationId;
-pub use rustc_lint_defs::{Applicability, pluralize};
+pub use rustc_lint_defs::{Applicability, listify, pluralize};
 use rustc_macros::{Decodable, Encodable};
 pub use rustc_span::ErrorGuaranteed;
 pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
@@ -1999,18 +1999,6 @@ pub fn a_or_an(s: &str) -> &'static str {
     }
 }
 
-/// Grammatical tool for displaying messages to end users in a nice form.
-///
-/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
-pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
-    match v {
-        [] => "".to_string(),
-        [a] => a.to_string(),
-        [a, b] => format!("{a} and {b}"),
-        [a, v @ ..] => format!("{a}, {}", display_list_with_comma_and(v)),
-    }
-}
-
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TerminalUrl {
     No,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 40049f96de4..6c534d58a7d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -778,13 +778,13 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     match tcx.def_kind(def_id) {
         DefKind::Static { .. } => {
-            tcx.ensure().typeck(def_id);
+            tcx.ensure_ok().typeck(def_id);
             maybe_check_static_with_link_section(tcx, def_id);
             check_static_inhabited(tcx, def_id);
             check_static_linkage(tcx, def_id);
         }
         DefKind::Const => {
-            tcx.ensure().typeck(def_id);
+            tcx.ensure_ok().typeck(def_id);
         }
         DefKind::Enum => {
             check_enum(tcx, def_id);
@@ -804,7 +804,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
                 if tcx
-                    .ensure()
+                    .ensure_ok()
                     .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
                     .is_ok()
                 {
@@ -1042,7 +1042,7 @@ fn check_impl_items_against_trait<'tcx>(
             continue;
         };
 
-        let res = tcx.ensure().compare_impl_item(impl_item.expect_local());
+        let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
 
         if res.is_ok() {
             match ty_impl_item.kind {
@@ -1488,7 +1488,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     for v in def.variants() {
         if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr {
-            tcx.ensure().typeck(discr_def_id.expect_local());
+            tcx.ensure_ok().typeck(discr_def_id.expect_local());
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 3bff5fe02c0..a91d72e9225 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2034,7 +2034,7 @@ pub(super) fn check_type_bounds<'tcx>(
 ) -> Result<(), ErrorGuaranteed> {
     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
     // other `Foo` impls are incoherent.
-    tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
+    tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?;
 
     let param_env = tcx.param_env(impl_ty.def_id);
     debug!(?param_env);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index c9837ca3716..79e2d764ac5 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1046,7 +1046,7 @@ fn check_associated_item(
 
         // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
         // other `Foo` impls are incoherent.
-        tcx.ensure()
+        tcx.ensure_ok()
             .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
 
         let self_ty = match item.container {
@@ -1354,7 +1354,7 @@ fn check_impl<'tcx>(
                 let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
                 // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                 // other `Foo` impls are incoherent.
-                tcx.ensure().coherent_trait(trait_ref.def_id)?;
+                tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
                 let trait_span = hir_trait_ref.path.span;
                 let trait_ref = wfcx.normalize(
                     trait_span,
@@ -2268,11 +2268,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
 fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
     let items = tcx.hir_module_items(module);
     let res = items
-        .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))
-        .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
-        .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
+        .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))
+        .and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
+        .and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)))
+        .and(
+            items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)),
+        )
+        .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item)));
     if module == LocalModDefId::CRATE_DEF_ID {
         super::entry::check_for_entry_fn(tcx);
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 30f51fe1724..3511dbc6252 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -192,7 +192,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
     // errors; other parts of the code may demand it for the info of
     // course.
     let span = tcx.def_span(impl_did);
-    tcx.at(span).ensure().coerce_unsized_info(impl_did)
+    tcx.at(span).ensure_ok().coerce_unsized_info(impl_did)
 }
 
 fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index b9ef166fc3f..1bc60087ab5 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -151,7 +151,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
     let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) };
     // Trigger building the specialization graph for the trait. This will detect and report any
     // overlap errors.
-    let mut res = tcx.ensure().specialization_graph_of(def_id);
+    let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
 
     for &impl_def_id in impls {
         let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
@@ -162,7 +162,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
             .and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
             .and(check_object_overlap(tcx, impl_def_id, trait_ref))
             .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
-            .and(tcx.ensure().orphan_check_impl(impl_def_id))
+            .and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
             .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 226370fccad..ce7319f6561 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -292,16 +292,16 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => {}
                 hir::GenericParamKind::Type { default: Some(_), .. } => {
-                    self.tcx.ensure().type_of(param.def_id);
+                    self.tcx.ensure_ok().type_of(param.def_id);
                 }
                 hir::GenericParamKind::Type { .. } => {}
                 hir::GenericParamKind::Const { default, .. } => {
-                    self.tcx.ensure().type_of(param.def_id);
+                    self.tcx.ensure_ok().type_of(param.def_id);
                     if let Some(default) = default {
                         // need to store default and type of default
-                        self.tcx.ensure().const_param_default(param.def_id);
+                        self.tcx.ensure_ok().const_param_default(param.def_id);
                         if let hir::ConstArgKind::Anon(ac) = default.kind {
-                            self.tcx.ensure().type_of(ac.def_id);
+                            self.tcx.ensure_ok().type_of(ac.def_id);
                         }
                     }
                 }
@@ -312,8 +312,8 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Closure(closure) = expr.kind {
-            self.tcx.ensure().generics_of(closure.def_id);
-            self.tcx.ensure().codegen_fn_attrs(closure.def_id);
+            self.tcx.ensure_ok().generics_of(closure.def_id);
+            self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id);
             // We do not call `type_of` for closures here as that
             // depends on typecheck and would therefore hide
             // any further errors in case one typeck fails.
@@ -325,15 +325,15 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
     /// `check_item_type` ensures that it's called instead.
     fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
         let def_id = opaque.def_id;
-        self.tcx.ensure().generics_of(def_id);
-        self.tcx.ensure().predicates_of(def_id);
-        self.tcx.ensure().explicit_item_bounds(def_id);
-        self.tcx.ensure().explicit_item_self_bounds(def_id);
-        self.tcx.ensure().item_bounds(def_id);
-        self.tcx.ensure().item_self_bounds(def_id);
+        self.tcx.ensure_ok().generics_of(def_id);
+        self.tcx.ensure_ok().predicates_of(def_id);
+        self.tcx.ensure_ok().explicit_item_bounds(def_id);
+        self.tcx.ensure_ok().explicit_item_self_bounds(def_id);
+        self.tcx.ensure_ok().item_bounds(def_id);
+        self.tcx.ensure_ok().item_self_bounds(def_id);
         if self.tcx.is_conditionally_const(def_id) {
-            self.tcx.ensure().explicit_implied_const_bounds(def_id);
-            self.tcx.ensure().const_conditions(def_id);
+            self.tcx.ensure_ok().explicit_implied_const_bounds(def_id);
+            self.tcx.ensure_ok().const_conditions(def_id);
         }
         intravisit::walk_opaque_ty(self, opaque);
     }
@@ -683,20 +683,20 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         hir::ItemKind::ForeignMod { items, .. } => {
             for item in *items {
                 let item = tcx.hir().foreign_item(item.id);
-                tcx.ensure().generics_of(item.owner_id);
-                tcx.ensure().type_of(item.owner_id);
-                tcx.ensure().predicates_of(item.owner_id);
+                tcx.ensure_ok().generics_of(item.owner_id);
+                tcx.ensure_ok().type_of(item.owner_id);
+                tcx.ensure_ok().predicates_of(item.owner_id);
                 if tcx.is_conditionally_const(def_id) {
-                    tcx.ensure().explicit_implied_const_bounds(def_id);
-                    tcx.ensure().const_conditions(def_id);
+                    tcx.ensure_ok().explicit_implied_const_bounds(def_id);
+                    tcx.ensure_ok().const_conditions(def_id);
                 }
                 match item.kind {
                     hir::ForeignItemKind::Fn(..) => {
-                        tcx.ensure().codegen_fn_attrs(item.owner_id);
-                        tcx.ensure().fn_sig(item.owner_id)
+                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
+                        tcx.ensure_ok().fn_sig(item.owner_id)
                     }
                     hir::ForeignItemKind::Static(..) => {
-                        tcx.ensure().codegen_fn_attrs(item.owner_id);
+                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
                         let mut visitor = HirPlaceholderCollector::default();
                         visitor.visit_foreign_item(item);
                         placeholder_type_error(
@@ -713,40 +713,40 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             }
         }
         hir::ItemKind::Enum(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
             lower_enum_variant_types(tcx, def_id.to_def_id());
         }
         hir::ItemKind::Impl { .. } => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().impl_trait_header(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().associated_items(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().impl_trait_header(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().associated_items(def_id);
         }
         hir::ItemKind::Trait(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().trait_def(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().trait_def(def_id);
             tcx.at(it.span).explicit_super_predicates_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().associated_items(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().associated_items(def_id);
         }
         hir::ItemKind::TraitAlias(..) => {
-            tcx.ensure().generics_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
             tcx.at(it.span).explicit_implied_predicates_of(def_id);
             tcx.at(it.span).explicit_super_predicates_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
         }
         hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
 
             for f in struct_def.fields() {
-                tcx.ensure().generics_of(f.def_id);
-                tcx.ensure().type_of(f.def_id);
-                tcx.ensure().predicates_of(f.def_id);
+                tcx.ensure_ok().generics_of(f.def_id);
+                tcx.ensure_ok().type_of(f.def_id);
+                tcx.ensure_ok().predicates_of(f.def_id);
             }
 
             if let Some(ctor_def_id) = struct_def.ctor_def_id() {
@@ -755,15 +755,15 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         }
 
         hir::ItemKind::TyAlias(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
         }
 
         hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
             if !ty.is_suggestable_infer_ty() {
                 let mut visitor = HirPlaceholderCollector::default();
                 visitor.visit_item(it);
@@ -779,11 +779,11 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
         }
 
         hir::ItemKind::Fn { .. } => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().fn_sig(def_id);
-            tcx.ensure().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().generics_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().predicates_of(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
         }
     }
 }
@@ -791,18 +791,18 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
 fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
     let trait_item = tcx.hir().trait_item(trait_item_id);
     let def_id = trait_item_id.owner_id;
-    tcx.ensure().generics_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
     let icx = ItemCtxt::new(tcx, def_id.def_id);
 
     match trait_item.kind {
         hir::TraitItemKind::Fn(..) => {
-            tcx.ensure().codegen_fn_attrs(def_id);
-            tcx.ensure().type_of(def_id);
-            tcx.ensure().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().type_of(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
         }
 
         hir::TraitItemKind::Const(ty, body_id) => {
-            tcx.ensure().type_of(def_id);
+            tcx.ensure_ok().type_of(def_id);
             if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
                 && !(ty.is_suggestable_infer_ty() && body_id.is_some())
             {
@@ -821,9 +821,9 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
 
         hir::TraitItemKind::Type(_, Some(_)) => {
-            tcx.ensure().item_bounds(def_id);
-            tcx.ensure().item_self_bounds(def_id);
-            tcx.ensure().type_of(def_id);
+            tcx.ensure_ok().item_bounds(def_id);
+            tcx.ensure_ok().item_self_bounds(def_id);
+            tcx.ensure_ok().type_of(def_id);
             // Account for `type T = _;`.
             let mut visitor = HirPlaceholderCollector::default();
             visitor.visit_trait_item(trait_item);
@@ -838,8 +838,8 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
 
         hir::TraitItemKind::Type(_, None) => {
-            tcx.ensure().item_bounds(def_id);
-            tcx.ensure().item_self_bounds(def_id);
+            tcx.ensure_ok().item_bounds(def_id);
+            tcx.ensure_ok().item_self_bounds(def_id);
             // #74612: Visit and try to find bad placeholders
             // even if there is no concrete type.
             let mut visitor = HirPlaceholderCollector::default();
@@ -856,20 +856,20 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
         }
     };
 
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
 }
 
 fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
     let def_id = impl_item_id.owner_id;
-    tcx.ensure().generics_of(def_id);
-    tcx.ensure().type_of(def_id);
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
+    tcx.ensure_ok().type_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
     let impl_item = tcx.hir().impl_item(impl_item_id);
     let icx = ItemCtxt::new(tcx, def_id.def_id);
     match impl_item.kind {
         hir::ImplItemKind::Fn(..) => {
-            tcx.ensure().codegen_fn_attrs(def_id);
-            tcx.ensure().fn_sig(def_id);
+            tcx.ensure_ok().codegen_fn_attrs(def_id);
+            tcx.ensure_ok().fn_sig(def_id);
         }
         hir::ImplItemKind::Type(_) => {
             // Account for `type T = _;`
@@ -904,9 +904,9 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
 }
 
 fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    tcx.ensure().generics_of(def_id);
-    tcx.ensure().type_of(def_id);
-    tcx.ensure().predicates_of(def_id);
+    tcx.ensure_ok().generics_of(def_id);
+    tcx.ensure_ok().type_of(def_id);
+    tcx.ensure_ok().predicates_of(def_id);
 }
 
 fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
@@ -937,9 +937,9 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
         );
 
         for f in &variant.fields {
-            tcx.ensure().generics_of(f.did);
-            tcx.ensure().type_of(f.did);
-            tcx.ensure().predicates_of(f.did);
+            tcx.ensure_ok().generics_of(f.did);
+            tcx.ensure_ok().type_of(f.did);
+            tcx.ensure_ok().predicates_of(f.did);
         }
 
         // Lower the ctor, if any. This also registers the variant as an item.
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 36b214b6ae7..79aa2f4b8cc 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -808,14 +808,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .map(|(trait_, mut assocs)| {
                 assocs.sort();
                 let trait_ = trait_.print_trait_sugared();
-                format!("{} in `{trait_}`", match &assocs[..] {
-                    [] => String::new(),
-                    [only] => format!("`{only}`"),
-                    [assocs @ .., last] => format!(
-                        "{} and `{last}`",
-                        assocs.iter().map(|a| format!("`{a}`")).collect::<Vec<_>>().join(", ")
-                    ),
-                })
+                format!(
+                    "{} in `{trait_}`",
+                    listify(&assocs[..], |a| format!("`{a}`")).unwrap_or_default()
+                )
             })
             .collect::<Vec<String>>();
         names.sort();
@@ -1075,18 +1071,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
             })
             .collect();
-        let this_type = match &types_and_spans[..] {
-            [.., _, (last, _)] => format!(
-                "{} and {last}",
-                types_and_spans[..types_and_spans.len() - 1]
-                    .iter()
-                    .map(|(x, _)| x.as_str())
-                    .intersperse(", ")
-                    .collect::<String>()
-            ),
-            [(only, _)] => only.to_string(),
-            [] => bug!("expected one segment to deny"),
-        };
+        let this_type = listify(&types_and_spans, |(t, _)| t.to_string())
+            .expect("expected one segment to deny");
 
         let arg_spans: Vec<Span> = segments
             .clone()
@@ -1102,21 +1088,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             ProhibitGenericsArg::Infer => kinds.push("generic"),
         });
 
-        let (kind, s) = match kinds[..] {
-            [.., _, last] => (
-                format!(
-                    "{} and {last}",
-                    kinds[..kinds.len() - 1]
-                        .iter()
-                        .map(|&x| x)
-                        .intersperse(", ")
-                        .collect::<String>()
-                ),
-                "s",
-            ),
-            [only] => (only.to_string(), ""),
-            [] => bug!("expected at least one generic to prohibit"),
-        };
+        let s = pluralize!(kinds.len());
+        let kind =
+            listify(&kinds, |k| k.to_string()).expect("expected at least one generic to prohibit");
         let last_span = *arg_spans.last().unwrap();
         let span: MultiSpan = arg_spans.into();
         let mut err = struct_span_code_err!(
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index fd5a7089b4c..c30b39dfe76 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -62,7 +62,7 @@ pub(crate) fn check_impl_wf(
     // Check that the args are constrained. We queryfied the check for ty/const params
     // since unconstrained type/const params cause ICEs in projection, so we want to
     // detect those specifically and project those to `TyKind::Error`.
-    let mut res = tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
+    let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id);
     res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id));
 
     if tcx.features().min_specialization() {
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index ae054a9eaeb..3af4318544e 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -100,7 +100,7 @@ use rustc_middle::middle;
 use rustc_middle::mir::interpret::GlobalId;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits;
 
 pub use crate::collect::suggest_impl_trait;
@@ -139,16 +139,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     let _prof_timer = tcx.sess.timer("type_check_crate");
 
     tcx.sess.time("coherence_checking", || {
+        // When discarding query call results, use an explicit type to indicate
+        // what we are intending to discard, to help future type-based refactoring.
+        type R = Result<(), ErrorGuaranteed>;
+
         tcx.hir().par_for_each_module(|module| {
-            let _ = tcx.ensure().check_mod_type_wf(module);
+            let _: R = tcx.ensure_ok().check_mod_type_wf(module);
         });
 
         for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
-            let _ = tcx.ensure().coherent_trait(trait_def_id);
+            let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
         }
         // these queries are executed for side-effects (error reporting):
-        let _ = tcx.ensure().crate_inherent_impls_validity_check(());
-        let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
+        let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(());
+        let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
     });
 
     if tcx.features().rustc_attrs() {
@@ -167,12 +171,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.hir().par_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
         match def_kind {
-            DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id),
+            DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
             DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
                 let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
                 let cid = GlobalId { instance, promoted: None };
                 let typing_env = ty::TypingEnv::fully_monomorphized();
-                tcx.ensure().eval_to_const_value_raw(typing_env.as_query_input(cid));
+                tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
             }
             _ => (),
         }
@@ -185,11 +189,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.hir().par_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
         if !matches!(def_kind, DefKind::AnonConst) {
-            tcx.ensure().typeck(item_def_id);
+            tcx.ensure_ok().typeck(item_def_id);
         }
     });
 
-    tcx.ensure().check_unused_traits(());
+    tcx.ensure_ok().check_unused_traits(());
 }
 
 /// Lower a [`hir::Ty`] to a [`Ty`].
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 28b1a823dae..edc3702d90b 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -49,7 +49,7 @@ pub(crate) fn check_legal_trait_for_method_call(
         };
         return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }));
     }
-    tcx.ensure().coherent_trait(trait_id)
+    tcx.ensure_ok().coherent_trait(trait_id)
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index bc076670585..85e949952f8 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{Applicability, Diag, MultiSpan};
+use rustc_errors::{Applicability, Diag, MultiSpan, listify};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::Visitor;
@@ -1016,18 +1016,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 },
                 self.tcx.def_path_str(candidate.item.container_id(self.tcx))
             ),
-            [.., last] if other_methods_in_scope.len() < 5 => {
+            _ if other_methods_in_scope.len() < 5 => {
                 format!(
-                    "the methods of the same name on {} and `{}`",
-                    other_methods_in_scope[..other_methods_in_scope.len() - 1]
-                        .iter()
-                        .map(|c| format!(
-                            "`{}`",
-                            self.tcx.def_path_str(c.item.container_id(self.tcx))
-                        ))
-                        .collect::<Vec<String>>()
-                        .join(", "),
-                    self.tcx.def_path_str(last.item.container_id(self.tcx))
+                    "the methods of the same name on {}",
+                    listify(
+                        &other_methods_in_scope[..other_methods_in_scope.len() - 1],
+                        |c| format!("`{}`", self.tcx.def_path_str(c.item.container_id(self.tcx)))
+                    )
+                    .unwrap_or_default(),
                 )
             }
             _ => format!(
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index f79667e59ba..a519e177fbc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, pluralize,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, listify, pluralize,
     struct_span_code_err,
 };
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -1658,8 +1658,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         hir_ty: Option<&'tcx hir::Ty<'tcx>>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        self.dcx().span_err(inner_expr.span, "unsafe binder casts are not fully implemented");
-
         match kind {
             hir::UnsafeBinderCastKind::Wrap => {
                 let ascribed_ty =
@@ -2190,13 +2188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             if !missing_mandatory_fields.is_empty() {
                 let s = pluralize!(missing_mandatory_fields.len());
-                let fields: Vec<_> =
-                    missing_mandatory_fields.iter().map(|f| format!("`{f}`")).collect();
-                let fields = match &fields[..] {
-                    [] => unreachable!(),
-                    [only] => only.to_string(),
-                    [start @ .., last] => format!("{} and {last}", start.join(", ")),
-                };
+                let fields = listify(&missing_mandatory_fields, |f| format!("`{f}`")).unwrap();
                 self.dcx()
                     .struct_span_err(
                         span.shrink_to_hi(),
@@ -2553,25 +2545,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .partition(|field| field.2);
         err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field");
         if !remaining_private_fields.is_empty() {
-            let remaining_private_fields_len = remaining_private_fields.len();
-            let names = match &remaining_private_fields
-                .iter()
-                .map(|(name, _, _)| name)
-                .collect::<Vec<_>>()[..]
-            {
-                _ if remaining_private_fields_len > 6 => String::new(),
-                [name] => format!("`{name}` "),
-                [names @ .., last] => {
-                    let names = names.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
-                    format!("{} and `{last}` ", names.join(", "))
-                }
-                [] => bug!("expected at least one private field to report"),
+            let names = if remaining_private_fields.len() > 6 {
+                String::new()
+            } else {
+                format!(
+                    "{} ",
+                    listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`"))
+                        .expect("expected at least one private field to report")
+                )
             };
             err.note(format!(
                 "{}private field{s} {names}that {were} not provided",
                 if used_fields.is_empty() { "" } else { "...and other " },
-                s = pluralize!(remaining_private_fields_len),
-                were = pluralize!("was", remaining_private_fields_len),
+                s = pluralize!(remaining_private_fields.len()),
+                were = pluralize!("was", remaining_private_fields.len()),
             ));
         }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index fb5fc109ce4..bbe65371496 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -4,8 +4,7 @@ use itertools::Itertools;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::codes::*;
 use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an,
-    display_list_with_comma_and, pluralize,
+    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize,
 };
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -2462,7 +2461,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 param.span,
                                 format!(
                                     "{} need{} to match the {} type of this parameter",
-                                    display_list_with_comma_and(&other_param_matched_names),
+                                    listify(&other_param_matched_names, |n| n.to_string())
+                                        .unwrap_or_default(),
                                     pluralize!(if other_param_matched_names.len() == 1 {
                                         0
                                     } else {
@@ -2477,7 +2477,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 format!(
                                     "this parameter needs to match the {} type of {}",
                                     matched_ty,
-                                    display_list_with_comma_and(&other_param_matched_names),
+                                    listify(&other_param_matched_names, |n| n.to_string())
+                                        .unwrap_or_default(),
                                 ),
                             );
                         }
@@ -2523,7 +2524,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             generic_param.span,
                             format!(
                                 "{} {} reference this parameter `{}`",
-                                display_list_with_comma_and(&param_idents_matching),
+                                listify(&param_idents_matching, |n| n.to_string())
+                                    .unwrap_or_default(),
                                 if param_idents_matching.len() == 2 { "both" } else { "all" },
                                 generic_param.name.ident().name,
                             ),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 60f9265bfcc..beddbf971fd 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -4,7 +4,7 @@ use core::iter;
 use hir::def_id::LocalDefId;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_data_structures::packed::Pu128;
-use rustc_errors::{Applicability, Diag, MultiSpan};
+use rustc_errors::{Applicability, Diag, MultiSpan, listify};
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{
@@ -1836,16 +1836,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 error.obligation.predicate,
                             ));
                         }
-                        [errors @ .., last] => {
+                        _ => {
                             diag.help(format!(
                                 "`Clone` is not implemented because the following trait bounds \
-                                 could not be satisfied: {} and `{}`",
-                                errors
-                                    .iter()
-                                    .map(|e| format!("`{}`", e.obligation.predicate))
-                                    .collect::<Vec<_>>()
-                                    .join(", "),
-                                last.obligation.predicate,
+                                 could not be satisfied: {}",
+                                listify(&errors, |e| format!("`{}`", e.obligation.predicate))
+                                    .unwrap(),
                             ));
                         }
                     }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index e4a6a0fedc5..920418407c0 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -5,6 +5,7 @@
 
 use core::ops::ControlFlow;
 use std::borrow::Cow;
+use std::path::PathBuf;
 
 use hir::Expr;
 use rustc_ast::ast::Mutability;
@@ -362,14 +363,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
         let mut file = None;
-        let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
         let mut err = struct_span_code_err!(
             self.dcx(),
             rcvr_expr.span,
             E0599,
             "cannot write into `{}`",
-            ty_str
+            self.tcx.short_string(rcvr_ty, &mut file),
         );
+        *err.long_ty_path() = file;
         err.span_note(
             rcvr_expr.span,
             "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
@@ -380,11 +381,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 "a writer is needed before this format string",
             );
         };
-        if let Some(file) = file {
-            err.note(format!("the full type name has been written to '{}'", file.display()));
-            err.note("consider using `--verbose` to print the full type name to the console");
-        }
-
         err
     }
 
@@ -595,7 +591,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (predicates.to_string(), with_forced_trimmed_paths!(predicates.to_string()))
             } else {
                 (
-                    tcx.short_ty_string(rcvr_ty, &mut ty_file),
+                    tcx.short_string(rcvr_ty, &mut ty_file),
                     with_forced_trimmed_paths!(rcvr_ty.to_string()),
                 )
             };
@@ -624,6 +620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             span,
             item_name,
             &short_ty_str,
+            &mut ty_file,
         ) {
             return guar;
         }
@@ -635,6 +632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             item_kind,
             item_name,
             &short_ty_str,
+            &mut ty_file,
         ) {
             return guar;
         }
@@ -728,10 +726,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty_str = short_ty_str;
         }
 
-        if let Some(file) = ty_file {
-            err.note(format!("the full type name has been written to '{}'", file.display(),));
-            err.note("consider using `--verbose` to print the full type name to the console");
-        }
         if rcvr_ty.references_error() {
             err.downgrade_to_delayed_bug();
         }
@@ -1314,7 +1308,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     bound_list.into_iter().map(|(_, path)| path).collect::<Vec<_>>().join("\n");
                 let actual_prefix = rcvr_ty.prefix_string(self.tcx);
                 info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
-                let mut long_ty_file = None;
                 let (primary_message, label, notes) = if unimplemented_traits.len() == 1
                     && unimplemented_traits_only
                 {
@@ -1329,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                             let OnUnimplementedNote { message, label, notes, .. } = self
                                 .err_ctxt()
-                                .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
+                                .on_unimplemented_note(trait_ref, &obligation, &mut ty_file);
                             (message, label, notes)
                         })
                         .unwrap()
@@ -1343,15 +1336,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     )
                 });
                 err.primary_message(primary_message);
-                if let Some(file) = long_ty_file {
-                    err.note(format!(
-                        "the full name for the type has been written to '{}'",
-                        file.display(),
-                    ));
-                    err.note(
-                        "consider using `--verbose` to print the full type name to the console",
-                    );
-                }
                 if let Some(label) = label {
                     custom_span_label = true;
                     err.span_label(span, label);
@@ -2403,6 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         item_name: Ident,
         ty_str: &str,
+        long_ty_path: &mut Option<PathBuf>,
     ) -> Result<(), ErrorGuaranteed> {
         if let SelfSource::MethodCall(expr) = source {
             for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
@@ -2460,7 +2445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                     if pick.is_ok() {
                         let range_span = parent_expr.span.with_hi(expr.span.hi());
-                        return Err(self.dcx().emit_err(errors::MissingParenthesesInRange {
+                        let mut err = self.dcx().create_err(errors::MissingParenthesesInRange {
                             span,
                             ty_str: ty_str.to_string(),
                             method_name: item_name.as_str().to_string(),
@@ -2469,7 +2454,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 left: range_span.shrink_to_lo(),
                                 right: range_span.shrink_to_hi(),
                             }),
-                        }));
+                        });
+                        *err.long_ty_path() = long_ty_path.take();
+                        return Err(err.emit());
                     }
                 }
             }
@@ -2486,6 +2473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         item_kind: &str,
         item_name: Ident,
         ty_str: &str,
+        long_ty_path: &mut Option<PathBuf>,
     ) -> Result<(), ErrorGuaranteed> {
         let found_candidate = all_traits(self.tcx)
             .into_iter()
@@ -2526,6 +2514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 item_name,
                 ty_str
             );
+            *err.long_ty_path() = long_ty_path.take();
             let concrete_type = if actual.is_integral() { "i32" } else { "f32" };
             match expr.kind {
                 ExprKind::Lit(lit) => {
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 0b91c023cfc..0324ebf9fd2 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -832,20 +832,20 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     sess.time("misc_checking_1", || {
         parallel!(
             {
-                sess.time("looking_for_entry_point", || tcx.ensure().entry_fn(()));
+                sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(()));
 
                 sess.time("looking_for_derive_registrar", || {
-                    tcx.ensure().proc_macro_decls_static(())
+                    tcx.ensure_ok().proc_macro_decls_static(())
                 });
 
                 CStore::from_tcx(tcx).report_unused_deps(tcx);
             },
             {
                 tcx.hir().par_for_each_module(|module| {
-                    tcx.ensure().check_mod_loops(module);
-                    tcx.ensure().check_mod_attrs(module);
-                    tcx.ensure().check_mod_naked_functions(module);
-                    tcx.ensure().check_mod_unstable_api_usage(module);
+                    tcx.ensure_ok().check_mod_loops(module);
+                    tcx.ensure_ok().check_mod_attrs(module);
+                    tcx.ensure_ok().check_mod_naked_functions(module);
+                    tcx.ensure_ok().check_mod_unstable_api_usage(module);
                 });
             },
             {
@@ -858,8 +858,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
                 // since they might not otherwise get called.
                 // This marks the corresponding crate-level attributes
                 // as used, and ensures that their values are valid.
-                tcx.ensure().limits(());
-                tcx.ensure().stability_index(());
+                tcx.ensure_ok().limits(());
+                tcx.ensure_ok().stability_index(());
             }
         );
     });
@@ -868,7 +868,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     sess.time("MIR_coroutine_by_move_body", || {
         tcx.hir().par_body_owners(|def_id| {
             if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) {
-                tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id);
+                tcx.ensure_done().coroutine_by_move_body_def_id(def_id);
             }
         });
     });
@@ -883,13 +883,13 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
         tcx.hir().par_body_owners(|def_id| {
             // Run unsafety check because it's responsible for stealing and
             // deallocating THIR.
-            tcx.ensure().check_unsafety(def_id);
-            tcx.ensure().mir_borrowck(def_id)
+            tcx.ensure_ok().check_unsafety(def_id);
+            tcx.ensure_ok().mir_borrowck(def_id)
         });
     });
     sess.time("MIR_effect_checking", || {
         tcx.hir().par_body_owners(|def_id| {
-            tcx.ensure().has_ffi_unwind_calls(def_id);
+            tcx.ensure_ok().has_ffi_unwind_calls(def_id);
 
             // If we need to codegen, ensure that we emit all errors from
             // `mir_drops_elaborated_and_const_checked` now, to avoid discovering
@@ -897,15 +897,15 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
             if tcx.sess.opts.output_types.should_codegen()
                 || tcx.hir().body_const_context(def_id).is_some()
             {
-                tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
+                tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id);
             }
         });
     });
     sess.time("coroutine_obligations", || {
         tcx.hir().par_body_owners(|def_id| {
             if tcx.is_coroutine(def_id.to_def_id()) {
-                tcx.ensure().mir_coroutine_witnesses(def_id);
-                tcx.ensure().check_coroutine_obligations(
+                tcx.ensure_ok().mir_coroutine_witnesses(def_id);
+                tcx.ensure_ok().check_coroutine_obligations(
                     tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
                 );
             }
@@ -950,15 +950,16 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
     sess.time("misc_checking_3", || {
         parallel!(
             {
-                tcx.ensure().effective_visibilities(());
+                tcx.ensure_ok().effective_visibilities(());
 
                 parallel!(
                     {
-                        tcx.ensure().check_private_in_public(());
+                        tcx.ensure_ok().check_private_in_public(());
                     },
                     {
-                        tcx.hir()
-                            .par_for_each_module(|module| tcx.ensure().check_mod_deathness(module));
+                        tcx.hir().par_for_each_module(|module| {
+                            tcx.ensure_ok().check_mod_deathness(module)
+                        });
                     },
                     {
                         sess.time("lint_checking", || {
@@ -966,14 +967,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
                         });
                     },
                     {
-                        tcx.ensure().clashing_extern_declarations(());
+                        tcx.ensure_ok().clashing_extern_declarations(());
                     }
                 );
             },
             {
                 sess.time("privacy_checking_modules", || {
                     tcx.hir().par_for_each_module(|module| {
-                        tcx.ensure().check_mod_privacy(module);
+                        tcx.ensure_ok().check_mod_privacy(module);
                     });
                 });
             }
@@ -981,7 +982,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
 
         // This check has to be run after all lints are done processing. We don't
         // define a lint filter, as all lint checks should have finished at this point.
-        sess.time("check_lint_expectations", || tcx.ensure().check_expectations(None));
+        sess.time("check_lint_expectations", || tcx.ensure_ok().check_expectations(None));
 
         // This query is only invoked normally if a diagnostic is emitted that needs any
         // diagnostic item. If the crate compiles without checking any diagnostic items,
@@ -1006,7 +1007,7 @@ fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
                     )
                 }) =>
             {
-                tcx.ensure().trigger_delayed_bug(def_id);
+                tcx.ensure_ok().trigger_delayed_bug(def_id);
             }
 
             // Bare `#[rustc_error]`.
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index c6d7b839e19..826ecc22c24 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -458,7 +458,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
         || {
             tcx.sess.time("module_lints", || {
                 // Run per-module lints
-                tcx.hir().par_for_each_module(|module| tcx.ensure().lint_mod(module));
+                tcx.hir().par_for_each_module(|module| tcx.ensure_ok().lint_mod(module));
             });
         },
     );
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 3f1e98556ef..7ffe4e4e490 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -42,6 +42,23 @@ macro_rules! pluralize {
     };
 }
 
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Take a list of items and a function to turn those items into a `String`, and output a display
+/// friendly comma separated list of those items.
+// FIXME(estebank): this needs to be changed to go through the translation machinery.
+pub fn listify<T>(list: &[T], fmt: impl Fn(&T) -> String) -> Option<String> {
+    Some(match list {
+        [only] => fmt(&only),
+        [others @ .., last] => format!(
+            "{} and {}",
+            others.iter().map(|i| fmt(i)).collect::<Vec<_>>().join(", "),
+            fmt(&last),
+        ),
+        [] => return None,
+    })
+}
+
 /// Indicates the confidence in the correctness of a suggestion.
 ///
 /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 88ea6e07d6e..62bf34ad5ad 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -118,11 +118,17 @@ struct QueryModifiers {
     /// Generate a `feed` method to set the query's value from another query.
     feedable: Option<Ident>,
 
-    /// Forward the result on ensure if the query gets recomputed, and
-    /// return `Ok(())` otherwise. Only applicable to queries returning
-    /// `Result<T, ErrorGuaranteed>`. The `T` is not returned from `ensure`
-    /// invocations.
-    ensure_forwards_result_if_red: Option<Ident>,
+    /// When this query is called via `tcx.ensure_ok()`, it returns
+    /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to
+    /// be executed, and that execution returns an error, the error result is
+    /// returned to the caller.
+    ///
+    /// If execution is skipped, a synthetic `Ok(())` is returned, on the
+    /// assumption that a query with all-green inputs must have succeeded.
+    ///
+    /// Can only be applied to queries with a return value of
+    /// `Result<_, ErrorGuaranteed>`.
+    return_result_from_ensure_ok: Option<Ident>,
 }
 
 fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
@@ -138,7 +144,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
     let mut depth_limit = None;
     let mut separate_provide_extern = None;
     let mut feedable = None;
-    let mut ensure_forwards_result_if_red = None;
+    let mut return_result_from_ensure_ok = None;
 
     while !input.is_empty() {
         let modifier: Ident = input.parse()?;
@@ -200,8 +206,8 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
             try_insert!(separate_provide_extern = modifier);
         } else if modifier == "feedable" {
             try_insert!(feedable = modifier);
-        } else if modifier == "ensure_forwards_result_if_red" {
-            try_insert!(ensure_forwards_result_if_red = modifier);
+        } else if modifier == "return_result_from_ensure_ok" {
+            try_insert!(return_result_from_ensure_ok = modifier);
         } else {
             return Err(Error::new(modifier.span(), "unknown query modifier"));
         }
@@ -222,7 +228,7 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
         depth_limit,
         separate_provide_extern,
         feedable,
-        ensure_forwards_result_if_red,
+        return_result_from_ensure_ok,
     })
 }
 
@@ -354,7 +360,7 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
             eval_always,
             depth_limit,
             separate_provide_extern,
-            ensure_forwards_result_if_red,
+            return_result_from_ensure_ok,
         );
 
         if modifiers.cache.is_some() {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index da07ad8f6c0..5fcb9c85035 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -165,7 +165,7 @@ macro_rules! provide_one {
             // doesn't need to do this (and can't, as it would cause a query cycle).
             use rustc_middle::dep_graph::dep_kinds;
             if dep_kinds::$name != dep_kinds::crate_hash && $tcx.dep_graph.is_fully_enabled() {
-                $tcx.ensure().crate_hash($def_id.krate);
+                $tcx.ensure_ok().crate_hash($def_id.krate);
             }
 
             let cdata = rustc_data_structures::sync::FreezeReadGuard::map(CStore::from_tcx($tcx), |c| {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 43372154b2c..6e562e457d2 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2191,13 +2191,13 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
         let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id);
 
         if encode_const {
-            tcx.ensure_with_value().mir_for_ctfe(def_id);
+            tcx.ensure_done().mir_for_ctfe(def_id);
         }
         if encode_opt {
-            tcx.ensure_with_value().optimized_mir(def_id);
+            tcx.ensure_done().optimized_mir(def_id);
         }
         if encode_opt || encode_const {
-            tcx.ensure_with_value().promoted_mir(def_id);
+            tcx.ensure_done().promoted_mir(def_id);
         }
     })
 }
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 4c47d9636d3..78749428c6d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -9,7 +9,7 @@ use super::{
     ReportedErrorInfo,
 };
 use crate::mir;
-use crate::query::TyCtxtEnsure;
+use crate::query::TyCtxtEnsureOk;
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, GenericArgs, TyCtxt};
 
@@ -198,7 +198,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxtEnsure<'tcx> {
+impl<'tcx> TyCtxtEnsureOk<'tcx> {
     /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
     /// that can't take any generic arguments like const items or enum discriminants. If a
     /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a318bacb866..09d7e60e199 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1248,6 +1248,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
             ShallowInitBox(ref place, ref ty) => {
                 with_no_trimmed_paths!(write!(fmt, "ShallowInitBox({place:?}, {ty})"))
             }
+
+            WrapUnsafeBinder(ref op, ty) => {
+                with_no_trimmed_paths!(write!(fmt, "wrap_binder!({op:?}; {ty})"))
+            }
         }
     }
 }
@@ -1308,6 +1312,9 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::Index(_)
             | ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subslice { .. } => {}
+            ProjectionElem::UnwrapUnsafeBinder(_) => {
+                write!(fmt, "unwrap_binder!(")?;
+            }
         }
     }
 
@@ -1356,6 +1363,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::Subslice { from, to, from_end: false } => {
                 write!(fmt, "[{from:?}..{to:?}]")?;
             }
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                write!(fmt, "; {ty})")?;
+            }
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 609d5647d04..d345c99f902 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -62,7 +62,8 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
-            | Self::Downcast(_, _) => false,
+            | Self::Downcast(_, _)
+            | Self::UnwrapUnsafeBinder(..) => false,
         }
     }
 
@@ -76,7 +77,8 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
-            | Self::Downcast(_, _) => true,
+            | Self::Downcast(_, _)
+            | Self::UnwrapUnsafeBinder(..) => true,
         }
     }
 
@@ -102,6 +104,9 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Subtype(_)
             | Self::OpaqueCast(_)
             | Self::Subslice { .. } => false,
+
+            // FIXME(unsafe_binders): Figure this out.
+            Self::UnwrapUnsafeBinder(..) => false,
         }
     }
 }
@@ -443,7 +448,8 @@ impl<'tcx> Rvalue<'tcx> {
             | Rvalue::UnaryOp(_, _)
             | Rvalue::Discriminant(_)
             | Rvalue::Aggregate(_, _)
-            | Rvalue::ShallowInitBox(_, _) => true,
+            | Rvalue::ShallowInitBox(_, _)
+            | Rvalue::WrapUnsafeBinder(_, _) => true,
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 90a2f175bc9..2da25f480c6 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1276,6 +1276,10 @@ pub enum ProjectionElem<V, T> {
     /// requiring an intermediate variable.
     OpaqueCast(T),
 
+    /// A transmute from an unsafe binder to the type that it wraps. This is a projection
+    /// of a place, so it doesn't necessarily constitute a move out of the binder.
+    UnwrapUnsafeBinder(T),
+
     /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
     /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
     /// explicit during optimizations and codegen.
@@ -1493,6 +1497,9 @@ pub enum Rvalue<'tcx> {
     /// optimizations and codegen backends that previously had to handle deref operations anywhere
     /// in a place.
     CopyForDeref(Place<'tcx>),
+
+    /// Wraps a value in an unsafe binder.
+    WrapUnsafeBinder(Operand<'tcx>, Ty<'tcx>),
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 4d11492e94d..49449426fa4 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -146,6 +146,11 @@ impl<'tcx> PlaceTy<'tcx> {
             ProjectionElem::Subtype(ty) => {
                 PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
             }
+
+            // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general.
+            ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
         };
         debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
         answer
@@ -241,6 +246,7 @@ impl<'tcx> Rvalue<'tcx> {
             },
             Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
             Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
+            Rvalue::WrapUnsafeBinder(_, ty) => ty,
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index b59b9e55fe8..9893dd0484c 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -1,6 +1,7 @@
 //! `TypeFoldable` implementations for MIR types
 
 use rustc_ast::InlineAsmTemplatePiece;
+use rustc_hir::UnsafeBinderCastKind;
 use rustc_hir::def_id::LocalDefId;
 
 use super::*;
@@ -21,6 +22,7 @@ TrivialTypeTraversalImpls! {
     SwitchTargets,
     CoroutineKind,
     CoroutineSavedLocal,
+    UnsafeBinderCastKind,
 }
 
 TrivialTypeTraversalImpls! {
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 6319a7e65b9..8d04bbb95bd 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -781,6 +781,11 @@ macro_rules! make_mir_visitor {
                         self.visit_operand(operand, location);
                         self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
                     }
+
+                    Rvalue::WrapUnsafeBinder(op, ty) => {
+                        self.visit_operand(op, location);
+                        self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
+                    }
                 }
             }
 
@@ -1151,6 +1156,11 @@ macro_rules! visit_place_fns {
                     self.visit_ty(&mut new_ty, TyContext::Location(location));
                     if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None }
                 }
+                PlaceElem::UnwrapUnsafeBinder(ty) => {
+                    let mut new_ty = ty;
+                    self.visit_ty(&mut new_ty, TyContext::Location(location));
+                    if ty != new_ty { Some(PlaceElem::UnwrapUnsafeBinder(new_ty)) } else { None }
+                }
                 PlaceElem::Deref
                 | PlaceElem::ConstantIndex { .. }
                 | PlaceElem::Subslice { .. }
@@ -1219,7 +1229,8 @@ macro_rules! visit_place_fns {
             match elem {
                 ProjectionElem::OpaqueCast(ty)
                 | ProjectionElem::Subtype(ty)
-                | ProjectionElem::Field(_, ty) => {
+                | ProjectionElem::Field(_, ty)
+                | ProjectionElem::UnwrapUnsafeBinder(ty) => {
                     self.visit_ty(ty, TyContext::Location(location));
                 }
                 ProjectionElem::Index(local) => {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 41e9858030c..6c442fc1047 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -91,7 +91,7 @@ pub use keys::{AsLocalKey, Key, LocalCrate};
 pub mod on_disk_cache;
 #[macro_use]
 pub mod plumbing;
-pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue};
+pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk};
 
 // Each of these queries corresponds to a function pointer field in the
 // `Providers` struct for requesting a value of that type, and a method
@@ -1087,7 +1087,7 @@ rustc_queries! {
 
     query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Caches `CoerceUnsized` kinds for impls on custom types.
@@ -1095,7 +1095,7 @@ rustc_queries! {
         desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
@@ -1110,7 +1110,7 @@ rustc_queries! {
 
     query coherent_trait(def_id: DefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "coherence checking all impls of trait `{}`", tcx.def_path_str(def_id) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Borrow-checks the function body. If this is a closure, returns
@@ -1140,7 +1140,7 @@ rustc_queries! {
     /// </div>
     query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> {
         desc { "check for inherent impls that should not be defined in crate" }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Checks all types in the crate for overlap in their inherent impls. Reports errors.
@@ -1152,7 +1152,7 @@ rustc_queries! {
     /// </div>
     query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> {
         desc { "check for overlap between inherent impls defined in this crate" }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Checks whether all impls in the crate pass the overlap check, returning
@@ -1162,7 +1162,7 @@ rustc_queries! {
             "checking whether impl `{}` follows the orphan rules",
             tcx.def_path_str(key),
         }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     /// Check whether the function has any recursion that could cause the inliner to trigger
@@ -1479,7 +1479,7 @@ rustc_queries! {
     query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
         desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
         cache_on_disk_if { true }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
     query dyn_compatibility_violations(trait_id: DefId) -> &'tcx [DynCompatibilityViolation] {
         desc { |tcx| "determining dyn-compatibility of trait `{}`", tcx.def_path_str(trait_id) }
@@ -1715,12 +1715,12 @@ rustc_queries! {
 
     query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query enforce_impl_non_lifetime_params_are_constrained(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that `{}`'s generics are constrained by the impl header", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     // The `DefId`s of all non-generic functions and statics in the given crate
@@ -2442,7 +2442,7 @@ rustc_queries! {
     /// Any other def id will ICE.
     query compare_impl_item(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking assoc item `{}` is compatible with trait definition", tcx.def_path_str(key) }
-        ensure_forwards_result_if_red
+        return_result_from_ensure_ok
     }
 
     query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] {
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 1c157f33a81..6c019b427db 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -88,30 +88,68 @@ impl<'tcx> Deref for TyCtxtAt<'tcx> {
 }
 
 #[derive(Copy, Clone)]
-pub struct TyCtxtEnsure<'tcx> {
+#[must_use]
+pub struct TyCtxtEnsureOk<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 }
 
 #[derive(Copy, Clone)]
-pub struct TyCtxtEnsureWithValue<'tcx> {
+#[must_use]
+pub struct TyCtxtEnsureDone<'tcx> {
     pub tcx: TyCtxt<'tcx>,
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
-    /// are executed instead of just returning their results.
+    /// Wrapper that calls queries in a special "ensure OK" mode, for callers
+    /// that don't need the return value and just want to invoke a query for
+    /// its potential side-effect of emitting fatal errors.
+    ///
+    /// This can be more efficient than a normal query call, because if the
+    /// query's inputs are all green, the call can return immediately without
+    /// needing to obtain a value (by decoding one from disk or by executing
+    /// the query).
+    ///
+    /// (As with all query calls, execution is also skipped if the query result
+    /// is already cached in memory.)
+    ///
+    /// ## WARNING
+    /// A subsequent normal call to the same query might still cause it to be
+    /// executed! This can occur when the inputs are all green, but the query's
+    /// result is not cached on disk, so the query must be executed to obtain a
+    /// return value.
+    ///
+    /// Therefore, this call mode is not appropriate for callers that want to
+    /// ensure that the query is _never_ executed in the future.
+    ///
+    /// ## `return_result_from_ensure_ok`
+    /// If a query has the `return_result_from_ensure_ok` modifier, calls via
+    /// `ensure_ok` will instead return `Result<(), ErrorGuaranteed>`. If the
+    /// query needs to be executed, and execution returns an error, that error
+    /// is returned to the caller.
     #[inline(always)]
-    pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
-        TyCtxtEnsure { tcx: self }
+    pub fn ensure_ok(self) -> TyCtxtEnsureOk<'tcx> {
+        TyCtxtEnsureOk { tcx: self }
     }
 
-    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
-    /// are executed instead of just returning their results.
+    /// Wrapper that calls queries in a special "ensure done" mode, for callers
+    /// that don't need the return value and just want to guarantee that the
+    /// query won't be executed in the future, by executing it now if necessary.
     ///
-    /// This version verifies that the computed result exists in the cache before returning.
+    /// This is useful for queries that read from a [`Steal`] value, to ensure
+    /// that they are executed before the query that will steal the value.
+    ///
+    /// Unlike [`Self::ensure_ok`], a query with all-green inputs will only be
+    /// skipped if its return value is stored in the disk-cache. This is still
+    /// more efficient than a regular query, because in that situation the
+    /// return value doesn't necessarily need to be decoded.
+    ///
+    /// (As with all query calls, execution is also skipped if the query result
+    /// is already cached in memory.)
+    ///
+    /// [`Steal`]: rustc_data_structures::steal::Steal
     #[inline(always)]
-    pub fn ensure_with_value(self) -> TyCtxtEnsureWithValue<'tcx> {
-        TyCtxtEnsureWithValue { tcx: self }
+    pub fn ensure_done(self) -> TyCtxtEnsureDone<'tcx> {
+        TyCtxtEnsureDone { tcx: self }
     }
 
     /// Returns a transparent wrapper for `TyCtxt` which uses
@@ -193,7 +231,7 @@ macro_rules! query_ensure {
     ([]$($args:tt)*) => {
         query_ensure($($args)*)
     };
-    ([(ensure_forwards_result_if_red) $($rest:tt)*]$($args:tt)*) => {
+    ([(return_result_from_ensure_ok) $($rest:tt)*]$($args:tt)*) => {
         query_ensure_error_guaranteed($($args)*).map(|_| ())
     };
     ([$other:tt $($modifiers:tt)*]$($args:tt)*) => {
@@ -248,15 +286,15 @@ macro_rules! separate_provide_extern_decl {
     };
 }
 
-macro_rules! ensure_result {
-    ([][$ty:ty]) => {
+macro_rules! ensure_ok_result {
+    ( [] ) => {
         ()
     };
-    ([(ensure_forwards_result_if_red) $($rest:tt)*][$ty:ty]) => {
+    ( [(return_result_from_ensure_ok) $($rest:tt)*] ) => {
         Result<(), ErrorGuaranteed>
     };
-    ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
-        ensure_result!([$($modifiers)*][$($args)*])
+    ( [$other:tt $($modifiers:tt)*] ) => {
+        ensure_ok_result!( [$($modifiers)*] )
     };
 }
 
@@ -383,10 +421,13 @@ macro_rules! define_callbacks {
             $($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)*
         }
 
-        impl<'tcx> TyCtxtEnsure<'tcx> {
+        impl<'tcx> TyCtxtEnsureOk<'tcx> {
             $($(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> ensure_result!([$($modifiers)*][$V]) {
+            pub fn $name(
+                self,
+                key: query_helper_param_ty!($($K)*),
+            ) -> ensure_ok_result!([$($modifiers)*]) {
                 query_ensure!(
                     [$($modifiers)*]
                     self.tcx,
@@ -398,7 +439,7 @@ macro_rules! define_callbacks {
             })*
         }
 
-        impl<'tcx> TyCtxtEnsureWithValue<'tcx> {
+        impl<'tcx> TyCtxtEnsureDone<'tcx> {
             $($(#[$attr])*
             #[inline(always)]
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 86014c34b45..d56046136c7 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -489,6 +489,19 @@ pub enum ExprKind<'tcx> {
         user_ty: UserTy<'tcx>,
         user_ty_span: Span,
     },
+    /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.
+    PlaceUnwrapUnsafeBinder {
+        source: ExprId,
+    },
+    /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`,
+    /// which makes a temporary.
+    ValueUnwrapUnsafeBinder {
+        source: ExprId,
+    },
+    /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`.
+    WrapUnsafeBinder {
+        source: ExprId,
+    },
     /// A closure definition.
     Closure(Box<ClosureExpr<'tcx>>),
     /// A literal.
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 64bac12b266..2aeb13942a3 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -136,6 +136,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
         | ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => {
             visitor.visit_expr(&visitor.thir()[source])
         }
+        PlaceUnwrapUnsafeBinder { source }
+        | ValueUnwrapUnsafeBinder { source }
+        | WrapUnsafeBinder { source } => visitor.visit_expr(&visitor.thir()[source]),
         Closure(box ClosureExpr {
             closure_id: _,
             args: _,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 69f6fc0ad8a..522a553d243 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1957,7 +1957,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap {
         // Create a dependency to the crate to be sure we re-execute this when the amount of
         // definitions change.
-        self.ensure().hir_crate(());
+        self.ensure_ok().hir_crate(());
         // Freeze definitions once we start iterating on them, to prevent adding new ones
         // while iterating. If some query needs to add definitions, it should be `ensure`d above.
         self.untracked.definitions.freeze().def_path_hash_to_def_index_map()
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index b4b66a8133a..cb218a27e62 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -5,7 +5,7 @@ use std::ops::ControlFlow;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{
-    Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, pluralize,
+    Applicability, Diag, DiagArgValue, IntoDiagArg, into_diag_arg_using_display, listify, pluralize,
 };
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -362,11 +362,8 @@ pub fn suggest_constraining_type_params<'a>(
             let n = trait_names.len();
             let stable = if all_stable { "" } else { "unstable " };
             let trait_ = if all_known { format!("trait{}", pluralize!(n)) } else { String::new() };
-            format!("{stable}{trait_}{}", match &trait_names[..] {
-                [t] => format!(" {t}"),
-                [ts @ .., last] => format!(" {} and {last}", ts.join(", ")),
-                [] => return false,
-            },)
+            let Some(trait_names) = listify(&trait_names, |n| n.to_string()) else { return false };
+            format!("{stable}{trait_} {trait_names}")
         } else {
             // We're more explicit when there's a mix of stable and unstable traits.
             let mut trait_names = constraints
@@ -378,10 +375,9 @@ pub fn suggest_constraining_type_params<'a>(
                 .collect::<Vec<_>>();
             trait_names.sort();
             trait_names.dedup();
-            match &trait_names[..] {
-                [t] => t.to_string(),
-                [ts @ .., last] => format!("{} and {last}", ts.join(", ")),
-                [] => return false,
+            match listify(&trait_names, |t| t.to_string()) {
+                Some(names) => names,
+                None => return false,
             }
         };
         let constraint = constraint.join(" + ");
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 35fbaa99569..8c1991ddb36 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -10,8 +10,8 @@ use rustc_hir::def::{CtorOf, DefKind};
 use rustc_macros::extension;
 pub use rustc_type_ir::error::ExpectedFound;
 
-use crate::ty::print::{FmtPrinter, PrettyPrinter, with_forced_trimmed_paths};
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::print::{FmtPrinter, Print, with_forced_trimmed_paths};
+use crate::ty::{self, Lift, Ty, TyCtxt};
 
 pub type TypeError<'tcx> = rustc_type_ir::error::TypeError<TyCtxt<'tcx>>;
 
@@ -159,8 +159,8 @@ impl<'tcx> Ty<'tcx> {
             ty::Error(_) => "type error".into(),
             _ => {
                 let width = tcx.sess.diagnostic_width();
-                let length_limit = std::cmp::max(width / 4, 15);
-                format!("`{}`", tcx.ty_string_with_limit(self, length_limit)).into()
+                let length_limit = std::cmp::max(width / 4, 40);
+                format!("`{}`", tcx.string_with_limit(self, length_limit)).into()
             }
         }
     }
@@ -213,10 +213,14 @@ impl<'tcx> Ty<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    pub fn ty_string_with_limit(self, ty: Ty<'tcx>, length_limit: usize) -> String {
+    pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String
+    where
+        T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy,
+        <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>,
+    {
         let mut type_limit = 50;
         let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            cx.pretty_print_type(ty)
+            self.lift(p).expect("could not lift for printing").print(cx)
         })
         .expect("could not write to `String`");
         if regular.len() <= length_limit {
@@ -231,7 +235,10 @@ impl<'tcx> TyCtxt<'tcx> {
                     hir::def::Namespace::TypeNS,
                     rustc_session::Limit(type_limit),
                 );
-                cx.pretty_print_type(ty).expect("could not write to `String`");
+                self.lift(p)
+                    .expect("could not lift for printing")
+                    .print(&mut cx)
+                    .expect("could not print type");
                 cx.into_buffer()
             });
             if short.len() <= length_limit || type_limit == 0 {
@@ -242,9 +249,17 @@ impl<'tcx> TyCtxt<'tcx> {
         short
     }
 
-    pub fn short_ty_string(self, ty: Ty<'tcx>, path: &mut Option<PathBuf>) -> String {
+    /// When calling this after a `Diag` is constructed, the preferred way of doing so is
+    /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps
+    /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user
+    /// where we wrote the file to is only printed once.
+    pub fn short_string<'a, T>(self, p: T, path: &mut Option<PathBuf>) -> String
+    where
+        T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy + Hash,
+        <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>,
+    {
         let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| {
-            cx.pretty_print_type(ty)
+            self.lift(p).expect("could not lift for printing").print(cx)
         })
         .expect("could not write to `String`");
 
@@ -257,13 +272,13 @@ impl<'tcx> TyCtxt<'tcx> {
         if regular.len() <= width * 2 / 3 {
             return regular;
         }
-        let short = self.ty_string_with_limit(ty, length_limit);
+        let short = self.string_with_limit(p, length_limit);
         if regular == short {
             return regular;
         }
         // Ensure we create an unique file for the type passed in when we create a file.
         let mut s = DefaultHasher::new();
-        ty.hash(&mut s);
+        p.hash(&mut s);
         let hash = s.finish();
         *path = Some(path.take().unwrap_or_else(|| {
             self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None)
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 72f353f06ff..dc2040aa5cf 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -105,6 +105,10 @@ pub trait Printer<'tcx>: Sized {
         args: &[GenericArg<'tcx>],
     ) -> Result<(), PrintError>;
 
+    fn should_truncate(&mut self) -> bool {
+        false
+    }
+
     // Defaults (should not be overridden):
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 018fcc66aee..6c8591dae89 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -865,7 +865,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 p!(write("{{"));
                 if !self.tcx().sess.verbose_internals() {
                     p!("coroutine witness");
-                    // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         let span = self.tcx().def_span(did);
                         p!(write(
@@ -887,26 +886,30 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 p!(write("{{"));
                 if !self.should_print_verbose() {
                     p!(write("closure"));
-                    // FIXME(eddyb) should use `def_span`.
-                    if let Some(did) = did.as_local() {
-                        if self.tcx().sess.opts.unstable_opts.span_free_formats {
-                            p!("@", print_def_path(did.to_def_id(), args));
-                        } else {
-                            let span = self.tcx().def_span(did);
-                            let preference = if with_forced_trimmed_paths() {
-                                FileNameDisplayPreference::Short
+                    if self.should_truncate() {
+                        write!(self, "@...}}")?;
+                        return Ok(());
+                    } else {
+                        if let Some(did) = did.as_local() {
+                            if self.tcx().sess.opts.unstable_opts.span_free_formats {
+                                p!("@", print_def_path(did.to_def_id(), args));
                             } else {
-                                FileNameDisplayPreference::Remapped
-                            };
-                            p!(write(
-                                "@{}",
-                                // This may end up in stderr diagnostics but it may also be emitted
-                                // into MIR. Hence we use the remapped path if available
-                                self.tcx().sess.source_map().span_to_string(span, preference)
-                            ));
+                                let span = self.tcx().def_span(did);
+                                let preference = if with_forced_trimmed_paths() {
+                                    FileNameDisplayPreference::Short
+                                } else {
+                                    FileNameDisplayPreference::Remapped
+                                };
+                                p!(write(
+                                    "@{}",
+                                    // This may end up in stderr diagnostics but it may also be emitted
+                                    // into MIR. Hence we use the remapped path if available
+                                    self.tcx().sess.source_map().span_to_string(span, preference)
+                                ));
+                            }
+                        } else {
+                            p!(write("@"), print_def_path(did, args));
                         }
-                    } else {
-                        p!(write("@"), print_def_path(did, args));
                     }
                 } else {
                     p!(print_def_path(did, args));
@@ -942,7 +945,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                             "coroutine from coroutine-closure should have CoroutineSource::Closure"
                         ),
                     }
-                    // FIXME(eddyb) should use `def_span`.
                     if let Some(did) = did.as_local() {
                         if self.tcx().sess.opts.unstable_opts.span_free_formats {
                             p!("@", print_def_path(did.to_def_id(), args));
@@ -1994,7 +1996,6 @@ pub struct FmtPrinterData<'a, 'tcx> {
     binder_depth: usize,
     printed_type_count: usize,
     type_length_limit: Limit,
-    truncated: bool,
 
     pub region_highlight_mode: RegionHighlightMode<'tcx>,
 
@@ -2046,7 +2047,6 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
             binder_depth: 0,
             printed_type_count: 0,
             type_length_limit,
-            truncated: false,
             region_highlight_mode: RegionHighlightMode::default(),
             ty_infer_name_resolver: None,
             const_infer_name_resolver: None,
@@ -2183,16 +2183,49 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
-        if self.type_length_limit.value_within_limit(self.printed_type_count) {
-            self.printed_type_count += 1;
-            self.pretty_print_type(ty)
-        } else {
-            self.truncated = true;
-            write!(self, "...")?;
-            Ok(())
+        match ty.kind() {
+            ty::Tuple(tys) if tys.len() == 0 && self.should_truncate() => {
+                // Don't truncate `()`.
+                self.printed_type_count += 1;
+                self.pretty_print_type(ty)
+            }
+            ty::Adt(..)
+            | ty::Foreign(_)
+            | ty::Pat(..)
+            | ty::RawPtr(..)
+            | ty::Ref(..)
+            | ty::FnDef(..)
+            | ty::FnPtr(..)
+            | ty::UnsafeBinder(..)
+            | ty::Dynamic(..)
+            | ty::Closure(..)
+            | ty::CoroutineClosure(..)
+            | ty::Coroutine(..)
+            | ty::CoroutineWitness(..)
+            | ty::Tuple(_)
+            | ty::Alias(..)
+            | ty::Param(_)
+            | ty::Bound(..)
+            | ty::Placeholder(_)
+            | ty::Error(_)
+                if self.should_truncate() =>
+            {
+                // We only truncate types that we know are likely to be much longer than 3 chars.
+                // There's no point in replacing `i32` or `!`.
+                write!(self, "...")?;
+                Ok(())
+            }
+            _ => {
+                self.printed_type_count += 1;
+                self.pretty_print_type(ty)
+            }
         }
     }
 
+    fn should_truncate(&mut self) -> bool {
+        !self.type_length_limit.value_within_limit(self.printed_type_count)
+    }
+
     fn print_dyn_existential(
         &mut self,
         predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
@@ -2942,7 +2975,7 @@ impl<'tcx> ty::TraitPredicate<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
+#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)]
 pub struct TraitPredPrintWithBoundConstness<'tcx>(
     ty::TraitPredicate<'tcx>,
     Option<ty::BoundConstness>,
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 7d5e5c2e823..318bd0c7ec0 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -367,7 +367,7 @@ impl<'tcx> TyCtxt<'tcx> {
         validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::Destructor> {
         let drop_trait = self.lang_items().drop_trait()?;
-        self.ensure().coherent_trait(drop_trait).ok()?;
+        self.ensure_ok().coherent_trait(drop_trait).ok()?;
 
         let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
@@ -404,7 +404,7 @@ impl<'tcx> TyCtxt<'tcx> {
         validate: impl Fn(Self, DefId) -> Result<(), ErrorGuaranteed>,
     ) -> Option<ty::AsyncDestructor> {
         let async_drop_trait = self.lang_items().async_drop_trait()?;
-        self.ensure().coherent_trait(async_drop_trait).ok()?;
+        self.ensure_ok().coherent_trait(async_drop_trait).ok()?;
 
         let ty = self.type_of(adt_did).instantiate_identity();
         let mut dtor_candidate = None;
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 053775b4937..3cf3c332893 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -25,8 +25,6 @@ mir_build_borrow_of_moved_value = borrow of moved value
     .occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait
     .value_borrowed_label = value borrowed here after move
     .suggestion = borrow this binding in the pattern to avoid moving the value
-    .full_type_name = the full type name has been written to '{$path}'
-    .consider_verbose = consider using `--verbose` to print the full type name to the console
 
 mir_build_call_to_deprecated_safe_fn_requires_unsafe =
     call to deprecated safe function `{$function}` is unsafe and requires unsafe block
@@ -361,6 +359,18 @@ mir_build_unreachable_pattern = unreachable pattern
     .unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings
     .suggestion = remove the match arm
 
+mir_build_unsafe_binder_cast_requires_unsafe =
+    unsafe binder cast is unsafe and requires unsafe block
+    .label = unsafe binder cast
+    .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
+        information that may be required to uphold safety guarantees of a type
+
+mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
+    unsafe binder cast is unsafe and requires unsafe block or unsafe fn
+    .label = unsafe binder cast
+    .note = casting to or from an `unsafe<...>` binder type is unsafe since it erases lifetime
+        information that may be required to uphold safety guarantees of a type
+
 mir_build_unsafe_field_requires_unsafe =
     use of unsafe field is unsafe and requires unsafe block
     .note = unsafe fields may carry library invariants
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 0086775e9f4..482f1e3840b 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -105,7 +105,8 @@ fn convert_to_hir_projections_and_truncate_for_capture(
             ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue,
             ProjectionElem::Index(..)
             | ProjectionElem::ConstantIndex { .. }
-            | ProjectionElem::Subslice { .. } => {
+            | ProjectionElem::Subslice { .. }
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {
                 // We don't capture array-access projections.
                 // We can stop here as arrays are captured completely.
                 break;
@@ -523,6 +524,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.and(PlaceBuilder::from(temp))
             }
 
+            ExprKind::PlaceUnwrapUnsafeBinder { source } => {
+                let place_builder = unpack!(
+                    block = this.expr_as_place(block, source, mutability, fake_borrow_temps,)
+                );
+                block.and(place_builder.project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
+            }
+            ExprKind::ValueUnwrapUnsafeBinder { source } => {
+                let source_expr = &this.thir[source];
+                let temp = unpack!(
+                    block = this.as_temp(block, source_expr.temp_lifetime, source, mutability)
+                );
+                block.and(PlaceBuilder::from(temp).project(PlaceElem::UnwrapUnsafeBinder(expr.ty)))
+            }
+
             ExprKind::Array { .. }
             | ExprKind::Tuple { .. }
             | ExprKind::Adt { .. }
@@ -560,7 +575,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::OffsetOf { .. }
             | ExprKind::Yield { .. }
             | ExprKind::ThreadLocalRef(_)
-            | ExprKind::Call { .. } => {
+            | ExprKind::Call { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
                 // these are not places, so we need to make a temporary.
                 debug_assert!(!matches!(Category::of(&expr.kind), Some(Category::Place)));
                 let temp =
@@ -776,7 +792,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     | ProjectionElem::OpaqueCast(..)
                     | ProjectionElem::Subtype(..)
                     | ProjectionElem::ConstantIndex { .. }
-                    | ProjectionElem::Subslice { .. } => (),
+                    | ProjectionElem::Subslice { .. }
+                    | ProjectionElem::UnwrapUnsafeBinder(_) => (),
                 }
             }
         }
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index 9961c2488ef..e7713f0a1d6 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -508,6 +508,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.and(Rvalue::Use(Operand::Constant(Box::new(constant))))
             }
 
+            ExprKind::WrapUnsafeBinder { source } => {
+                let source = unpack!(
+                    block = this.as_operand(
+                        block,
+                        scope,
+                        source,
+                        LocalInfo::Boring,
+                        NeedsTemporary::Maybe
+                    )
+                );
+                block.and(Rvalue::WrapUnsafeBinder(source, expr.ty))
+            }
+
             ExprKind::Yield { .. }
             | ExprKind::Block { .. }
             | ExprKind::Match { .. }
@@ -532,7 +545,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Become { .. }
             | ExprKind::InlineAsm { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => {
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => {
                 // these do not have corresponding `Rvalue` variants,
                 // so make an operand and then return that
                 debug_assert!(!matches!(
diff --git a/compiler/rustc_mir_build/src/builder/expr/category.rs b/compiler/rustc_mir_build/src/builder/expr/category.rs
index e0349e3e3f6..ca55d36bfc6 100644
--- a/compiler/rustc_mir_build/src/builder/expr/category.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/category.rs
@@ -41,7 +41,9 @@ impl Category {
             | ExprKind::UpvarRef { .. }
             | ExprKind::VarRef { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => Some(Category::Place),
 
             ExprKind::LogicalOp { .. }
             | ExprKind::Match { .. }
@@ -68,7 +70,8 @@ impl Category {
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
             | ExprKind::ThreadLocalRef(_)
-            | ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
+            | ExprKind::OffsetOf { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
 
             ExprKind::ConstBlock { .. }
             | ExprKind::Literal { .. }
diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs
index 928156572d5..b25cd0f4426 100644
--- a/compiler/rustc_mir_build/src/builder/expr/into.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/into.rs
@@ -554,7 +554,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::VarRef { .. }
             | ExprKind::UpvarRef { .. }
             | ExprKind::PlaceTypeAscription { .. }
-            | ExprKind::ValueTypeAscription { .. } => {
+            | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. } => {
                 debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
 
                 let place = unpack!(block = this.as_place(block, expr_id));
@@ -613,7 +615,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::ConstParam { .. }
             | ExprKind::ThreadLocalRef(_)
             | ExprKind::StaticRef { .. }
-            | ExprKind::OffsetOf { .. } => {
+            | ExprKind::OffsetOf { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
                 debug_assert!(match Category::of(&expr.kind).unwrap() {
                     // should be handled above
                     Category::Rvalue(RvalueFunc::Into) => false,
diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs
index 93fb9873e80..e04c70b5883 100644
--- a/compiler/rustc_mir_build/src/builder/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/mod.rs
@@ -47,7 +47,7 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 /// Create the MIR for a given `DefId`, including unreachable code. Do not call
 /// this directly; instead use the cached version via `mir_built`.
 pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
-    tcx.ensure_with_value().thir_abstract_const(def);
+    tcx.ensure_done().thir_abstract_const(def);
     if let Err(e) = tcx.check_match(def) {
         return construct_error(tcx, def, e);
     }
@@ -68,7 +68,7 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
             // "not all control paths return a value" is reported here.
             //
             // maybe move the check to a MIR pass?
-            tcx.ensure().check_liveness(def);
+            tcx.ensure_ok().check_liveness(def);
 
             // Don't steal here, instead steal in unsafeck. This is so that
             // pattern inline constants can be evaluated as part of building the
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 995bc311b7c..e47c14b8bfa 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -200,7 +200,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
     fn visit_inner_body(&mut self, def: LocalDefId) {
         if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
             // Runs all other queries that depend on THIR.
-            self.tcx.ensure_with_value().mir_built(def);
+            self.tcx.ensure_done().mir_built(def);
             let inner_thir = &inner_thir.steal();
             let hir_context = self.tcx.local_def_id_to_hir_id(def);
             let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
@@ -439,6 +439,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             | ExprKind::NeverToAny { .. }
             | ExprKind::PlaceTypeAscription { .. }
             | ExprKind::ValueTypeAscription { .. }
+            | ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | ExprKind::WrapUnsafeBinder { .. }
             | ExprKind::PointerCoercion { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::StaticRef { .. }
@@ -680,6 +683,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     }
                 }
             }
+            ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | ExprKind::WrapUnsafeBinder { .. } => {
+                self.requires_unsafe(expr.span, UnsafeBinderCast);
+            }
             _ => {}
         }
         visit::walk_expr(self, expr);
@@ -728,6 +736,7 @@ enum UnsafeOpKind {
         /// (e.g., with `-C target-feature`).
         build_enabled: Vec<Symbol>,
     },
+    UnsafeBinderCast,
 }
 
 use UnsafeOpKind::*;
@@ -891,6 +900,15 @@ impl UnsafeOpKind {
                     unsafe_not_inherited_note,
                 },
             ),
+            UnsafeBinderCast => tcx.emit_node_span_lint(
+                UNSAFE_OP_IN_UNSAFE_FN,
+                hir_id,
+                span,
+                UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
+                    span,
+                    unsafe_not_inherited_note,
+                },
+            ),
         }
     }
 
@@ -1099,6 +1117,15 @@ impl UnsafeOpKind {
                     function: tcx.def_path_str(*function),
                 });
             }
+            UnsafeBinderCast if unsafe_op_in_unsafe_fn_allowed => {
+                dcx.emit_err(UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+                    span,
+                    unsafe_not_inherited_note,
+                });
+            }
+            UnsafeBinderCast => {
+                dcx.emit_err(UnsafeBinderCastRequiresUnsafe { span, unsafe_not_inherited_note });
+            }
         }
     }
 }
@@ -1112,7 +1139,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
 
     let Ok((thir, expr)) = tcx.thir_body(def) else { return };
     // Runs all other queries that depend on THIR.
-    tcx.ensure_with_value().mir_built(def);
+    tcx.ensure_done().mir_built(def);
     let thir = &thir.steal();
 
     let hir_id = tcx.local_def_id_to_hir_id(def);
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 1f87bf0dbbb..af6f33d9cdd 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -161,6 +161,18 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe
 }
 
 #[derive(LintDiagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe,
+    code = E0133,
+)]
+pub(crate) struct UnsafeOpInUnsafeFnUnsafeBinderCastRequiresUnsafe {
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)]
 #[help]
 pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
@@ -494,6 +506,32 @@ pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
 }
 
+#[derive(Diagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe,
+    code = E0133,
+)]
+pub(crate) struct UnsafeBinderCastRequiresUnsafe {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Diagnostic)]
+#[diag(
+    mir_build_unsafe_binder_cast_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
+    code = E0133,
+)]
+pub(crate) struct UnsafeBinderCastRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    #[subdiagnostic]
+    pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
 #[derive(Subdiagnostic)]
 #[label(mir_build_unsafe_not_inherited)]
 pub(crate) struct UnsafeNotInheritedNote {
@@ -801,10 +839,6 @@ pub(crate) struct BorrowOfMovedValue {
     pub(crate) ty: String,
     #[suggestion(code = "ref ", applicability = "machine-applicable")]
     pub(crate) suggest_borrowing: Option<Span>,
-    #[note(mir_build_full_type_name)]
-    #[note(mir_build_consider_verbose)]
-    pub(crate) has_path: bool,
-    pub(crate) path: String,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 9cdf08d749b..795ac6b4bea 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -1,5 +1,6 @@
 use itertools::Itertools;
 use rustc_abi::{FIRST_VARIANT, FieldIdx};
+use rustc_ast::UnsafeBinderCastKind;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -910,8 +911,19 @@ impl<'tcx> Cx<'tcx> {
                 }
             }
 
-            hir::ExprKind::UnsafeBinderCast(_kind, _source, _ty) => {
-                unreachable!("unsafe binders are not yet implemented")
+            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, source, _ty) => {
+                // FIXME(unsafe_binders): Take into account the ascribed type, too.
+                let mirrored = self.mirror_expr(source);
+                if source.is_syntactic_place_expr() {
+                    ExprKind::PlaceUnwrapUnsafeBinder { source: mirrored }
+                } else {
+                    ExprKind::ValueUnwrapUnsafeBinder { source: mirrored }
+                }
+            }
+            hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, source, _ty) => {
+                // FIXME(unsafe_binders): Take into account the ascribed type, too.
+                let mirrored = self.mirror_expr(source);
+                ExprKind::WrapUnsafeBinder { source: mirrored }
             }
 
             hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) },
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index e0a1117f905..8247a6c6a32 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -326,9 +326,10 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
             | Use { source }
             | PointerCoercion { source, .. }
             | PlaceTypeAscription { source, .. }
-            | ValueTypeAscription { source, .. } => {
-                self.is_known_valid_scrutinee(&self.thir()[*source])
-            }
+            | ValueTypeAscription { source, .. }
+            | PlaceUnwrapUnsafeBinder { source }
+            | ValueUnwrapUnsafeBinder { source }
+            | WrapUnsafeBinder { source } => self.is_known_valid_scrutinee(&self.thir()[*source]),
 
             // These diverge.
             Become { .. } | Break { .. } | Continue { .. } | Return { .. } => true,
@@ -796,16 +797,16 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
             });
             if !conflicts_ref.is_empty() {
                 let mut path = None;
-                let ty = cx.tcx.short_ty_string(ty, &mut path);
-                sess.dcx().emit_err(BorrowOfMovedValue {
+                let ty = cx.tcx.short_string(ty, &mut path);
+                let mut err = sess.dcx().create_err(BorrowOfMovedValue {
                     binding_span: pat.span,
                     conflicts_ref,
                     name: Ident::new(name, pat.span),
                     ty,
                     suggest_borrowing: Some(pat.span.shrink_to_lo()),
-                    has_path: path.is_some(),
-                    path: path.map(|p| p.display().to_string()).unwrap_or_default(),
                 });
+                *err.long_ty_path() = path;
+                err.emit();
             }
             return;
         }
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 228a64c2c70..729c8f784ba 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -477,6 +477,24 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 self.print_expr(*source, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl);
             }
+            PlaceUnwrapUnsafeBinder { source } => {
+                print_indented!(self, "PlaceUnwrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ValueUnwrapUnsafeBinder { source } => {
+                print_indented!(self, "ValueUnwrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            WrapUnsafeBinder { source } => {
+                print_indented!(self, "WrapUnsafeBinder {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
             Closure(closure_expr) => {
                 print_indented!(self, "Closure {", depth_lvl);
                 print_indented!(self, "closure_expr:", depth_lvl + 1);
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index df4b1a53417..9abb8343432 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -97,7 +97,8 @@ where
             | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Aggregate(..)
-            | Rvalue::CopyForDeref(..) => {}
+            | Rvalue::CopyForDeref(..)
+            | Rvalue::WrapUnsafeBinder(..) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
index d79d2c316ee..d056ad3d4b4 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
@@ -32,6 +32,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
             }
             ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
             ProjectionElem::Subtype(_ty) => ProjectionElem::Subtype(()),
+            ProjectionElem::UnwrapUnsafeBinder(_ty) => ProjectionElem::UnwrapUnsafeBinder(()),
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index d1b3a389e9e..6e00e427a46 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -208,7 +208,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
                     | ty::Infer(_)
                     | ty::Error(_)
                     | ty::Placeholder(_) => bug!(
-                        "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
+                        "When Place contains ProjectionElem::Field its type shouldn't be {place_ty:#?}"
                     ),
                 },
                 ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
@@ -226,6 +226,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
                     }
                     _ => bug!("Unexpected type {place_ty:#?}"),
                 },
+                ProjectionElem::UnwrapUnsafeBinder(_) => {}
                 // `OpaqueCast`:Only transmutes the type, so no moves there.
                 // `Downcast`  :Only changes information about a `Place` without moving.
                 // `Subtype`   :Only transmutes the type, so moves.
@@ -399,7 +400,8 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             | Rvalue::Repeat(ref operand, _)
             | Rvalue::Cast(_, ref operand, _)
             | Rvalue::ShallowInitBox(ref operand, _)
-            | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
+            | Rvalue::UnaryOp(_, ref operand)
+            | Rvalue::WrapUnsafeBinder(ref operand, _) => self.gather_operand(operand),
             Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs)) => {
                 self.gather_operand(lhs);
                 self.gather_operand(rhs);
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 8879e029346..90173da17f0 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -504,7 +504,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             | Rvalue::Cast(..)
             | Rvalue::BinaryOp(..)
             | Rvalue::Aggregate(..)
-            | Rvalue::ShallowInitBox(..) => {
+            | Rvalue::ShallowInitBox(..)
+            | Rvalue::WrapUnsafeBinder(..) => {
                 // No modification is possible through these r-values.
                 return ValueOrPlace::TOP;
             }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 41de1b58b91..7395ad496db 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -575,6 +575,9 @@ impl WriteInfo {
                             self.add_operand(op);
                         }
                     }
+                    Rvalue::WrapUnsafeBinder(op, _) => {
+                        self.add_operand(op);
+                    }
                     Rvalue::ThreadLocalRef(_)
                     | Rvalue::NullaryOp(_, _)
                     | Rvalue::Ref(_, _, _)
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 16e15fa12e0..c261e25100d 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -476,6 +476,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     }
                     ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
                     ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
+                    ProjectionElem::UnwrapUnsafeBinder(ty) => {
+                        ProjectionElem::UnwrapUnsafeBinder(ty)
+                    }
                     // This should have been replaced by a `ConstantIndex` earlier.
                     ProjectionElem::Index(_) => return None,
                 };
@@ -713,6 +716,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
             ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
             ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
+            ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty),
         };
 
         Some(self.insert(Value::Projection(value, proj)))
@@ -867,6 +871,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 self.simplify_place_projection(place, location);
                 return self.new_pointer(*place, AddressKind::Address(mutbl));
             }
+            Rvalue::WrapUnsafeBinder(ref mut op, _) => {
+                return self.simplify_operand(op, location);
+            }
 
             // Operations.
             Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
@@ -931,6 +938,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             ProjectionElem::Downcast(symbol, idx) => ProjectionElem::Downcast(symbol, idx),
             ProjectionElem::OpaqueCast(idx) => ProjectionElem::OpaqueCast(idx),
             ProjectionElem::Subtype(idx) => ProjectionElem::Subtype(idx),
+            ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty),
         })
     }
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 95aeccfdda6..f8b0688dfdc 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -4,7 +4,7 @@ use std::iter;
 use std::ops::{Range, RangeFrom};
 
 use rustc_abi::{ExternAbi, FieldIdx};
-use rustc_attr_parsing::InlineAttr;
+use rustc_attr_parsing::{InlineAttr, OptimizeAttr};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
@@ -770,6 +770,10 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
         return Err("never inline attribute");
     }
 
+    if let OptimizeAttr::DoNotOptimize = callee_attrs.optimize {
+        return Err("has DoNotOptimize attribute");
+    }
+
     // Reachability pass defines which functions are eligible for inlining. Generally inlining
     // other functions is incorrect because they could reference symbols that aren't exported.
     let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index f4ac5c6aa80..2864cc0b9fe 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -444,7 +444,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
-            | Rvalue::NullaryOp(..) => {}
+            | Rvalue::NullaryOp(..)
+            | Rvalue::WrapUnsafeBinder(..) => {}
         }
 
         // FIXME we need to revisit this for #67176
@@ -546,7 +547,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let val: Value<'_> = match *rvalue {
             ThreadLocalRef(_) => return None,
 
-            Use(ref operand) => self.eval_operand(operand)?.into(),
+            Use(ref operand) | WrapUnsafeBinder(ref operand, _) => {
+                self.eval_operand(operand)?.into()
+            }
 
             CopyForDeref(place) => self.eval_place(place)?.into(),
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 4af9a111bdf..b572f6ca0b3 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -421,11 +421,11 @@ fn mir_promoted(
     };
 
     // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
-    tcx.ensure_with_value().has_ffi_unwind_calls(def);
+    tcx.ensure_done().has_ffi_unwind_calls(def);
 
     // the `by_move_body` query uses the raw mir, so make sure it is run.
     if tcx.needs_coroutine_by_move_body_def_id(def.to_def_id()) {
-        tcx.ensure_with_value().coroutine_by_move_body_def_id(def);
+        tcx.ensure_done().coroutine_by_move_body_def_id(def);
     }
 
     let mut body = tcx.mir_built(def).steal();
@@ -488,7 +488,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
 /// end up missing the source MIR due to stealing happening.
 fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
     if tcx.is_coroutine(def.to_def_id()) {
-        tcx.ensure_with_value().mir_coroutine_witnesses(def);
+        tcx.ensure_done().mir_coroutine_witnesses(def);
     }
 
     // We only need to borrowck non-synthetic MIR.
@@ -501,7 +501,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
         if pm::should_run_pass(tcx, &inline::Inline, pm::Optimizations::Allowed)
             || inline::ForceInline::should_run_pass_for_callee(tcx, def.to_def_id())
         {
-            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
+            tcx.ensure_done().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
         }
     }
 
@@ -733,7 +733,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
         // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked`
         // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it
         // computes and caches its result.
-        Some(hir::ConstContext::ConstFn) => tcx.ensure_with_value().mir_for_ctfe(did),
+        Some(hir::ConstContext::ConstFn) => tcx.ensure_done().mir_for_ctfe(did),
         None => {}
         Some(other) => panic!("do not use `optimized_mir` for constants: {other:?}"),
     }
@@ -772,7 +772,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
     }
 
     if !tcx.is_synthetic_mir(def) {
-        tcx.ensure_with_value().mir_borrowck(def);
+        tcx.ensure_done().mir_borrowck(def);
     }
     let mut promoted = tcx.mir_promoted(def).1.steal();
 
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 6aa3343bb6e..9101c9bfc9a 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -293,7 +293,8 @@ impl<'tcx> Validator<'_, 'tcx> {
             // Recurse directly.
             ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Subslice { .. } => {}
+            | ProjectionElem::Subslice { .. }
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {}
 
             // Never recurse.
             ProjectionElem::OpaqueCast(..) | ProjectionElem::Downcast(..) => {
@@ -426,7 +427,9 @@ impl<'tcx> Validator<'_, 'tcx> {
 
     fn validate_rvalue(&mut self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
         match rvalue {
-            Rvalue::Use(operand) | Rvalue::Repeat(operand, _) => {
+            Rvalue::Use(operand)
+            | Rvalue::Repeat(operand, _)
+            | Rvalue::WrapUnsafeBinder(operand, _) => {
                 self.validate_operand(operand)?;
             }
             Rvalue::CopyForDeref(place) => {
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 5881264cba5..e282eaf761c 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -807,6 +807,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     )
                 }
             }
+            ProjectionElem::UnwrapUnsafeBinder(unwrapped_ty) => {
+                let binder_ty = place_ref.ty(&self.body.local_decls, self.tcx);
+                let ty::UnsafeBinder(binder_ty) = *binder_ty.ty.kind() else {
+                    self.fail(
+                        location,
+                        format!("WrapUnsafeBinder does not produce a ty::UnsafeBinder"),
+                    );
+                    return;
+                };
+                let binder_inner_ty = self.tcx.instantiate_bound_regions_with_erased(*binder_ty);
+                if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
+                    self.fail(
+                        location,
+                        format!(
+                            "Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty:?}"
+                        ),
+                    );
+                }
+            }
             _ => {}
         }
         self.super_projection_elem(place_ref, elem, context, location);
@@ -1362,6 +1381,24 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             | Rvalue::RawPtr(_, _)
             | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks, _)
             | Rvalue::Discriminant(_) => {}
+
+            Rvalue::WrapUnsafeBinder(op, ty) => {
+                let unwrapped_ty = op.ty(self.body, self.tcx);
+                let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
+                    self.fail(
+                        location,
+                        format!("WrapUnsafeBinder does not produce a ty::UnsafeBinder"),
+                    );
+                    return;
+                };
+                let binder_inner_ty = self.tcx.instantiate_bound_regions_with_erased(*binder_ty);
+                if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
+                    self.fail(
+                        location,
+                        format!("Cannot wrap {unwrapped_ty:?} into unsafe binder {binder_ty:?}"),
+                    );
+                }
+            }
         }
         self.super_rvalue(rvalue, location);
     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 246faed50e3..de8a20c5dee 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1222,7 +1222,7 @@ fn collect_items_of_instance<'tcx>(
     mode: CollectionMode,
 ) -> (MonoItems<'tcx>, MonoItems<'tcx>) {
     // This item is getting monomorphized, do mono-time checks.
-    tcx.ensure().check_mono_item(instance);
+    tcx.ensure_ok().check_mono_item(instance);
 
     let body = tcx.instance_mir(instance.def);
     // Naively, in "used" collection mode, all functions get added to *both* `used_items` and
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index d19df08519d..3842b7035e5 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -24,7 +24,7 @@ use rustc_ast::MacroDef;
 use rustc_ast::visit::{VisitorResult, try_visit};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::MultiSpan;
+use rustc_errors::{MultiSpan, listify};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, InferKind, Visitor};
@@ -958,29 +958,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
         //    |         ^^ field `gamma` is private  # `fields.2` is `false`
 
         // Get the list of all private fields for the main message.
-        let field_names: Vec<_> = fields.iter().map(|(name, _, _)| name).collect();
-        let field_names = match &field_names[..] {
-            [] => return,
-            [name] => format!("`{name}`"),
-            [fields @ .., last] => format!(
-                "{} and `{last}`",
-                fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
-            ),
-        };
+        let Some(field_names) = listify(&fields[..], |(n, _, _)| format!("`{n}`")) else { return };
         let span: MultiSpan = fields.iter().map(|(_, span, _)| *span).collect::<Vec<Span>>().into();
 
         // Get the list of all private fields when pointing at the `..rest`.
         let rest_field_names: Vec<_> =
             fields.iter().filter(|(_, _, is_present)| !is_present).map(|(n, _, _)| n).collect();
         let rest_len = rest_field_names.len();
-        let rest_field_names = match &rest_field_names[..] {
-            [] => String::new(),
-            [name] => format!("`{name}`"),
-            [fields @ .., last] => format!(
-                "{} and `{last}`",
-                fields.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "),
-            ),
-        };
+        let rest_field_names =
+            listify(&rest_field_names[..], |n| format!("`{n}`")).unwrap_or_default();
         // Get all the labels for each field or `..rest` in the primary MultiSpan.
         let labels = fields
             .iter()
@@ -1005,7 +991,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
             } else {
                 None
             },
-            field_names: field_names.clone(),
+            field_names,
             variant_descr: def.variant_descr(),
             def_path_str: self.tcx.def_path_str(def.did()),
             labels,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 150ec02b7db..4a0420cc603 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -217,6 +217,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables))
             }
             CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
+            WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
         }
     }
 }
@@ -395,6 +396,7 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
             Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)),
             OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)),
             Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)),
+            UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
         }
     }
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7f7b460cf57..322da939011 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2152,7 +2152,6 @@ symbols! {
         unwrap,
         unwrap_binder,
         unwrap_or,
-        unwrap_unsafe_binder,
         use_extern_macros,
         use_nested_groups,
         used,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index db4a14356cc..ac72774027c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -435,7 +435,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
         terr: TypeError<'tcx>,
         param_env: Option<ParamEnv<'tcx>>,
-        path: &mut Option<PathBuf>,
     ) {
         match *cause.code() {
             ObligationCauseCode::Pattern {
@@ -458,7 +457,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             format!("this is an iterator with items of type `{}`", args.type_at(0)),
                         );
                     } else {
-                        let expected_ty = self.tcx.short_ty_string(expected_ty, path);
+                        let expected_ty = self.tcx.short_string(expected_ty, err.long_ty_path());
                         err.span_label(span, format!("this expression has type `{expected_ty}`"));
                     }
                 }
@@ -1545,7 +1544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         (false, Mismatch::Fixed("existential projection"))
                     }
                 };
-                let Some(vals) = self.values_str(values, cause) else {
+                let Some(vals) = self.values_str(values, cause, diag.long_ty_path()) else {
                     // Derived error. Cancel the emitter.
                     // NOTE(eddyb) this was `.cancel()`, but `diag`
                     // is borrowed, so we can't fully defuse it.
@@ -1600,9 +1599,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             return;
         }
 
-        let mut path = None;
-        if let Some((expected, found, p)) = expected_found {
-            path = p;
+        if let Some((expected, found)) = expected_found {
             let (expected_label, found_label, exp_found) = match exp_found {
                 Mismatch::Variable(ef) => (
                     ef.expected.prefix_string(self.tcx),
@@ -1878,11 +1875,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // It reads better to have the error origin as the final
         // thing.
-        self.note_error_origin(diag, cause, exp_found, terr, param_env, &mut path);
-        if let Some(path) = path {
-            diag.note(format!("the full type name has been written to '{}'", path.display()));
-            diag.note("consider using `--verbose` to print the full type name to the console");
-        }
+        self.note_error_origin(diag, cause, exp_found, terr, param_env);
 
         debug!(?diag);
     }
@@ -1891,6 +1884,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         trace: &TypeTrace<'tcx>,
         terr: TypeError<'tcx>,
+        path: &mut Option<PathBuf>,
     ) -> Vec<TypeErrorAdditionalDiags> {
         let mut suggestions = Vec::new();
         let span = trace.cause.span;
@@ -1969,7 +1963,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         })
         | ObligationCauseCode::BlockTailExpression(.., source)) = code
             && let hir::MatchSource::TryDesugar(_) = source
-            && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values, &trace.cause)
+            && let Some((expected_ty, found_ty)) = self.values_str(trace.values, &trace.cause, path)
         {
             suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
                 found: found_ty.content(),
@@ -2048,12 +2042,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
 
         let span = trace.cause.span;
+        let mut path = None;
         let failure_code = trace.cause.as_failure_code_diag(
             terr,
             span,
-            self.type_error_additional_suggestions(&trace, terr),
+            self.type_error_additional_suggestions(&trace, terr, &mut path),
         );
         let mut diag = self.dcx().create_err(failure_code);
+        *diag.long_ty_path() = path;
         self.note_type_err(
             &mut diag,
             &trace.cause,
@@ -2098,10 +2094,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         values: ValuePairs<'tcx>,
         cause: &ObligationCause<'tcx>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+        file: &mut Option<PathBuf>,
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         match values {
             ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found),
-            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found),
+            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, file),
             ValuePairs::Aliases(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
@@ -2111,7 +2108,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     found: exp_found.found.print_trait_sugared(),
                 };
                 match self.expected_found_str(pretty_exp_found) {
-                    Some((expected, found, _)) if expected == found => {
+                    Some((expected, found)) if expected == found => {
                         self.expected_found_str(exp_found)
                     }
                     ret => ret,
@@ -2133,9 +2130,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     (None, None)
                 };
 
-                let (exp, fnd) =
-                    self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2);
-                Some((exp, fnd, None))
+                Some(self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2))
             }
         }
     }
@@ -2143,7 +2138,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn expected_found_str_term(
         &self,
         exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+        path: &mut Option<PathBuf>,
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2158,21 +2154,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 let len = self.tcx.sess().diagnostic_width() + 40;
                 let exp_s = exp.content();
                 let fnd_s = fnd.content();
-                let mut path = None;
                 if exp_s.len() > len {
-                    let exp_s = self.tcx.short_ty_string(expected, &mut path);
+                    let exp_s = self.tcx.short_string(expected, path);
                     exp = DiagStyledString::highlighted(exp_s);
                 }
                 if fnd_s.len() > len {
-                    let fnd_s = self.tcx.short_ty_string(found, &mut path);
+                    let fnd_s = self.tcx.short_string(found, path);
                     fnd = DiagStyledString::highlighted(fnd_s);
                 }
-                (exp, fnd, path)
+                (exp, fnd)
             }
             _ => (
                 DiagStyledString::highlighted(exp_found.expected.to_string()),
                 DiagStyledString::highlighted(exp_found.found.to_string()),
-                None,
             ),
         })
     }
@@ -2181,7 +2175,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         exp_found: ty::error::ExpectedFound<T>,
-    ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
+    ) -> Option<(DiagStyledString, DiagStyledString)> {
         let exp_found = self.resolve_vars_if_possible(exp_found);
         if exp_found.references_error() {
             return None;
@@ -2190,7 +2184,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         Some((
             DiagStyledString::highlighted(exp_found.expected.to_string()),
             DiagStyledString::highlighted(exp_found.found.to_string()),
-            None,
         ))
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 68a53381230..99b70c87ccd 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -713,7 +713,7 @@ impl<'tcx> InferSourceKind<'tcx> {
                 if ty.is_closure() {
                     ("closure", closure_as_fn_str(infcx, ty), path)
                 } else if !ty.is_ty_or_numeric_infer() {
-                    ("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
+                    ("normal", infcx.tcx.short_string(ty, &mut path), path)
                 } else {
                     ("other", String::new(), path)
                 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
deleted file mode 100644
index beae9962f7f..00000000000
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs
+++ /dev/null
@@ -1,422 +0,0 @@
-use rustc_errors::{Diag, Subdiagnostic};
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::traits::ObligationCauseCode;
-use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
-use rustc_span::kw;
-use tracing::debug;
-
-use super::ObligationCauseAsDiagArg;
-use crate::error_reporting::infer::{TypeErrCtxt, note_and_explain_region};
-use crate::errors::{
-    FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, RefLongerThanData,
-    RegionOriginNote, WhereClauseSuggestions, note_and_explain,
-};
-use crate::fluent_generated as fluent;
-use crate::infer::{self, SubregionOrigin};
-
-impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
-    pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
-        match *origin {
-            infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
-                span: trace.cause.span,
-                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
-            }
-            .add_to_diag(err),
-            infer::Reborrow(span) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
-            }
-            infer::RelateObjectBound(span) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
-                    .add_to_diag(err);
-            }
-            infer::ReferenceOutlivesReferent(ty, span) => {
-                RegionOriginNote::WithName {
-                    span,
-                    msg: fluent::infer_reference_outlives_referent,
-                    name: &self.ty_to_string(ty),
-                    continues: false,
-                }
-                .add_to_diag(err);
-            }
-            infer::RelateParamBound(span, ty, opt_span) => {
-                RegionOriginNote::WithName {
-                    span,
-                    msg: fluent::infer_relate_param_bound,
-                    name: &self.ty_to_string(ty),
-                    continues: opt_span.is_some(),
-                }
-                .add_to_diag(err);
-                if let Some(span) = opt_span {
-                    RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
-                        .add_to_diag(err);
-                }
-            }
-            infer::RelateRegionParamBound(span, _) => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
-                    .add_to_diag(err);
-            }
-            infer::CompareImplItemObligation { span, .. } => {
-                RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
-                    .add_to_diag(err);
-            }
-            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
-                self.note_region_origin(err, parent);
-            }
-            infer::AscribeUserTypeProvePredicate(span) => {
-                RegionOriginNote::Plain {
-                    span,
-                    msg: fluent::infer_ascribe_user_type_prove_predicate,
-                }
-                .add_to_diag(err);
-            }
-        }
-    }
-
-    pub(super) fn report_concrete_failure(
-        &self,
-        generic_param_scope: LocalDefId,
-        origin: SubregionOrigin<'tcx>,
-        sub: Region<'tcx>,
-        sup: Region<'tcx>,
-    ) -> Diag<'a> {
-        let mut err = match origin {
-            infer::Subtype(box trace) => {
-                let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
-                let mut err = self.report_and_explain_type_error(trace, terr);
-                match (*sub, *sup) {
-                    (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
-                    (ty::RePlaceholder(_), _) => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "",
-                            sup,
-                            " doesn't meet the lifetime requirements",
-                            None,
-                        );
-                    }
-                    (_, ty::RePlaceholder(_)) => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "the required lifetime does not necessarily outlive ",
-                            sub,
-                            "",
-                            None,
-                        );
-                    }
-                    _ => {
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "",
-                            sup,
-                            "...",
-                            None,
-                        );
-                        note_and_explain_region(
-                            self.tcx,
-                            &mut err,
-                            generic_param_scope,
-                            "...does not necessarily outlive ",
-                            sub,
-                            "",
-                            None,
-                        );
-                    }
-                }
-                err
-            }
-            infer::Reborrow(span) => {
-                let reference_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::RefValidFor,
-                    note_and_explain::SuffixKind::Continues,
-                );
-                let content_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::ContentValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(OutlivesContent {
-                    span,
-                    notes: reference_valid.into_iter().chain(content_valid).collect(),
-                })
-            }
-            infer::RelateObjectBound(span) => {
-                let object_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::TypeObjValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let pointer_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::SourcePointerValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(OutlivesBound {
-                    span,
-                    notes: object_valid.into_iter().chain(pointer_valid).collect(),
-                })
-            }
-            infer::RelateParamBound(span, ty, opt_span) => {
-                let prefix = match *sub {
-                    ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
-                    _ => note_and_explain::PrefixKind::TypeOutlive,
-                };
-                let suffix = if opt_span.is_some() {
-                    note_and_explain::SuffixKind::ReqByBinding
-                } else {
-                    note_and_explain::SuffixKind::Empty
-                };
-                let note = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    opt_span,
-                    prefix,
-                    suffix,
-                );
-                self.dcx().create_err(FulfillReqLifetime {
-                    span,
-                    ty: self.resolve_vars_if_possible(ty),
-                    note,
-                })
-            }
-            infer::RelateRegionParamBound(span, _) => {
-                let param_instantiated = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::LfParamInstantiatedWith,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let param_must_outlive = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::LfParamMustOutlive,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(LfBoundNotSatisfied {
-                    span,
-                    notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
-                })
-            }
-            infer::ReferenceOutlivesReferent(ty, span) => {
-                let pointer_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::PointerValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let data_valid = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::DataValidFor,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(RefLongerThanData {
-                    span,
-                    ty: self.resolve_vars_if_possible(ty),
-                    notes: pointer_valid.into_iter().chain(data_valid).collect(),
-                })
-            }
-            infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
-                let mut err = self.infcx.report_extra_impl_obligation(
-                    span,
-                    impl_item_def_id,
-                    trait_item_def_id,
-                    &format!("`{sup}: {sub}`"),
-                );
-                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
-                if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id)
-                    && generics.where_clause_span.contains(span)
-                {
-                    self.suggest_copy_trait_method_bounds(
-                        trait_item_def_id,
-                        impl_item_def_id,
-                        &mut err,
-                    );
-                }
-                err
-            }
-            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
-                let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
-
-                // Don't mention the item name if it's an RPITIT, since that'll just confuse
-                // folks.
-                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
-                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
-                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
-                    err.span_label(
-                        trait_item_span,
-                        format!("definition of `{item_name}` from trait"),
-                    );
-                }
-
-                self.suggest_copy_trait_method_bounds(
-                    trait_item_def_id,
-                    impl_item_def_id,
-                    &mut err,
-                );
-                err
-            }
-            infer::AscribeUserTypeProvePredicate(span) => {
-                let instantiated = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sup,
-                    None,
-                    note_and_explain::PrefixKind::LfInstantiatedWith,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                let must_outlive = note_and_explain::RegionExplanation::new(
-                    self.tcx,
-                    generic_param_scope,
-                    sub,
-                    None,
-                    note_and_explain::PrefixKind::LfMustOutlive,
-                    note_and_explain::SuffixKind::Empty,
-                );
-                self.dcx().create_err(LfBoundNotSatisfied {
-                    span,
-                    notes: instantiated.into_iter().chain(must_outlive).collect(),
-                })
-            }
-        };
-        if sub.is_error() || sup.is_error() {
-            err.downgrade_to_delayed_bug();
-        }
-        err
-    }
-
-    pub fn suggest_copy_trait_method_bounds(
-        &self,
-        trait_item_def_id: DefId,
-        impl_item_def_id: LocalDefId,
-        err: &mut Diag<'_>,
-    ) {
-        // FIXME(compiler-errors): Right now this is only being used for region
-        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
-        // but right now it's not really very smart when it comes to implicit `Sized`
-        // predicates and bounds on the trait itself.
-
-        let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
-        else {
-            return;
-        };
-        let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
-            return;
-        };
-        let trait_args = trait_ref
-            .instantiate_identity()
-            // Replace the explicit self type with `Self` for better suggestion rendering
-            .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
-            .args;
-        let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
-            .rebase_onto(self.tcx, impl_def_id, trait_args);
-
-        let Ok(trait_predicates) =
-            self.tcx
-                .explicit_predicates_of(trait_item_def_id)
-                .instantiate_own(self.tcx, trait_item_args)
-                .map(|(pred, _)| {
-                    if pred.is_suggestable(self.tcx, false) {
-                        Ok(pred.to_string())
-                    } else {
-                        Err(())
-                    }
-                })
-                .collect::<Result<Vec<_>, ()>>()
-        else {
-            return;
-        };
-
-        let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else {
-            return;
-        };
-
-        let suggestion = if trait_predicates.is_empty() {
-            WhereClauseSuggestions::Remove { span: generics.where_clause_span }
-        } else {
-            let space = if generics.where_clause_span.is_empty() { " " } else { "" };
-            WhereClauseSuggestions::CopyPredicates {
-                span: generics.where_clause_span,
-                space,
-                trait_predicates: trait_predicates.join(", "),
-            }
-        };
-        err.subdiagnostic(suggestion);
-    }
-
-    pub(super) fn report_placeholder_failure(
-        &self,
-        generic_param_scope: LocalDefId,
-        placeholder_origin: SubregionOrigin<'tcx>,
-        sub: Region<'tcx>,
-        sup: Region<'tcx>,
-    ) -> Diag<'a> {
-        // I can't think how to do better than this right now. -nikomatsakis
-        debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
-        match placeholder_origin {
-            infer::Subtype(box ref trace)
-                if matches!(
-                    &trace.cause.code().peel_derives(),
-                    ObligationCauseCode::WhereClause(..)
-                        | ObligationCauseCode::WhereClauseInExpr(..)
-                ) =>
-            {
-                // Hack to get around the borrow checker because trace.cause has an `Rc`.
-                if let ObligationCauseCode::WhereClause(_, span)
-                | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
-                    &trace.cause.code().peel_derives()
-                    && !span.is_dummy()
-                {
-                    let span = *span;
-                    self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
-                        .with_span_note(span, "the lifetime requirement is introduced here")
-                } else {
-                    unreachable!(
-                        "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
-                    )
-                }
-            }
-            infer::Subtype(box trace) => {
-                let terr = TypeError::RegionsPlaceholderMismatch;
-                return self.report_and_explain_type_error(trace, terr);
-            }
-            _ => {
-                return self.report_concrete_failure(
-                    generic_param_scope,
-                    placeholder_origin,
-                    sub,
-                    sup,
-                );
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 3acca47025c..f35a5349ecb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -221,7 +221,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
                 span: trace.cause.span,
                 requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values, &trace.cause).map(|(e, f, _)| (e, f)),
+                expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()),
             }
             .add_to_diag(err),
             infer::Reborrow(span) => {
@@ -946,10 +946,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         if let infer::Subtype(ref sup_trace) = sup_origin
             && let infer::Subtype(ref sub_trace) = sub_origin
-            && let Some((sup_expected, sup_found, _)) =
-                self.values_str(sup_trace.values, &sup_trace.cause)
-            && let Some((sub_expected, sub_found, _)) =
-                self.values_str(sub_trace.values, &sup_trace.cause)
+            && let Some((sup_expected, sup_found)) =
+                self.values_str(sup_trace.values, &sup_trace.cause, err.long_ty_path())
+            && let Some((sub_expected, sub_found)) =
+                self.values_str(sub_trace.values, &sup_trace.cause, err.long_ty_path())
             && sub_expected == sup_expected
             && sub_found == sup_found
         {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index 231fecf7a4a..562000e28ac 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -418,7 +418,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 };
 
                 let sugg = match (expected.is_ref(), found.is_ref()) {
-                    (true, false) => FunctionPointerSuggestion::UseRef { span, fn_name },
+                    (true, false) => {
+                        FunctionPointerSuggestion::UseRef { span: span.shrink_to_lo() }
+                    }
                     (false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
                     (true, true) => {
                         diag.subdiagnostic(FnItemsAreDistinct);
@@ -426,7 +428,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                     (false, false) => {
                         diag.subdiagnostic(FnItemsAreDistinct);
-                        FunctionPointerSuggestion::Cast { span, fn_name, sig }
+                        FunctionPointerSuggestion::Cast { span: span.shrink_to_hi(), sig }
                     }
                 };
                 diag.subdiagnostic(sugg);
@@ -466,8 +468,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                 } else {
                     FunctionPointerSuggestion::CastBoth {
-                        span,
-                        fn_name,
+                        span: span.shrink_to_hi(),
                         found_sig: *found_sig,
                         expected_sig: *expected_sig,
                     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index b4d294a70c0..6beb108bc3a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -163,6 +163,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         let predicate = self.resolve_vars_if_possible(obligation.predicate);
         let span = obligation.cause.span;
+        let mut file = None;
 
         debug!(?predicate, obligation.cause.code = ?obligation.cause.code());
 
@@ -179,7 +180,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     return e;
                 }
 
-                if let Err(guar) = self.tcx.ensure().coherent_trait(trait_pred.def_id()) {
+                if let Err(guar) = self.tcx.ensure_ok().coherent_trait(trait_pred.def_id()) {
                     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                     // other `Foo` impls are incoherent.
                     return guar;
@@ -245,7 +246,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         span,
                         E0283,
                         "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        self.tcx.short_string(predicate, &mut file),
                     )
                 };
 
@@ -292,7 +293,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         err.cancel();
                         return e;
                     }
-                    err.note(format!("cannot satisfy `{predicate}`"));
+                    let pred = self.tcx.short_string(predicate, &mut file);
+                    err.note(format!("cannot satisfy `{pred}`"));
                     let impl_candidates =
                         self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap());
                     if impl_candidates.len() < 40 {
@@ -511,8 +513,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     return e;
                 }
 
-                if let Err(guar) =
-                    self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id))
+                if let Err(guar) = self
+                    .tcx
+                    .ensure_ok()
+                    .coherent_trait(self.tcx.parent(data.projection_term.def_id))
                 {
                     // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                     // other `Foo` impls are incoherent.
@@ -524,6 +528,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     .iter()
                     .chain(Some(data.term.into_arg()))
                     .find(|g| g.has_non_region_infer());
+                let predicate = self.tcx.short_string(predicate, &mut file);
                 if let Some(arg) = arg {
                     self.emit_inference_failure_err(
                         obligation.cause.body_id,
@@ -539,8 +544,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         self.dcx(),
                         span,
                         E0284,
-                        "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        "type annotations needed: cannot satisfy `{predicate}`",
                     )
                     .with_span_label(span, format!("cannot satisfy `{predicate}`"))
                 }
@@ -565,12 +569,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     err
                 } else {
                     // If we can't find a generic parameter, just print a generic error
+                    let predicate = self.tcx.short_string(predicate, &mut file);
                     struct_span_code_err!(
                         self.dcx(),
                         span,
                         E0284,
-                        "type annotations needed: cannot satisfy `{}`",
-                        predicate,
+                        "type annotations needed: cannot satisfy `{predicate}`",
                     )
                     .with_span_label(span, format!("cannot satisfy `{predicate}`"))
                 }
@@ -590,6 +594,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let Some(e) = self.tainted_by_errors() {
                     return e;
                 }
+                let alias = self.tcx.short_string(alias, &mut file);
                 struct_span_code_err!(
                     self.dcx(),
                     span,
@@ -603,16 +608,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let Some(e) = self.tainted_by_errors() {
                     return e;
                 }
+                let predicate = self.tcx.short_string(predicate, &mut file);
                 struct_span_code_err!(
                     self.dcx(),
                     span,
                     E0284,
-                    "type annotations needed: cannot satisfy `{}`",
-                    predicate,
+                    "type annotations needed: cannot satisfy `{predicate}`",
                 )
                 .with_span_label(span, format!("cannot satisfy `{predicate}`"))
             }
         };
+        *err.long_ty_path() = file;
         self.note_obligation_cause(&mut err, obligation);
         err.emit()
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 6416c539f26..d0a193e8bd5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1,5 +1,6 @@
 use core::ops::ControlFlow;
 use std::borrow::Cow;
+use std::path::PathBuf;
 
 use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::FxHashMap;
@@ -9,7 +10,6 @@ use rustc_errors::{
     Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions,
     pluralize, struct_span_code_err,
 };
-use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, LangItem, Node};
@@ -20,8 +20,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::print::{
-    FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _,
-    PrintTraitRefExt as _, with_forced_trimmed_paths,
+    PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
+    with_forced_trimmed_paths,
 };
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast};
 use rustc_middle::{bug, span_bug};
@@ -60,6 +60,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     ) -> ErrorGuaranteed {
         let tcx = self.tcx;
         let mut span = obligation.cause.span;
+        let mut long_ty_file = None;
 
         let mut err = match *error {
             SelectionError::Unimplemented => {
@@ -169,11 +170,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         if let Err(guar) = self.fn_arg_obligation(&obligation) {
                             return guar;
                         }
-                        let mut file = None;
                         let (post_message, pre_message, type_def) = self
                             .get_parent_trait_ref(obligation.cause.code())
                             .map(|(t, s)| {
-                                let t = self.tcx.short_ty_string(t, &mut file);
+                                let t = self.tcx.short_string(t, &mut long_ty_file);
                                 (
                                     format!(" in `{t}`"),
                                     format!("within `{t}`, "),
@@ -181,12 +181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                                 )
                             })
                             .unwrap_or_default();
-                        let file_note = file.as_ref().map(|file| format!(
-                            "the full trait has been written to '{}'",
-                            file.display(),
-                        ));
-
-                        let mut long_ty_file = None;
 
                         let OnUnimplementedNote {
                             message,
@@ -223,6 +217,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             None,
                             append_const_msg,
                             post_message,
+                            &mut long_ty_file,
                         );
 
                         let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait)
@@ -251,14 +246,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         };
 
                         let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
+                        *err.long_ty_path() = long_ty_file;
 
-                        if let Some(long_ty_file) = long_ty_file {
-                            err.note(format!(
-                                "the full name for the type has been written to '{}'",
-                                long_ty_file.display(),
-                            ));
-                            err.note("consider using `--verbose` to print the full type name to the console");
-                        }
                         let mut suggested = false;
                         if is_try_conversion {
                             suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);
@@ -309,7 +298,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             return err.emit();
                         }
 
-                        file_note.map(|note| err.note(note));
                         if let Some(s) = label {
                             // If it has a custom `#[rustc_on_unimplemented]`
                             // error message, let's display it as the label!
@@ -762,14 +750,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             trait_ref: predicate.trait_ref,
             polarity: ty::PredicatePolarity::Positive,
         });
+        let mut file = None;
         let err_msg = self.get_standard_error_message(
             trait_ref,
             None,
             Some(predicate.constness()),
             None,
             String::new(),
+            &mut file,
         );
         let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
+        *diag.long_ty_path() = file;
         if !self.predicate_may_hold(&Obligation::new(
             self.tcx,
             ObligationCause::dummy(),
@@ -1381,6 +1372,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 _ => (None, error.err),
             };
 
+            let mut file = None;
             let (msg, span, closure_span) = values
                 .and_then(|(predicate, normalized_term, expected_term)| {
                     self.maybe_detailed_projection_msg(
@@ -1388,24 +1380,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         predicate,
                         normalized_term,
                         expected_term,
+                        &mut file,
                     )
                 })
                 .unwrap_or_else(|| {
-                    let mut cx = FmtPrinter::new_with_limit(
-                        self.tcx,
-                        Namespace::TypeNS,
-                        rustc_session::Limit(10),
-                    );
                     (
-                        with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", {
-                            self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
-                            cx.into_buffer()
-                        })),
+                        with_forced_trimmed_paths!(format!(
+                            "type mismatch resolving `{}`",
+                            self.tcx
+                                .short_string(self.resolve_vars_if_possible(predicate), &mut file),
+                        )),
                         obligation.cause.span,
                         None,
                     )
                 });
             let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}");
+            *diag.long_ty_path() = file;
             if let Some(span) = closure_span {
                 // Mark the closure decl so that it is seen even if we are pointing at the return
                 // type or expression.
@@ -1471,15 +1461,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         ty.span,
                         with_forced_trimmed_paths!(Cow::from(format!(
                             "type mismatch resolving `{}`",
-                            {
-                                let mut cx = FmtPrinter::new_with_limit(
-                                    self.tcx,
-                                    Namespace::TypeNS,
-                                    rustc_session::Limit(5),
-                                );
-                                self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
-                                cx.into_buffer()
-                            }
+                            self.tcx.short_string(
+                                self.resolve_vars_if_possible(predicate),
+                                diag.long_ty_path()
+                            ),
                         ))),
                         true,
                     )),
@@ -1512,6 +1497,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         projection_term: ty::AliasTerm<'tcx>,
         normalized_ty: ty::Term<'tcx>,
         expected_ty: ty::Term<'tcx>,
+        file: &mut Option<PathBuf>,
     ) -> Option<(String, Span, Option<Span>)> {
         let trait_def_id = projection_term.trait_def_id(self.tcx);
         let self_ty = projection_term.self_ty();
@@ -1552,7 +1538,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 };
                 let item = match self_ty.kind() {
                     ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
-                    _ => self_ty.to_string(),
+                    _ => self.tcx.short_string(self_ty, file),
                 };
                 Some((format!(
                     "expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \
@@ -1984,8 +1970,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         StringPart::normal(" implemented for `"),
                     ]);
                     if types_content.0 == types_content.1 {
-                        let ty =
-                            self.tcx.short_ty_string(obligation_trait_ref.self_ty(), &mut None);
+                        let ty = self
+                            .tcx
+                            .short_string(obligation_trait_ref.self_ty(), err.long_ty_path());
                         msg.push(StringPart::normal(ty));
                     } else {
                         msg.extend(types.0.0);
@@ -2342,7 +2329,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // First, attempt to add note to this error with an async-await-specific
         // message, and fall back to regular note otherwise.
         if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
-            let mut long_ty_file = None;
             self.note_obligation_cause_code(
                 obligation.cause.body_id,
                 err,
@@ -2351,15 +2337,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 obligation.cause.code(),
                 &mut vec![],
                 &mut Default::default(),
-                &mut long_ty_file,
             );
-            if let Some(file) = long_ty_file {
-                err.note(format!(
-                    "the full name for the type has been written to '{}'",
-                    file.display(),
-                ));
-                err.note("consider using `--verbose` to print the full type name to the console");
-            }
             self.suggest_unsized_bound_if_applicable(err, obligation);
             if let Some(span) = err.span.primary_span()
                 && let Some(mut diag) =
@@ -2403,6 +2381,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         predicate_constness: Option<ty::BoundConstness>,
         append_const_msg: Option<AppendConstMessage>,
         post_message: String,
+        long_ty_file: &mut Option<PathBuf>,
     ) -> String {
         message
             .and_then(|cannot_do_this| {
@@ -2426,7 +2405,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             .unwrap_or_else(|| {
                 format!(
                     "the trait bound `{}` is not satisfied{post_message}",
-                    trait_predicate.print_with_bound_constness(predicate_constness)
+                    self.tcx.short_string(
+                        trait_predicate.print_with_bound_constness(predicate_constness),
+                        long_ty_file,
+                    ),
                 )
             })
     }
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 b4e5cc6185c..658fb4009d5 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -306,7 +306,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if let ObligationCauseCode::WhereClause(..)
                 | ObligationCauseCode::WhereClauseInExpr(..) = code
                 {
-                    let mut long_ty_file = None;
                     self.note_obligation_cause_code(
                         error.obligation.cause.body_id,
                         &mut diag,
@@ -315,17 +314,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         code,
                         &mut vec![],
                         &mut Default::default(),
-                        &mut long_ty_file,
                     );
-                    if let Some(file) = long_ty_file {
-                        diag.note(format!(
-                            "the full name for the type has been written to '{}'",
-                            file.display(),
-                        ));
-                        diag.note(
-                            "consider using `--verbose` to print the full type name to the console",
-                        );
-                    }
                 }
                 diag.emit()
             }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 3d79b0acf83..518323f6526 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -932,7 +932,7 @@ impl<'tcx> OnUnimplementedFormatString {
                 let value = match param.kind {
                     GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
                         if let Some(ty) = trait_ref.args[param.index as usize].as_type() {
-                            tcx.short_ty_string(ty, long_ty_file)
+                            tcx.short_string(ty, long_ty_file)
                         } else {
                             trait_ref.args[param.index as usize].to_string()
                         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
index d82acc4e054..fad03b5e9bf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -141,7 +141,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             obligation.cause.span,
             suggest_increasing_limit,
             |err| {
-                let mut long_ty_file = None;
                 self.note_obligation_cause_code(
                     obligation.cause.body_id,
                     err,
@@ -150,17 +149,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     obligation.cause.code(),
                     &mut vec![],
                     &mut Default::default(),
-                    &mut long_ty_file,
                 );
-                if let Some(file) = long_ty_file {
-                    err.note(format!(
-                        "the full name for the type has been written to '{}'",
-                        file.display(),
-                    ));
-                    err.note(
-                        "consider using `--verbose` to print the full type name to the console",
-                    );
-                }
             },
         );
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index ab25bef4120..24ca7bb7fc2 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3,7 +3,6 @@
 use std::assert_matches::debug_assert_matches;
 use std::borrow::Cow;
 use std::iter;
-use std::path::PathBuf;
 
 use itertools::{EitherOrBoth, Itertools};
 use rustc_abi::ExternAbi;
@@ -1297,30 +1296,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     // Because of this, we modify the error to refer to the original obligation and
                     // return early in the caller.
 
-                    let msg = format!("the trait bound `{old_pred}` is not satisfied");
+                    let msg = format!(
+                        "the trait bound `{}` is not satisfied",
+                        self.tcx.short_string(old_pred, err.long_ty_path()),
+                    );
+                    let self_ty_str =
+                        self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path());
                     if has_custom_message {
                         err.note(msg);
                     } else {
                         err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
                     }
-                    let mut file = None;
                     err.span_label(
                         span,
                         format!(
-                            "the trait `{}` is not implemented for `{}`",
-                            old_pred.print_modifiers_and_trait_path(),
-                            self.tcx.short_ty_string(old_pred.self_ty().skip_binder(), &mut file),
+                            "the trait `{}` is not implemented for `{self_ty_str}`",
+                            old_pred.print_modifiers_and_trait_path()
                         ),
                     );
-                    if let Some(file) = file {
-                        err.note(format!(
-                            "the full type name has been written to '{}'",
-                            file.display()
-                        ));
-                        err.note(
-                            "consider using `--verbose` to print full type name to the console",
-                        );
-                    }
 
                     if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
                         err.span_suggestions(
@@ -2689,7 +2682,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // Add a note for the item obligation that remains - normally a note pointing to the
         // bound that introduced the obligation (e.g. `T: Send`).
         debug!(?next_code);
-        let mut long_ty_file = None;
         self.note_obligation_cause_code(
             obligation.cause.body_id,
             err,
@@ -2698,7 +2690,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             next_code.unwrap(),
             &mut Vec::new(),
             &mut Default::default(),
-            &mut long_ty_file,
         );
     }
 
@@ -2711,7 +2702,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         cause_code: &ObligationCauseCode<'tcx>,
         obligated_types: &mut Vec<Ty<'tcx>>,
         seen_requirements: &mut FxHashSet<DefId>,
-        long_ty_file: &mut Option<PathBuf>,
     ) where
         T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
     {
@@ -2965,9 +2955,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::Coercion { source, target } => {
                 let source =
-                    tcx.short_ty_string(self.resolve_vars_if_possible(source), long_ty_file);
+                    tcx.short_string(self.resolve_vars_if_possible(source), err.long_ty_path());
                 let target =
-                    tcx.short_ty_string(self.resolve_vars_if_possible(target), long_ty_file);
+                    tcx.short_string(self.resolve_vars_if_possible(target), err.long_ty_path());
                 err.note(with_forced_trimmed_paths!(format!(
                     "required for the cast from `{source}` to `{target}`",
                 )));
@@ -3252,7 +3242,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 };
 
                 if !is_upvar_tys_infer_tuple {
-                    let ty_str = tcx.short_ty_string(ty, long_ty_file);
+                    let ty_str = tcx.short_string(ty, err.long_ty_path());
                     let msg = format!("required because it appears within the type `{ty_str}`");
                     match ty.kind() {
                         ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) {
@@ -3330,7 +3320,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             &data.parent_code,
                             obligated_types,
                             seen_requirements,
-                            long_ty_file,
                         )
                     });
                 } else {
@@ -3343,7 +3332,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             cause_code.peel_derives(),
                             obligated_types,
                             seen_requirements,
-                            long_ty_file,
                         )
                     });
                 }
@@ -3353,7 +3341,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     self.resolve_vars_if_possible(data.derived.parent_trait_pred);
                 let parent_def_id = parent_trait_pred.def_id();
                 let self_ty_str =
-                    tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
+                    tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
                 let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
                 let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`");
                 let mut is_auto_trait = false;
@@ -3449,8 +3437,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         count,
                         pluralize!(count)
                     ));
-                    let self_ty = tcx
-                        .short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
+                    let self_ty = tcx.short_string(
+                        parent_trait_pred.skip_binder().self_ty(),
+                        err.long_ty_path(),
+                    );
                     err.note(format!(
                         "required for `{self_ty}` to implement `{}`",
                         parent_trait_pred.print_modifiers_and_trait_path()
@@ -3466,7 +3456,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3505,7 +3494,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.derived.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3519,7 +3507,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3536,7 +3523,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         &data.parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3551,7 +3537,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         nested,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
                 let mut multispan = MultiSpan::from(span);
@@ -3582,7 +3567,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         parent_code,
                         obligated_types,
                         seen_requirements,
-                        long_ty_file,
                     )
                 });
             }
@@ -3622,7 +3606,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::OpaqueReturnType(expr_info) => {
                 let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
-                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
                     let expr = tcx.hir().expect_expr(hir_id);
                     (expr_ty, expr)
                 } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
@@ -3637,7 +3621,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
                     && self.can_eq(param_env, pred.self_ty(), expr_ty)
                 {
-                    let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
+                    let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
                     (expr_ty, expr)
                 } else {
                     return;
@@ -5231,7 +5215,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
             format!(
                 "{pre_message}the trait `{}` is not implemented for{desc} `{}`",
                 trait_predicate.print_modifiers_and_trait_path(),
-                tcx.short_ty_string(trait_predicate.self_ty().skip_binder(), &mut None),
+                tcx.short_string(trait_predicate.self_ty().skip_binder(), &mut None),
             )
         } else {
             // "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index c5ab8a71c78..62cac5b17bd 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1391,15 +1391,13 @@ pub struct OpaqueCapturesLifetime<'tcx> {
 pub enum FunctionPointerSuggestion<'a> {
     #[suggestion(
         trait_selection_fps_use_ref,
-        code = "&{fn_name}",
+        code = "&",
         style = "verbose",
         applicability = "maybe-incorrect"
     )]
     UseRef {
         #[primary_span]
         span: Span,
-        #[skip_arg]
-        fn_name: String,
     },
     #[suggestion(
         trait_selection_fps_remove_ref,
@@ -1429,7 +1427,7 @@ pub enum FunctionPointerSuggestion<'a> {
     },
     #[suggestion(
         trait_selection_fps_cast,
-        code = "{fn_name} as {sig}",
+        code = " as {sig}",
         style = "verbose",
         applicability = "maybe-incorrect"
     )]
@@ -1437,13 +1435,11 @@ pub enum FunctionPointerSuggestion<'a> {
         #[primary_span]
         span: Span,
         #[skip_arg]
-        fn_name: String,
-        #[skip_arg]
         sig: Binder<'a, FnSig<'a>>,
     },
     #[suggestion(
         trait_selection_fps_cast_both,
-        code = "{fn_name} as {found_sig}",
+        code = " as {found_sig}",
         style = "hidden",
         applicability = "maybe-incorrect"
     )]
@@ -1451,8 +1447,6 @@ pub enum FunctionPointerSuggestion<'a> {
         #[primary_span]
         span: Span,
         #[skip_arg]
-        fn_name: String,
-        #[skip_arg]
         found_sig: Binder<'a, FnSig<'a>>,
         expected_sig: Binder<'a, FnSig<'a>>,
     },
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 401b41c796d..cb3e81f5477 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -575,7 +575,7 @@ fn report_conflicting_impls<'tcx>(
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
-                || tcx.ensure().orphan_check_impl(impl_def_id).is_ok()
+                || tcx.ensure_ok().orphan_check_impl(impl_def_id).is_ok()
             {
                 let mut err = tcx.dcx().struct_span_err(impl_span, msg());
                 err.code(E0119);
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index c351cf5aaac..f39c611d19f 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -379,7 +379,7 @@ pub(crate) fn assoc_def(
         // Ensure that the impl is constrained, otherwise projection may give us
         // bad unconstrained infer vars.
         if let Some(impl_def_id) = impl_def_id.as_local() {
-            tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
+            tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
         }
 
         let item = tcx.associated_item(impl_item_id);
@@ -402,7 +402,7 @@ pub(crate) fn assoc_def(
         if assoc_item.item.container == ty::AssocItemContainer::Impl
             && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
         {
-            tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
+            tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
         }
 
         Ok(assoc_item)
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 37d49cc2f55..96051ad0aa5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -830,8 +830,25 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 // Let the visitor iterate into the argument/return
                 // types appearing in the fn signature.
             }
-            ty::UnsafeBinder(_) => {
-                // FIXME(unsafe_binders): We should also recurse into the binder here.
+            ty::UnsafeBinder(ty) => {
+                // FIXME(unsafe_binders): For now, we have no way to express
+                // that a type must be `ManuallyDrop` OR `Copy` (or a pointer).
+                if !ty.has_escaping_bound_vars() {
+                    self.out.push(traits::Obligation::new(
+                        self.tcx(),
+                        self.cause(ObligationCauseCode::Misc),
+                        self.param_env,
+                        ty.map_bound(|ty| {
+                            ty::TraitRef::new(
+                                self.tcx(),
+                                self.tcx().require_lang_item(LangItem::Copy, Some(self.span)),
+                                [ty],
+                            )
+                        }),
+                    ));
+                }
+
+                // We recurse into the binder below.
             }
 
             ty::Dynamic(data, r, _) => {
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 931c36137ee..4038a1d68fa 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -116,6 +116,11 @@ fn recurse_build<'tcx>(
         | &ExprKind::ValueTypeAscription { source, .. } => {
             recurse_build(tcx, body, source, root_span)?
         }
+        &ExprKind::PlaceUnwrapUnsafeBinder { .. }
+        | &ExprKind::ValueUnwrapUnsafeBinder { .. }
+        | &ExprKind::WrapUnsafeBinder { .. } => {
+            todo!("FIXME(unsafe_binders)")
+        }
         &ExprKind::Literal { lit, neg } => {
             let sp = node.span;
             tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg })
@@ -347,6 +352,9 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
             | thir::ExprKind::Adt(_)
             | thir::ExprKind::PlaceTypeAscription { .. }
             | thir::ExprKind::ValueTypeAscription { .. }
+            | thir::ExprKind::PlaceUnwrapUnsafeBinder { .. }
+            | thir::ExprKind::ValueUnwrapUnsafeBinder { .. }
+            | thir::ExprKind::WrapUnsafeBinder { .. }
             | thir::ExprKind::Closure(_)
             | thir::ExprKind::Literal { .. }
             | thir::ExprKind::NonHirLiteral { .. }
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index d5e1937efaa..8c6e3c86bf5 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -225,7 +225,7 @@ fn resolve_associated_item<'tcx>(
             if trait_item_id != leaf_def.item.def_id
                 && let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
             {
-                tcx.ensure().compare_impl_item(leaf_def_item)?;
+                tcx.ensure_ok().compare_impl_item(leaf_def_item)?;
             }
 
             Some(ty::Instance::new(leaf_def.item.def_id, args))
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 97974d195fe..594236cf1d9 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -973,6 +973,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(1.max(2), 2);
     /// assert_eq!(2.max(2), 2);
     /// ```
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// #[derive(Eq)]
+    /// struct Equal(&'static str);
+    ///
+    /// impl PartialEq for Equal {
+    ///     fn eq(&self, other: &Self) -> bool { true }
+    /// }
+    /// impl PartialOrd for Equal {
+    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+    /// }
+    /// impl Ord for Equal {
+    ///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+    /// }
+    ///
+    /// assert_eq!(Equal("self").max(Equal("other")).0, "other");
+    /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
@@ -981,7 +999,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     where
         Self: Sized,
     {
-        max_by(self, other, Ord::cmp)
+        if other < self { self } else { other }
     }
 
     /// Compares and returns the minimum of two values.
@@ -994,6 +1012,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(1.min(2), 1);
     /// assert_eq!(2.min(2), 2);
     /// ```
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// #[derive(Eq)]
+    /// struct Equal(&'static str);
+    ///
+    /// impl PartialEq for Equal {
+    ///     fn eq(&self, other: &Self) -> bool { true }
+    /// }
+    /// impl PartialOrd for Equal {
+    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+    /// }
+    /// impl Ord for Equal {
+    ///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+    /// }
+    ///
+    /// assert_eq!(Equal("self").min(Equal("other")).0, "self");
+    /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
     #[must_use]
@@ -1002,7 +1038,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     where
         Self: Sized,
     {
-        min_by(self, other, Ord::cmp)
+        if other < self { other } else { self }
     }
 
     /// Restrict a value to a certain interval.
@@ -1414,6 +1450,24 @@ pub macro PartialOrd($item:item) {
 /// assert_eq!(cmp::min(1, 2), 1);
 /// assert_eq!(cmp::min(2, 2), 2);
 /// ```
+/// ```
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::min(Equal("v1"), Equal("v2")).0, "v1");
+/// ```
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1431,20 +1485,22 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
-/// assert_eq!(result, 1);
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
 ///
-/// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
-/// assert_eq!(result, -2);
+/// let result = cmp::min_by(2, -1, abs_cmp);
+/// assert_eq!(result, -1);
+///
+/// let result = cmp::min_by(2, -3, abs_cmp);
+/// assert_eq!(result, 2);
+///
+/// let result = cmp::min_by(1, -1, abs_cmp);
+/// assert_eq!(result, 1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
-    match compare(&v1, &v2) {
-        Ordering::Less | Ordering::Equal => v1,
-        Ordering::Greater => v2,
-    }
+    if compare(&v2, &v1).is_lt() { v2 } else { v1 }
 }
 
 /// Returns the element that gives the minimum value from the specified function.
@@ -1456,17 +1512,20 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::min_by_key(-2, 1, |x: &i32| x.abs());
-/// assert_eq!(result, 1);
+/// let result = cmp::min_by_key(2, -1, |x: &i32| x.abs());
+/// assert_eq!(result, -1);
 ///
-/// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs());
-/// assert_eq!(result, -2);
+/// let result = cmp::min_by_key(2, -3, |x: &i32| x.abs());
+/// assert_eq!(result, 2);
+///
+/// let result = cmp::min_by_key(1, -1, |x: &i32| x.abs());
+/// assert_eq!(result, 1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
-    min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { v2 } else { v1 }
 }
 
 /// Compares and returns the maximum of two values.
@@ -1483,6 +1542,24 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 /// assert_eq!(cmp::max(1, 2), 2);
 /// assert_eq!(cmp::max(2, 2), 2);
 /// ```
+/// ```
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::max(Equal("v1"), Equal("v2")).0, "v2");
+/// ```
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1500,20 +1577,22 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
+///
+/// let result = cmp::max_by(3, -2, abs_cmp) ;
+/// assert_eq!(result, 3);
+///
+/// let result = cmp::max_by(1, -2, abs_cmp);
 /// assert_eq!(result, -2);
 ///
-/// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ;
-/// assert_eq!(result, 2);
+/// let result = cmp::max_by(1, -1, abs_cmp);
+/// assert_eq!(result, -1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
-    match compare(&v1, &v2) {
-        Ordering::Less | Ordering::Equal => v2,
-        Ordering::Greater => v1,
-    }
+    if compare(&v2, &v1).is_lt() { v1 } else { v2 }
 }
 
 /// Returns the element that gives the maximum value from the specified function.
@@ -1525,17 +1604,20 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs());
+/// let result = cmp::max_by_key(3, -2, |x: &i32| x.abs());
+/// assert_eq!(result, 3);
+///
+/// let result = cmp::max_by_key(1, -2, |x: &i32| x.abs());
 /// assert_eq!(result, -2);
 ///
-/// let result = cmp::max_by_key(-2, 2, |x: &i32| x.abs());
-/// assert_eq!(result, 2);
+/// let result = cmp::max_by_key(1, -1, |x: &i32| x.abs());
+/// assert_eq!(result, -1);
 /// ```
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
 pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
-    max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { v1 } else { v2 }
 }
 
 /// Compares and sorts two values, returning minimum and maximum.
@@ -1549,13 +1631,32 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 /// use std::cmp;
 ///
 /// assert_eq!(cmp::minmax(1, 2), [1, 2]);
-/// assert_eq!(cmp::minmax(2, 2), [2, 2]);
+/// assert_eq!(cmp::minmax(2, 1), [1, 2]);
 ///
 /// // You can destructure the result using array patterns
 /// let [min, max] = cmp::minmax(42, 17);
 /// assert_eq!(min, 17);
 /// assert_eq!(max, 42);
 /// ```
+/// ```
+/// #![feature(cmp_minmax)]
+/// use std::cmp::{self, Ordering};
+///
+/// #[derive(Eq)]
+/// struct Equal(&'static str);
+///
+/// impl PartialEq for Equal {
+///     fn eq(&self, other: &Self) -> bool { true }
+/// }
+/// impl PartialOrd for Equal {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
+/// }
+/// impl Ord for Equal {
+///     fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
+/// }
+///
+/// assert_eq!(cmp::minmax(Equal("v1"), Equal("v2")).map(|v| v.0), ["v1", "v2"]);
+/// ```
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
@@ -1563,7 +1664,7 @@ pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
 where
     T: Ord,
 {
-    if v1 <= v2 { [v1, v2] } else { [v2, v1] }
+    if v2 < v1 { [v2, v1] } else { [v1, v2] }
 }
 
 /// Returns minimum and maximum values with respect to the specified comparison function.
@@ -1576,11 +1677,14 @@ where
 /// #![feature(cmp_minmax)]
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
-/// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
+/// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
+///
+/// assert_eq!(cmp::minmax_by(-2, 1, abs_cmp), [1, -2]);
+/// assert_eq!(cmp::minmax_by(-1, 2, abs_cmp), [-1, 2]);
+/// assert_eq!(cmp::minmax_by(-2, 2, abs_cmp), [-2, 2]);
 ///
 /// // You can destructure the result using array patterns
-/// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// let [min, max] = cmp::minmax_by(-42, 17, abs_cmp);
 /// assert_eq!(min, 17);
 /// assert_eq!(max, -42);
 /// ```
@@ -1591,7 +1695,7 @@ pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
 where
     F: FnOnce(&T, &T) -> Ordering,
 {
-    if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
+    if compare(&v2, &v1).is_lt() { [v2, v1] } else { [v1, v2] }
 }
 
 /// Returns minimum and maximum values with respect to the specified key function.
@@ -1620,7 +1724,7 @@ where
     F: FnMut(&T) -> K,
     K: Ord,
 {
-    minmax_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+    if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] }
 }
 
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index ec569291853..0c6eaf60d04 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1681,7 +1681,7 @@ impl<T, const N: usize> *const [T; N] {
     }
 }
 
-// Equality for pointers
+/// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *const T {
     #[inline]
@@ -1691,10 +1691,11 @@ impl<T: ?Sized> PartialEq for *const T {
     }
 }
 
+/// Pointer equality is an equivalence relation.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Eq for *const T {}
 
-// Comparison for pointers
+/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Ord for *const T {
     #[inline]
@@ -1710,6 +1711,7 @@ impl<T: ?Sized> Ord for *const T {
     }
 }
 
+/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialOrd for *const T {
     #[inline]
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5d9d337f101..d1b0104c0fa 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -2097,7 +2097,7 @@ impl<T, const N: usize> *mut [T; N] {
     }
 }
 
-// Equality for pointers
+/// Pointer equality is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *mut T {
     #[inline(always)]
@@ -2107,9 +2107,11 @@ impl<T: ?Sized> PartialEq for *mut T {
     }
 }
 
+/// Pointer equality is an equivalence relation.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Eq for *mut T {}
 
+/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Ord for *mut T {
     #[inline]
@@ -2125,6 +2127,7 @@ impl<T: ?Sized> Ord for *mut T {
     }
 }
 
+/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialOrd for *mut T {
     #[inline(always)]
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index e0dd2e14817..fd0fd1cb755 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2318,14 +2318,10 @@ pub fn exit(code: i32) -> ! {
 /// Terminates the process in an abnormal fashion.
 ///
 /// The function will never return and will immediately terminate the current
-/// process in a platform specific "abnormal" manner.
-///
-/// Note that because this function never returns, and that it terminates the
-/// process, no destructors on the current stack or any other thread's stack
-/// will be run.
-///
-/// Rust IO buffers (eg, from `BufWriter`) will not be flushed.
-/// Likewise, C stdio buffers will (on most platforms) not be flushed.
+/// process in a platform specific "abnormal" manner. As a consequence,
+/// no destructors on the current stack or any other thread's stack
+/// will be run, Rust IO buffers (eg, from `BufWriter`) will not be flushed,
+/// and C stdio buffers will (on most platforms) not be flushed.
 ///
 /// This is in contrast to the default behavior of [`panic!`] which unwinds
 /// the current thread's stack and calls all destructors.
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 49f2dafd8fd..6fc0abbed9e 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -174,8 +174,6 @@ impl<T> OnceLock<T> {
     ///
     /// Waiting for a computation on another thread to finish:
     /// ```rust
-    /// #![feature(once_wait)]
-    ///
     /// use std::thread;
     /// use std::sync::OnceLock;
     ///
@@ -189,7 +187,7 @@ impl<T> OnceLock<T> {
     /// })
     /// ```
     #[inline]
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait(&self) -> &T {
         self.once.wait_force();
 
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index 01ef71a187f..fb43ada6375 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -181,10 +181,29 @@ pub struct Mutex<T: ?Sized> {
     data: UnsafeCell<T>,
 }
 
-// these are the only places where `T: Send` matters; all other
-// functionality works fine on a single thread.
+/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
+/// the owned `T` from the `Mutex` via [`into_inner`].
+///
+/// [`into_inner`]: Mutex::into_inner
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
+
+/// `T` must be `Send` for [`Mutex`] to be `Sync`.
+/// This ensures that the protected data can be accessed safely from multiple threads
+/// without causing data races or other unsafe behavior.
+///
+/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
+/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
+/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
+/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
+/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
+/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
+/// to potential data races.
+///
+/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
+/// to one thread at a time if `T` is not `Sync`.
+///
+/// [`Rc`]: crate::rc::Rc
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
 
@@ -211,8 +230,17 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
     poison: poison::Guard,
 }
 
+/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
+///
+/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
+/// release mutex locks on the same thread they were acquired.
+/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
+/// another thread.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
+
+/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
+/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
 #[stable(feature = "mutexguard", since = "1.19.0")]
 unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
 
diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs
index 27db4b634fb..528b11ca0c1 100644
--- a/library/std/src/sync/poison/once.rs
+++ b/library/std/src/sync/poison/once.rs
@@ -269,8 +269,6 @@ impl Once {
     /// # Example
     ///
     /// ```rust
-    /// #![feature(once_wait)]
-    ///
     /// use std::sync::Once;
     /// use std::thread;
     ///
@@ -289,7 +287,7 @@ impl Once {
     /// If this [`Once`] has been poisoned because an initialization closure has
     /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force)
     /// if this behavior is not desired.
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait(&self) {
         if !self.inner.is_completed() {
             self.inner.wait(false);
@@ -298,7 +296,7 @@ impl Once {
 
     /// Blocks the current thread until initialization has completed, ignoring
     /// poisoning.
-    #[unstable(feature = "once_wait", issue = "127527")]
+    #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")]
     pub fn wait_force(&self) {
         if !self.inner.is_completed() {
             self.inner.wait(true);
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 37299a5a76b..2bbe3756580 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -525,8 +525,7 @@ auto:
     env:
       RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
       SCRIPT: make ci-mingw
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-i686-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows-25-8c
 
@@ -535,8 +534,7 @@ auto:
     env:
       SCRIPT: make ci-mingw-x
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows
 
@@ -544,8 +542,7 @@ auto:
     env:
       SCRIPT: make ci-mingw-bootstrap
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
+      # There is no dist-x86_64-mingw-alt, so there is no prebuilt LLVM with assertions
       NO_DOWNLOAD_CI_LLVM: 1
     <<: *job-windows
 
@@ -593,9 +590,6 @@ auto:
       RUST_CONFIGURE_ARGS: >-
         --build=i686-pc-windows-gnu
         --enable-full-tools
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
-      NO_DOWNLOAD_CI_LLVM: 1
       SCRIPT: python x.py dist bootstrap --include-default-paths
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
@@ -607,9 +601,6 @@ auto:
       RUST_CONFIGURE_ARGS: >-
         --build=x86_64-pc-windows-gnu
         --enable-full-tools
-      # We are intentionally allowing an old toolchain on this builder (and that's
-      # incompatible with LLVM downloads today).
-      NO_DOWNLOAD_CI_LLVM: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-windows
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index 4a7dad0090b..8850e168145 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -1,8 +1,19 @@
 #!/bin/bash
+set -euo pipefail
 
 # Free disk space on Linux GitHub action runners
 # Script inspired by https://github.com/jlumbroso/free-disk-space
 
+isX86() {
+    local arch
+    arch=$(uname -m)
+    if [ "$arch" = "x86_64" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
 # print a line of the specified character
 printSeparationLine() {
     for ((i = 0; i < 80; i++)); do
@@ -14,11 +25,15 @@ printSeparationLine() {
 # compute available space
 # REF: https://unix.stackexchange.com/a/42049/60849
 # REF: https://stackoverflow.com/a/450821/408734
-getAvailableSpace() { echo $(df -a | awk 'NR > 1 {avail+=$4} END {print avail}'); }
+getAvailableSpace() {
+    df -a | awk 'NR > 1 {avail+=$4} END {print avail}'
+}
 
 # make Kb human readable (assume the input is Kb)
 # REF: https://unix.stackexchange.com/a/44087/60849
-formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
+formatByteCount() {
+    numfmt --to=iec-i --suffix=B --padding=7 "$1"'000'
+}
 
 # macro to output saved space
 printSavedSpace() {
@@ -58,11 +73,27 @@ removeDir() {
     dir=${1}
 
     local before
-    before=$(getAvailableSpace)
+    if [ ! -d "$dir" ]; then
+        echo "::warning::Directory $dir does not exist, skipping."
+    else
+        before=$(getAvailableSpace)
+        sudo rm -rf "$dir"
+        printSavedSpace "$before" "Removed $dir"
+    fi
+}
+
+removeUnusedDirectories() {
+    local dirs_to_remove=(
+        "/usr/local/lib/android"
+        "/usr/share/dotnet"
 
-    sudo rm -rf "$dir" || true
+        # Haskell runtime
+        "/usr/local/.ghcup"
+    )
 
-    printSavedSpace "$before" "$dir"
+    for dir in "${dirs_to_remove[@]}"; do
+        removeDir "$dir"
+    done
 }
 
 execAndMeasureSpaceChange() {
@@ -79,21 +110,29 @@ execAndMeasureSpaceChange() {
 # Remove large packages
 # REF: https://github.com/apache/flink/blob/master/tools/azure-pipelines/free_disk_space.sh
 cleanPackages() {
-    sudo apt-get -qq remove -y --fix-missing \
-        '^aspnetcore-.*'       \
-        '^dotnet-.*'           \
-        '^llvm-.*'             \
-        'php.*'                \
-        '^mongodb-.*'          \
-        '^mysql-.*'            \
-        'azure-cli'            \
-        'google-chrome-stable' \
-        'firefox'              \
-        'powershell'           \
-        'mono-devel'           \
-        'libgl1-mesa-dri'      \
-        'google-cloud-sdk'     \
-        'google-cloud-cli'
+    local packages=(
+        '^aspnetcore-.*'
+        '^dotnet-.*'
+        '^llvm-.*'
+        '^mongodb-.*'
+        '^mysql-.*'
+        'azure-cli'
+        'firefox'
+        'libgl1-mesa-dri'
+        'mono-devel'
+        'php.*'
+    )
+
+    if isX86; then
+        packages+=(
+            'google-chrome-stable'
+            'google-cloud-cli'
+            'google-cloud-sdk'
+            'powershell'
+        )
+    fi
+
+    sudo apt-get -qq remove -y --fix-missing "${packages[@]}"
 
     sudo apt-get autoremove -y || echo "::warning::The command [sudo apt-get autoremove -y] failed"
     sudo apt-get clean || echo "::warning::The command [sudo apt-get clean] failed failed"
@@ -101,9 +140,9 @@ cleanPackages() {
 
 # Remove Docker images
 cleanDocker() {
-    echo "Removing the following docker images:"
+    echo "=> Removing the following docker images:"
     sudo docker image ls
-    echo "Removing docker images..."
+    echo "=> Removing docker images..."
     sudo docker image prune --all --force || true
 }
 
@@ -121,17 +160,12 @@ AVAILABLE_INITIAL=$(getAvailableSpace)
 printDF "BEFORE CLEAN-UP:"
 echo ""
 
-removeDir /usr/local/lib/android
-removeDir /usr/share/dotnet
-
-# Haskell runtime
-removeDir /opt/ghc
-removeDir /usr/local/.ghcup
-
-execAndMeasureSpaceChange cleanPackages "Large misc. packages"
+execAndMeasureSpaceChange cleanPackages "Unused packages"
 execAndMeasureSpaceChange cleanDocker "Docker images"
 execAndMeasureSpaceChange cleanSwap "Swap storage"
 
+removeUnusedDirectories
+
 # Output saved space statistic
 echo ""
 printDF "AFTER CLEAN-UP:"
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 0437ebb5857..a072b1256f4 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -336,14 +336,14 @@ pub(crate) fn run_global_ctxt(
 
     // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
     let _ = tcx.sess.time("wf_checking", || {
-        tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
+        tcx.hir().try_par_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module))
     });
 
     tcx.dcx().abort_if_errors();
 
     tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));
     tcx.sess.time("check_mod_attrs", || {
-        tcx.hir().for_each_module(|module| tcx.ensure().check_mod_attrs(module))
+        tcx.hir().for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module))
     });
     rustc_passes::stability::check_unused_or_stable_features(tcx);
 
diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs
index 589b99518a0..7bae04a10f1 100644
--- a/src/tools/clippy/clippy_lints/src/ctfe.rs
+++ b/src/tools/clippy/clippy_lints/src/ctfe.rs
@@ -21,6 +21,6 @@ impl<'tcx> LateLintPass<'tcx> for ClippyCtfe {
         _: Span,
         defid: LocalDefId,
     ) {
-        cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint
+        cx.tcx.ensure_ok().mir_drops_elaborated_and_const_checked(defid); // Lint
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 287bdc9a6fd..0aaef91e48a 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -116,6 +116,7 @@ fn check_rvalue<'tcx>(
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
+        | Rvalue::WrapUnsafeBinder(operand, _)
         | Rvalue::Cast(
             CastKind::PointerWithExposedProvenance
             | CastKind::IntToInt
@@ -289,7 +290,8 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Index(_) => {},
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {},
         }
     }
 
diff --git a/tests/codegen/issues/issue-136329-optnone-noinline.rs b/tests/codegen/issues/issue-136329-optnone-noinline.rs
new file mode 100644
index 00000000000..57c9e47a499
--- /dev/null
+++ b/tests/codegen/issues/issue-136329-optnone-noinline.rs
@@ -0,0 +1,21 @@
+//! Ensure that `#[optimize(none)]` functions are never inlined
+
+//@ compile-flags: -Copt-level=3
+
+#![feature(optimize_attribute)]
+
+#[optimize(none)]
+pub fn foo() {
+    let _x = 123;
+}
+
+// CHECK-LABEL: define{{.*}}void @bar
+// CHECK: start:
+// CHECK: {{.*}}call {{.*}}void
+// CHECK: ret void
+#[no_mangle]
+pub fn bar() {
+    foo();
+}
+
+fn main() {}
diff --git a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
index 0c220a13876..b682bdac034 100644
--- a/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
+++ b/tests/ui/coercion/coerce-expect-unsized-ascribed.stderr
@@ -29,7 +29,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:14:27
    |
 LL |     let _ = type_ascribe!(Box::new( { |x| (x as u8) }), Box<dyn Fn(i32) -> _>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:14:39}>`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@...}>`
    |
    = note: expected struct `Box<dyn Fn(i32) -> u8>`
               found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:14:39: 14:42}>`
@@ -85,7 +85,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:22:27
    |
 LL |     let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _);
-   |                           ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@coerce-expect-unsized-ascribed.rs:22:30}`
+   |                           ^^^^^^^^^^^^^^^^^^ expected `&dyn Fn(i32) -> u8`, found `&{closure@...}`
    |
    = note: expected reference `&dyn Fn(i32) -> u8`
               found reference `&{closure@$DIR/coerce-expect-unsized-ascribed.rs:22:30: 22:33}`
@@ -123,7 +123,7 @@ error[E0308]: mismatched types
   --> $DIR/coerce-expect-unsized-ascribed.rs:27:27
    |
 LL |     let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:27:36}>`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@...}>`
    |
    = note: expected struct `Box<dyn Fn(i32) -> u8>`
               found struct `Box<{closure@$DIR/coerce-expect-unsized-ascribed.rs:27:36: 27:39}>`
diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index 7446b1a543e..93555b336a6 100644
--- a/tests/ui/diagnostic-width/E0271.ascii.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
+error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
   --> $DIR/E0271.rs:20:5
    |
 LL | /     Box::new(
@@ -7,14 +7,16 @@ LL | |             Err::<(), _>(
 LL | |                 Ok::<_, ()>(
 ...  |
 LL | |     )
-   | |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
+   | |_____^ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    |
 note: expected this to be `Foo`
   --> $DIR/E0271.rs:10:18
    |
 LL |     type Error = E;
    |                  ^
-   = note: required for the cast from `Box<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+   = note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.ascii/E0271.long-type-hash.txt'
+   = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index 061ba45c219..2faf09d46c6 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
-//@[ascii] compile-flags: --diagnostic-width=40
-//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40
+//@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
 //@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 trait Future {
     type Error;
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
index 72df2a381a4..1e9acf603b2 100644
--- a/tests/ui/diagnostic-width/E0271.unicode.stderr
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -1,4 +1,4 @@
-error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
+error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    ╭▸ $DIR/E0271.rs:20:5

 LL │ ┏     Box::new(
@@ -7,14 +7,16 @@ LL │ ┃             Err::<(), _>(
 LL │ ┃                 Ok::<_, ()>(
    ‡ ┃
 LL │ ┃     )
-   │ ┗━━━━━┛ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
+   │ ┗━━━━━┛ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    ╰╴
 note: expected this to be `Foo`
    ╭▸ $DIR/E0271.rs:10:18

 LL │     type Error = E;
    │                  ━
-   ╰ note: required for the cast from `Box<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+   ├ note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.unicode/E0271.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
index 3053e37a87a..83da5586188 100644
--- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
@@ -16,11 +16,11 @@ LL |  |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
 LL |  |             Ok("")
 LL |  |         ))))))))))))))))))))))))))))))
 LL |  |     ))))))))))))))))))))))))))))));
-   |  |__________________________________^ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
+   |  |__________________________________^ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `Result<Result<Result<..., _>, _>, _>`
    |
-   = note: expected struct `Atype<Btype<..., ...>, ...>`
-                found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: expected struct `Atype<Btype<..., i32>, i32>`
+                found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -32,11 +32,11 @@ LL | |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
 LL | |             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL | |         ))))))))))))))))))))))))))))))
 LL | |     ))))))))))))))))))))))));
-   | |____________________________^ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
+   | |____________________________^ expected `Option<Result<Option<Option<...>>, _>>`, found `Result<Result<Result<..., _>, _>, _>`
    |
-   = note: expected enum `Option<Result<..., ...>>`
-              found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: expected enum `Option<Result<Option<...>, _>>`
+              found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -50,13 +50,13 @@ LL | |           Atype<
 ...  |
 LL | |       i32
 LL | |     > = ();
-   | |     -   ^^ expected `Atype<Btype<..., ...>, ...>`, found `()`
+   | |     -   ^^ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `()`
    | |_____|
    |       expected due to this
    |
-   = note: expected struct `Atype<Btype<..., ...>, ...>`
+   = note: expected struct `Atype<Btype<..., i32>, i32>`
            found unit type `()`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -70,11 +70,11 @@ LL | |         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
 LL | |             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL | |         ))))))))))))))))))))))))))))))
 LL | |     ))))))))))))))))))))))));
-   | |____________________________^ expected `()`, found `Result<Result<..., ...>, ...>`
+   | |____________________________^ expected `()`, found `Result<Result<Result<..., _>, _>, _>`
    |
    = note: expected unit type `()`
-                   found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+                   found enum `Result<Result<..., _>, _>`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
index 50b386325b9..54abf576dbd 100644
--- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
@@ -16,11 +16,11 @@ LL │  ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O…
 LL │  ┃             Ok("")
 LL │  ┃         ))))))))))))))))))))))))))))))
 LL │  ┃     ))))))))))))))))))))))))))))));
-   │  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
+   │  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `Result<Result<Result<..., _>, _>, _>`

-   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
-   │            found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: expected struct `Atype<Btype<..., i32>, i32>`
+   │            found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -32,11 +32,11 @@ LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
 LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL │ ┃         ))))))))))))))))))))))))))))))
 LL │ ┃     ))))))))))))))))))))))));
-   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option<Result<Option<Option<...>>, _>>`, found `Result<Result<Result<..., _>, _>, _>`

-   ├ note: expected enum `Option<Result<..., ...>>`
-   │          found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: expected enum `Option<Result<Option<...>, _>>`
+   │          found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -50,13 +50,13 @@ LL │ │           Atype<
    ‡ │
 LL │ │       i32
 LL │ │     > = ();
-   │ │     │   ━━ expected `Atype<Btype<..., ...>, ...>`, found `()`
+   │ │     │   ━━ expected `Atype<Btype<Ctype<..., i32>, i32>, i32>`, found `()`
    │ └─────┤
    │       expected due to this

-   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
+   ├ note: expected struct `Atype<Btype<..., i32>, i32>`
    │       found unit type `()`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
@@ -70,11 +70,11 @@ LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
 LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
 LL │ ┃         ))))))))))))))))))))))))))))))
 LL │ ┃     ))))))))))))))))))))))));
-   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result<Result<..., ...>, ...>`
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result<Result<Result<..., _>, _>, _>`

    ├ note: expected unit type `()`
-   │               found enum `Result<Result<..., ...>, ...>`
-   ├ note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   │               found enum `Result<Result<..., _>, _>`
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs
new file mode 100644
index 00000000000..9b3bd8bb728
--- /dev/null
+++ b/tests/ui/diagnostic-width/long-e0277.rs
@@ -0,0 +1,15 @@
+//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+// The regex below normalizes the long type file name to make it suitable for compare-modes.
+//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+type A = (i32, i32, i32, i32);
+type B = (A, A, A, A);
+type C = (B, B, B, B);
+type D = (C, C, C, C);
+
+trait Trait {}
+
+fn require_trait<T: Trait>() {}
+
+fn main() {
+    require_trait::<D>(); //~ ERROR the trait bound `(...
+}
diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr
new file mode 100644
index 00000000000..a57270df7e2
--- /dev/null
+++ b/tests/ui/diagnostic-width/long-e0277.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied
+  --> $DIR/long-e0277.rs:14:21
+   |
+LL |     require_trait::<D>();
+   |                     ^ unsatisfied trait bound
+   |
+   = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)`
+help: this trait has no implementations, consider adding one
+  --> $DIR/long-e0277.rs:9:1
+   |
+LL | trait Trait {}
+   | ^^^^^^^^^^^
+note: required by a bound in `require_trait`
+  --> $DIR/long-e0277.rs:11:21
+   |
+LL | fn require_trait<T: Trait>() {}
+   |                     ^^^^^ required by this bound in `require_trait`
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: consider using `--verbose` to print the full type name to the console
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
index 889a2b3666d..254542c7b39 100644
--- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr
+++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
@@ -2,13 +2,13 @@ error[E0382]: use of moved value: `x`
   --> $DIR/non-copy-type-moved.rs:16:14
    |
 LL | fn foo(x: D) {
-   |        - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait
+   |        - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait
 LL |     let _a = x;
    |              - value moved here
 LL |     let _b = x;
    |              ^ value used here after move
    |
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 help: consider cloning the value if the performance cost is acceptable
    |
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
index 4caa9424425..c8845af3183 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
@@ -12,7 +12,7 @@ fn foo(x: D) {
     //~^ NOTE this expression has type `((...,
     //~| NOTE expected `((...,
     //~| NOTE expected tuple
-    //~| NOTE the full type name has been written to
+    //~| NOTE the full name for the type has been written to
     //~| NOTE consider using `--verbose` to print the full type name to the console
 }
 
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
index 346b112019f..a95e1709148 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
@@ -8,7 +8,7 @@ LL |     let () = x;
    |
    = note:  expected tuple `((..., ..., ..., ...), ..., ..., ...)`
            found unit type `()`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/fn/fn-pointer-mismatch.stderr b/tests/ui/fn/fn-pointer-mismatch.stderr
index 9cda11639d0..2aa840911f6 100644
--- a/tests/ui/fn/fn-pointer-mismatch.stderr
+++ b/tests/ui/fn/fn-pointer-mismatch.stderr
@@ -67,7 +67,7 @@ LL |     let d: &fn(u32) -> u32 = foo;
 help: consider using a reference
    |
 LL |     let d: &fn(u32) -> u32 = &foo;
-   |                              ~~~~
+   |                              +
 
 error[E0308]: mismatched types
   --> $DIR/fn-pointer-mismatch.rs:48:30
diff --git a/tests/ui/force-inlining/cast.stderr b/tests/ui/force-inlining/cast.stderr
index 116919e5fe7..53132959659 100644
--- a/tests/ui/force-inlining/cast.stderr
+++ b/tests/ui/force-inlining/cast.stderr
@@ -12,7 +12,7 @@ LL |     let _: fn(isize) -> usize = callee;
 help: consider casting to a fn pointer
    |
 LL |     let _: fn(isize) -> usize = callee as fn(isize) -> usize;
-   |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                                        +++++++++++++++++++++
 
 error[E0605]: non-primitive cast: `fn(isize) -> usize {callee}` as `fn(isize) -> usize`
   --> $DIR/cast.rs:15:13
@@ -32,7 +32,7 @@ LL |         callee,
 help: consider casting to a fn pointer
    |
 LL |         callee as fn(isize) -> usize,
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   |                +++++++++++++++++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
index 67417a5e525..be2eca3e61a 100644
--- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
@@ -11,7 +11,7 @@ LL | |     ),
 LL | | ) {
    | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type
 LL |       f
-   |       ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)`
+   |       ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...))))`, found `&dyn Fn(u32)`
    |
    = note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))`
               found reference `&dyn Fn(u32)`
diff --git a/tests/ui/suggestions/box-future-wrong-output.stderr b/tests/ui/suggestions/box-future-wrong-output.stderr
index 6a232c3444d..bac26ae8fb5 100644
--- a/tests/ui/suggestions/box-future-wrong-output.stderr
+++ b/tests/ui/suggestions/box-future-wrong-output.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/box-future-wrong-output.rs:20:39
    |
 LL |     let _: BoxFuture<'static, bool> = async {}.boxed();
-   |            ------------------------   ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |            ------------------------   ^^^^^^^^^^^^^^^^ expected `Pin<Box<...>>`, found `Pin<Box<dyn Future<Output = ()> + Send>>`
    |            |
    |            expected due to this
    |
diff --git a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 42bc094859a..61a1d30d31d 100644
--- a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -32,7 +32,7 @@ error[E0308]: mismatched types
 LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
    |        - found this type parameter
 LL |     Pin::new(x)
-   |     -------- ^ expected `Box<dyn Future<Output = ...> + Send>`, found type parameter `F`
+   |     -------- ^ expected `Box<dyn Future<Output = i32> + Send>`, found type parameter `F`
    |     |
    |     arguments to this function are incorrect
    |     help: use `Box::pin` to pin and box this expression: `Box::pin`
diff --git a/tests/ui/suggestions/issue-107860.stderr b/tests/ui/suggestions/issue-107860.stderr
index 4be495da46b..2bfd2193981 100644
--- a/tests/ui/suggestions/issue-107860.stderr
+++ b/tests/ui/suggestions/issue-107860.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-107860.rs:3:36
    |
 LL | async fn str<T>(T: &str) -> &str { &str }
-   |                                    ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<...>}`
+   |                                    ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<_>}`
    |
    = note: expected reference `&str`
               found reference `&for<'a> fn(&'a str) -> impl Future<Output = &'a str> {str::<_>}`
diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
index 8bfda71bac1..5299236026d 100644
--- a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
+++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<dyn Pointee<Metadata = ()> as Pointee>::
   --> $DIR/ice-with-dyn-pointee-errors.rs:9:33
    |
 LL |     unknown_sized_object_ptr_in(x)
-   |     --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ...>>`
+   |     --------------------------- ^ expected `()`, found `DynMetadata<dyn Pointee<Metadata = ()>>`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index af941e69c5f..2f9fdf151f0 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -110,7 +110,7 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:36:79
    |
 LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x }
-   |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = ...>`
+   |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = &u8>`
    |                                                                            |
    |                                                                            help: try adding a return type: `-> &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>`
    |
@@ -132,7 +132,7 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:38:73
    |
 LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x }
-   |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = ...>`
+   |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = u8>`
    |                                                                      |
    |                                                                      help: try adding a return type: `-> &dyn AnyDifferentBinders<Assoc = u8>`
    |
diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr
index 5722f4006ff..2705d7c501e 100644
--- a/tests/ui/traits/on_unimplemented_long_types.stderr
+++ b/tests/ui/traits/on_unimplemented_long_types.stderr
@@ -13,8 +13,6 @@ LL | |         ))))))))))),
 LL | |     )))))))))))
    | |_______________- return type was inferred to be `Option<Option<Option<...>>>` here
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
-   = note: consider using `--verbose` to print the full type name to the console
    = help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
    = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
diff --git a/tests/ui/typeck/issue-107775.stderr b/tests/ui/typeck/issue-107775.stderr
index dad7e1581e7..1be26897469 100644
--- a/tests/ui/typeck/issue-107775.stderr
+++ b/tests/ui/typeck/issue-107775.stderr
@@ -6,7 +6,7 @@ LL |         map.insert(1, Struct::do_something);
    |         |
    |         ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
 LL |         Self { map }
-   |                ^^^ expected `HashMap<u16, fn(u8) -> Pin<...>>`, found `HashMap<{integer}, ...>`
+   |                ^^^ expected `HashMap<u16, fn(u8) -> Pin<Box<...>>>`, found `HashMap<{integer}, ...>`
    |
    = note: expected struct `HashMap<u16, fn(_) -> Pin<Box<(dyn Future<Output = ()> + Send + 'static)>>>`
               found struct `HashMap<{integer}, fn(_) -> Pin<Box<dyn Future<Output = ()> + Send>> {<Struct as Trait>::do_something::<'_>}>`
diff --git a/tests/ui/typeck/return_type_containing_closure.rs b/tests/ui/typeck/return_type_containing_closure.rs
index b81cac0a58a..a9bb89bae2d 100644
--- a/tests/ui/typeck/return_type_containing_closure.rs
+++ b/tests/ui/typeck/return_type_containing_closure.rs
@@ -2,7 +2,7 @@
 fn foo() { //~ HELP try adding a return type
     vec!['a'].iter().map(|c| c)
     //~^ ERROR mismatched types [E0308]
-    //~| NOTE expected `()`, found `Map<Iter<'_, char>, ...>`
+    //~| NOTE expected `()`, found `Map<Iter<'_, char>, {closure@...}>`
     //~| NOTE expected unit type `()`
     //~| HELP consider using a semicolon here
 }
diff --git a/tests/ui/typeck/return_type_containing_closure.stderr b/tests/ui/typeck/return_type_containing_closure.stderr
index 3f14650a82c..a60bf79a57b 100644
--- a/tests/ui/typeck/return_type_containing_closure.stderr
+++ b/tests/ui/typeck/return_type_containing_closure.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/return_type_containing_closure.rs:3:5
    |
 LL |     vec!['a'].iter().map(|c| c)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map<Iter<'_, char>, ...>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Map<Iter<'_, char>, {closure@...}>`
    |
    = note: expected unit type `()`
                  found struct `Map<std::slice::Iter<'_, char>, {closure@$DIR/return_type_containing_closure.rs:3:26: 3:29}>`
diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs
index 0fe68751f0a..d437d8f8ac0 100644
--- a/tests/ui/unsafe-binders/expr.rs
+++ b/tests/ui/unsafe-binders/expr.rs
@@ -1,3 +1,5 @@
+//@ check-pass
+
 #![feature(unsafe_binders)]
 //~^ WARN the feature `unsafe_binders` is incomplete
 
@@ -7,8 +9,6 @@ fn main() {
     unsafe {
     let x = 1;
         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-        //~^ ERROR unsafe binder casts are not fully implemented
         let rx = *unwrap_binder!(binder);
-        //~^ ERROR unsafe binder casts are not fully implemented
     }
 }
diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr
index 78a288e10a3..07026e18e12 100644
--- a/tests/ui/unsafe-binders/expr.stderr
+++ b/tests/ui/unsafe-binders/expr.stderr
@@ -1,5 +1,5 @@
 warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/expr.rs:1:12
+  --> $DIR/expr.rs:3:12
    |
 LL | #![feature(unsafe_binders)]
    |            ^^^^^^^^^^^^^^
@@ -7,17 +7,5 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:9:55
-   |
-LL |         let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
-   |                                                       ^^
-
-error: unsafe binder casts are not fully implemented
-  --> $DIR/expr.rs:11:34
-   |
-LL |         let rx = *unwrap_binder!(binder);
-   |                                  ^^^^^^
-
-error: aborting due to 2 previous errors; 1 warning emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs
index 731fe2d1ce9..840d938cbe9 100644
--- a/tests/ui/unsafe-binders/mismatch.rs
+++ b/tests/ui/unsafe-binders/mismatch.rs
@@ -5,38 +5,31 @@ use std::unsafe_binder::{wrap_binder, unwrap_binder};
 
 fn a() {
     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
 }
 
 fn b() {
     let _: i32 = wrap_binder!(&());
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR `wrap_binder!()` can only wrap into unsafe binder
+    //~^ ERROR `wrap_binder!()` can only wrap into unsafe binder
 }
 
 fn c() {
     let y = 1;
     unwrap_binder!(y);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    //~| ERROR expected unsafe binder, found integer as input
+    //~^ ERROR expected unsafe binder, found integer as input
 }
 
 fn d() {
     let unknown = Default::default();
+    //~^ ERROR type annotations needed
     unwrap_binder!(unknown);
-    //~^ ERROR unsafe binder casts are not fully implemented
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
 }
 
 fn e() {
     let x = wrap_binder!(&42);
-    //~^ ERROR unsafe binder casts are not fully implemented
+    //~^ ERROR type annotations needed
     // Currently, type inference doesn't flow backwards for unsafe binders.
     // It could, perhaps, but that may cause even more surprising corners.
-    // FIXME(unsafe_binders): This should report ambiguity once we've removed
-    // the error above which taints the infcx.
     let _: unsafe<'a> &'a i32 = x;
 }
 
diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr
index a720e5dbdc1..f64db92eb65 100644
--- a/tests/ui/unsafe-binders/mismatch.stderr
+++ b/tests/ui/unsafe-binders/mismatch.stderr
@@ -7,12 +7,6 @@ LL | #![feature(unsafe_binders)]
    = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:7:46
-   |
-LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
-   |                                              ^^^
-
 error[E0308]: mismatched types
   --> $DIR/mismatch.rs:7:46
    |
@@ -22,14 +16,8 @@ LL |     let _: unsafe<'a> &'a i32 = wrap_binder!(&());
    = note: expected reference `&i32`
               found reference `&()`
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:13:31
-   |
-LL |     let _: i32 = wrap_binder!(&());
-   |                               ^^^
-
 error: `wrap_binder!()` can only wrap into unsafe binder, not `i32`
-  --> $DIR/mismatch.rs:13:18
+  --> $DIR/mismatch.rs:12:18
    |
 LL |     let _: i32 = wrap_binder!(&());
    |                  ^^^^^^^^^^^^^^^^^
@@ -37,32 +25,35 @@ LL |     let _: i32 = wrap_binder!(&());
    = note: unsafe binders are the only valid output of wrap
    = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:20:20
-   |
-LL |     unwrap_binder!(y);
-   |                    ^
-
 error: expected unsafe binder, found integer as input of `unwrap_binder!()`
-  --> $DIR/mismatch.rs:20:20
+  --> $DIR/mismatch.rs:18:20
    |
 LL |     unwrap_binder!(y);
    |                    ^
    |
    = note: only an unsafe binder type can be unwrapped
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:27:20
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:23:9
    |
+LL |     let unknown = Default::default();
+   |         ^^^^^^^
+LL |
 LL |     unwrap_binder!(unknown);
-   |                    ^^^^^^^
+   |                    ------- type must be known at this point
+   |
+help: consider giving `unknown` an explicit type
+   |
+LL |     let unknown: /* Type */ = Default::default();
+   |                ++++++++++++
 
-error: unsafe binder casts are not fully implemented
-  --> $DIR/mismatch.rs:34:26
+error[E0282]: type annotations needed
+  --> $DIR/mismatch.rs:29:26
    |
 LL |     let x = wrap_binder!(&42);
-   |                          ^^^
+   |                          ^^^ cannot infer type
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/unsafe-binders/moves.rs b/tests/ui/unsafe-binders/moves.rs
new file mode 100644
index 00000000000..5bfcee62402
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.rs
@@ -0,0 +1,41 @@
+//@ known-bug: unknown
+
+#![feature(unsafe_binders)]
+// FIXME(unsafe_binders) ~^ WARN the feature `unsafe_binders` is incomplete
+
+use std::unsafe_binder::{wrap_binder, unwrap_binder};
+use std::mem::{drop, ManuallyDrop};
+
+struct NotCopyInner;
+type NotCopy = ManuallyDrop<NotCopyInner>;
+
+fn use_after_wrap() {
+    unsafe {
+        let base = NotCopy;
+        let binder: unsafe<> NotCopy = wrap_binder!(base);
+        drop(base);
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `base`
+    }
+}
+
+fn move_out_of_wrap() {
+    unsafe {
+        let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+        drop(unwrap_binder!(binder));
+        drop(unwrap_binder!(binder));
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder`
+    }
+}
+
+fn not_conflicting() {
+    unsafe {
+        let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+        drop(unwrap_binder!(binder).0);
+        drop(unwrap_binder!(binder).1);
+        // ^ NOT a problem.
+        drop(unwrap_binder!(binder).0);
+        // FIXME(unsafe_binders) ~^ ERROR use of moved value: `binder.0`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unsafe-binders/moves.stderr b/tests/ui/unsafe-binders/moves.stderr
new file mode 100644
index 00000000000..ca507964008
--- /dev/null
+++ b/tests/ui/unsafe-binders/moves.stderr
@@ -0,0 +1,85 @@
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:14:20
+   |
+LL |         let base = NotCopy;
+   |                    ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:23:53
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+   |                                                     ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:32:65
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                                                                 ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0423]: expected value, found type alias `NotCopy`
+  --> $DIR/moves.rs:32:74
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                                                                          ^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/moves.rs:3:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:15:21
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(base);
+   |                     ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:23:21
+   |
+LL |         let binder: unsafe<> NotCopy = wrap_binder!(NotCopy);
+   |                     ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error[E0277]: the trait bound `NotCopyInner: Copy` is not satisfied
+  --> $DIR/moves.rs:32:21
+   |
+LL |         let binder: unsafe<> (NotCopy, NotCopy) = wrap_binder!((NotCopy, NotCopy));
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopyInner`
+   |
+   = note: required for `ManuallyDrop<NotCopyInner>` to implement `Copy`
+   = note: required because it appears within the type `(ManuallyDrop<NotCopyInner>, ManuallyDrop<NotCopyInner>)`
+help: consider annotating `NotCopyInner` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopyInner;
+   |
+
+error: aborting due to 7 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0277, E0423.
+For more information about an error, try `rustc --explain E0277`.