diff --git a/Cargo.lock b/Cargo.lock
index 23481488563bd..9f64aa44314db 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -502,9 +502,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-derive"
-version = "0.80.0"
+version = "0.87.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0001adf0cf12361e08b65e1898ea138f8f77d8f5177cbf29b6b3b3532252bd6"
+checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -514,9 +514,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-engine"
-version = "0.80.0"
+version = "0.87.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c44ee96f2d67cb5193d1503f185db1abad9933a1c6e6b4169c176f90baecd393"
+checksum = "7e54ac43048cb31c470d7b3e3acd409090ef4a5abddfe02455187aebc3d6879f"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
@@ -527,9 +527,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-ir"
-version = "0.80.0"
+version = "0.87.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d8a95548f23618fda86426e4304e563ec2bb7ba0216139f0748d63c107b5f1"
+checksum = "43aa55deff4e7fbdb09fa014543372f2c95a06835ac487b9ce57b5099b950838"
 dependencies = [
  "bitflags",
  "chalk-derive",
@@ -538,9 +538,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-solve"
-version = "0.80.0"
+version = "0.87.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f37f492dacfafe2e21319b80827da2779932909bb392f0cc86b2bd5c07c1b4e1"
+checksum = "61213deefc36ba265ad01c4d997e18bcddf7922862a4594a47ca4575afb3dab4"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 274917f09fe36..f0a83b7a02689 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -376,7 +376,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     /// Read an immediate from a place, asserting that that is possible with the given layout.
     ///
-    /// If this suceeds, the `ImmTy` is never `Uninit`.
+    /// If this succeeds, the `ImmTy` is never `Uninit`.
     #[inline(always)]
     pub fn read_immediate(
         &self,
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 4d0125bf395d6..29d2312612ea9 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -316,8 +316,7 @@ where
         Ok(MPlaceTy { mplace, layout, align })
     }
 
-    /// Take an operand, representing a pointer, and dereference it to a place -- that
-    /// will always be a MemPlace.  Lives in `place.rs` because it creates a place.
+    /// Take an operand, representing a pointer, and dereference it to a place.
     #[instrument(skip(self), level = "debug")]
     pub fn deref_operand(
         &self,
@@ -331,7 +330,7 @@ where
         }
 
         let mplace = self.ref_to_mplace(&val)?;
-        self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?;
+        self.check_mplace(mplace)?;
         Ok(mplace)
     }
 
@@ -358,17 +357,18 @@ where
     }
 
     /// Check if this mplace is dereferenceable and sufficiently aligned.
-    fn check_mplace_access(
-        &self,
-        mplace: MPlaceTy<'tcx, M::Provenance>,
-        msg: CheckInAllocMsg,
-    ) -> InterpResult<'tcx> {
+    pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
         let (size, align) = self
             .size_and_align_of_mplace(&mplace)?
             .unwrap_or((mplace.layout.size, mplace.layout.align.abi));
         assert!(mplace.align <= align, "dynamic alignment less strict than static one?");
         let align = M::enforce_alignment(self).then_some(align);
-        self.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?;
+        self.check_ptr_access_align(
+            mplace.ptr,
+            size,
+            align.unwrap_or(Align::ONE),
+            CheckInAllocMsg::DerefTest,
+        )?;
         Ok(())
     }
 
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
index 6d42b23fb3a21..815e8f4d3567e 100644
--- a/compiler/rustc_error_messages/locales/en-US/parser.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -375,3 +375,12 @@ parser_async_move_order_incorrect = the order of `move` and `async` is incorrect
 
 parser_double_colon_in_bound = expected `:` followed by trait or lifetime
     .suggestion = use single colon
+
+parser_fn_ptr_with_generics = function pointer types may not have generic parameters
+    .suggestion = consider moving the lifetime {$arity ->
+        [one] parameter
+        *[other] parameters
+    } to {$for_param_list_exists ->
+        [true] the
+        *[false] a
+    } `for` parameter list
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index a8fd1a17a5110..170d4341ae71b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1254,6 +1254,10 @@ impl HandlerInner {
         }
 
         if diagnostic.has_future_breakage() {
+            // Future breakages aren't emitted if they're Level::Allowed,
+            // but they still need to be constructed and stashed below,
+            // so they'll trigger the good-path bug check.
+            self.suppressed_expected_diag = true;
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 99af91072882e..5e17d8a021e96 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -333,7 +333,7 @@ fn expand_macro<'cx>(
     assert!(try_success_result.is_err(), "Macro matching returned a success on the second try");
 
     if let Some(result) = tracker.result {
-        // An irrecoverable error occured and has been emitted.
+        // An irrecoverable error occurred and has been emitted.
         return result;
     }
 
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index dc3a74956843e..01477265f6175 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -147,7 +147,7 @@ pub enum AttributeDuplicates {
     FutureWarnPreceding,
 }
 
-/// A conveniece macro to deal with `$($expr)?`.
+/// A convenience macro to deal with `$($expr)?`.
 macro_rules! or_default {
     ($default:expr,) => {
         $default
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 3001e79947672..8d3acee48884d 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -35,7 +35,7 @@ struct ClosureSignatures<'tcx> {
     bound_sig: ty::PolyFnSig<'tcx>,
     /// The signature within the function body.
     /// This mostly differs in the sense that lifetimes are now early bound and any
-    /// opaque types from the signature expectation are overriden in case there are
+    /// opaque types from the signature expectation are overridden in case there are
     /// explicit hidden types written by the user in the closure signature.
     liberated_sig: ty::FnSig<'tcx>,
 }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 37caab2da0f5b..3e2efb7d3610d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -360,7 +360,7 @@ fn lint_int_literal<'tcx>(
         }
 
         if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
-            // The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
+            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
             return;
         }
 
@@ -429,7 +429,7 @@ fn lint_uint_literal<'tcx>(
             }
         }
         if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
-            // The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
+            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
             return;
         }
         if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 8e7d0cf2ab1b0..5f6e498dbeaa2 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -8,7 +8,7 @@ doctest = false
 
 [dependencies]
 bitflags = "1.2.1"
-chalk-ir = "0.80.0"
+chalk-ir = "0.87.0"
 either = "1.5.0"
 gsgdt = "0.1.2"
 polonius-engine = "0.13.0"
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index a4495d2934df3..4781651071d38 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1541,7 +1541,7 @@ impl<'tcx> Place<'tcx> {
     /// If MirPhase >= Derefered and if projection contains Deref,
     /// It's guaranteed to be in the first place
     pub fn has_deref(&self) -> bool {
-        // To make sure this is not accidently used in wrong mir phase
+        // To make sure this is not accidentally used in wrong mir phase
         debug_assert!(
             self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
         );
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 85ef51f129bbd..fed943169dfb5 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -85,7 +85,7 @@ pub enum MirPhase {
     ///
     /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
     /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
-    /// transformations which may supress such errors should not run on analysis MIR.
+    /// transformations which may suppress such errors should not run on analysis MIR.
     Runtime(RuntimePhase),
 }
 
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 183db56d7a08c..db05592ed0ea5 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     else_block: Some(else_block),
                 } => {
                     // When lowering the statement `let <pat> = <expr> else { <else> };`,
-                    // the `<else>` block is nested in the parent scope enclosing this statment.
+                    // the `<else>` block is nested in the parent scope enclosing this statement.
                     // That scope is usually either the enclosing block scope,
                     // or the remainder scope of the last statement.
                     // This is to make sure that temporaries instantiated in `<expr>` are dropped
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 776c748c7e5fe..80b532aec6c1a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -577,6 +577,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     self.errors.push(PatternError::ConstParamInPattern(span));
                     return PatKind::Wild;
                 }
+                ConstKind::Error(_) => {
+                    return PatKind::Wild;
+                }
                 _ => bug!("Expected ConstKind::Param"),
             },
             mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index d59982f7063f3..a39398950a533 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1280,3 +1280,24 @@ pub(crate) struct DoubleColonInBound {
     #[suggestion(code = ": ", applicability = "machine-applicable")]
     pub between: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(parser_fn_ptr_with_generics)]
+pub(crate) struct FnPtrWithGenerics {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sugg: Option<FnPtrWithGenericsSugg>,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
+pub(crate) struct FnPtrWithGenericsSugg {
+    #[suggestion_part(code = "{snippet}")]
+    pub left: Span,
+    pub snippet: String,
+    #[suggestion_part(code = "")]
+    pub right: Span,
+    pub arity: usize,
+    pub for_param_list_exists: bool,
+}
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 3dcadb4c9115f..c78479b098ba0 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -3,6 +3,7 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
+#![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 4d78c5bd0e273..d6854f0702518 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1,5 +1,6 @@
 use super::{Parser, PathStyle, TokenType};
 
+use crate::errors::{FnPtrWithGenerics, FnPtrWithGenericsSugg};
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 
 use rustc_ast::ptr::P;
@@ -270,14 +271,19 @@ impl<'a> Parser<'a> {
             TyKind::Infer
         } else if self.check_fn_front_matter(false, Case::Sensitive) {
             // Function pointer type
-            self.parse_ty_bare_fn(lo, Vec::new(), recover_return_sign)?
+            self.parse_ty_bare_fn(lo, Vec::new(), None, recover_return_sign)?
         } else if self.check_keyword(kw::For) {
             // Function pointer type or bound list (trait object type) starting with a poly-trait.
             //   `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
             //   `for<'lt> Trait1<'lt> + Trait2 + 'a`
             let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
             if self.check_fn_front_matter(false, Case::Sensitive) {
-                self.parse_ty_bare_fn(lo, lifetime_defs, recover_return_sign)?
+                self.parse_ty_bare_fn(
+                    lo,
+                    lifetime_defs,
+                    Some(self.prev_token.span.shrink_to_lo()),
+                    recover_return_sign,
+                )?
             } else {
                 let path = self.parse_path(PathStyle::Type)?;
                 let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
@@ -519,7 +525,8 @@ impl<'a> Parser<'a> {
     fn parse_ty_bare_fn(
         &mut self,
         lo: Span,
-        params: Vec<GenericParam>,
+        mut params: Vec<GenericParam>,
+        param_insertion_point: Option<Span>,
         recover_return_sign: RecoverReturnSign,
     ) -> PResult<'a, TyKind> {
         let inherited_vis = rustc_ast::Visibility {
@@ -530,6 +537,9 @@ impl<'a> Parser<'a> {
         let span_start = self.token.span;
         let ast::FnHeader { ext, unsafety, constness, asyncness } =
             self.parse_fn_front_matter(&inherited_vis)?;
+        if self.may_recover() && self.token.kind == TokenKind::Lt {
+            self.recover_fn_ptr_with_generics(lo, &mut params, param_insertion_point)?;
+        }
         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
         let whole_span = lo.to(self.prev_token.span);
         if let ast::Const::Yes(span) = constness {
@@ -545,6 +555,48 @@ impl<'a> Parser<'a> {
         Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
     }
 
+    /// Recover from function pointer types with a generic parameter list (e.g. `fn<'a>(&'a str)`).
+    fn recover_fn_ptr_with_generics(
+        &mut self,
+        lo: Span,
+        params: &mut Vec<GenericParam>,
+        param_insertion_point: Option<Span>,
+    ) -> PResult<'a, ()> {
+        let generics = self.parse_generics()?;
+        let arity = generics.params.len();
+
+        let mut lifetimes: Vec<_> = generics
+            .params
+            .into_iter()
+            .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime))
+            .collect();
+
+        let sugg = if !lifetimes.is_empty() {
+            let snippet =
+                lifetimes.iter().map(|param| param.ident.as_str()).intersperse(", ").collect();
+
+            let (left, snippet) = if let Some(span) = param_insertion_point {
+                (span, if params.is_empty() { snippet } else { format!(", {snippet}") })
+            } else {
+                (lo.shrink_to_lo(), format!("for<{snippet}> "))
+            };
+
+            Some(FnPtrWithGenericsSugg {
+                left,
+                snippet,
+                right: generics.span,
+                arity,
+                for_param_list_exists: param_insertion_point.is_some(),
+            })
+        } else {
+            None
+        };
+
+        self.sess.emit_err(FnPtrWithGenerics { span: generics.span, sugg });
+        params.append(&mut lifetimes);
+        Ok(())
+    }
+
     /// Emit an error for the given bad function pointer qualifier.
     fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) {
         self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual))
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index fa6d34be0cc37..82dcc7efb1baf 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -72,7 +72,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
                 update(node_id);
                 if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
                     // In theory all the single import IDs have individual visibilities and
-                    // effective visibilities, but in practice these IDs go straigth to HIR
+                    // effective visibilities, but in practice these IDs go straight to HIR
                     // where all their few uses assume that their (effective) visibility
                     // applies to the whole syntactic `use` item. So they all get the same
                     // value which is the maximum of all bindings. Maybe HIR for imports
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index a1ff477c6fefb..9ca3588fff451 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1932,6 +1932,11 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    /// For rustdoc.
+    pub fn get_partial_res(&self, node_id: NodeId) -> Option<PartialRes> {
+        self.partial_res_map.get(&node_id).copied()
+    }
+
     /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
     #[inline]
     pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
diff --git a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
index 2cf2cbc751000..52ee68e7560f6 100644
--- a/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/arm64_32_apple_watchos.rs
@@ -12,6 +12,8 @@ pub fn target() -> Target {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             forces_embed_bitcode: true,
+            dynamic_linking: false,
+            position_independent_executables: true,
             // These arguments are not actually invoked - they just have
             // to look right to pass App Store validation.
             bitcode_llvm_cmdline: "-triple\0\
diff --git a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs
index 45ead8d65aba9..6e1d00d1f6ca5 100644
--- a/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/armv7k_apple_watchos.rs
@@ -12,6 +12,8 @@ pub fn target() -> Target {
             features: "+v7,+vfp4,+neon".into(),
             max_atomic_width: Some(64),
             forces_embed_bitcode: true,
+            dynamic_linking: false,
+            position_independent_executables: true,
             // These arguments are not actually invoked - they just have
             // to look right to pass App Store validation.
             bitcode_llvm_cmdline: "-triple\0\
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index e809f646860b0..664592b02a124 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -114,7 +114,7 @@ pub enum Lld {
 /// relevant now.
 ///
 /// The second goal is to keep the number of flavors to the minimum if possible.
-/// LLD somewhat forces our hand here because that linker is self-sufficent only if its executable
+/// LLD somewhat forces our hand here because that linker is self-sufficient only if its executable
 /// (`argv[0]`) is named in specific way, otherwise it doesn't work and requires a
 /// `-flavor LLD_FLAVOR` argument to choose which logic to use. Our shipped `rust-lld` in
 /// particular is not named in such specific way, so it needs the flavor option, so we make our
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 23c3715860ea6..19f404cb5b788 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -58,10 +58,10 @@ pub struct NoValueInOnUnimplemented {
     pub span: Span,
 }
 
-pub struct NegativePositiveConflict<'a> {
+pub struct NegativePositiveConflict<'tcx> {
     pub impl_span: Span,
-    pub trait_desc: &'a str,
-    pub self_desc: &'a Option<String>,
+    pub trait_desc: ty::TraitRef<'tcx>,
+    pub self_ty: Option<Ty<'tcx>>,
     pub negative_impl_span: Result<Span, Symbol>,
     pub positive_impl_span: Result<Span, Symbol>,
 }
@@ -73,10 +73,10 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
         handler: &Handler,
     ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
         let mut diag = handler.struct_err(fluent::trait_selection_negative_positive_conflict);
-        diag.set_arg("trait_desc", self.trait_desc);
+        diag.set_arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
         diag.set_arg(
             "self_desc",
-            self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
+            self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()),
         );
         diag.set_span(self.impl_span);
         diag.code(rustc_errors::error_code!(E0751));
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 8aab75490a81b..3cf2959a9ffc5 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -64,13 +64,13 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
 /// with a suitably-freshened `ImplHeader` with those types
 /// substituted. Otherwise, returns `None`.
 #[instrument(skip(tcx, skip_leak_check), level = "debug")]
-pub fn overlapping_impls(
-    tcx: TyCtxt<'_>,
+pub fn overlapping_impls<'tcx>(
+    tcx: TyCtxt<'tcx>,
     impl1_def_id: DefId,
     impl2_def_id: DefId,
     skip_leak_check: SkipLeakCheck,
     overlap_mode: OverlapMode,
-) -> Option<OverlapResult<'_>> {
+) -> Option<OverlapResult<'tcx>> {
     // Before doing expensive operations like entering an inference context, do
     // a quick check via fast_reject to tell if the impl headers could possibly
     // unify.
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 231a18f86eae7..7cc12eff20e8b 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -19,9 +19,9 @@ use crate::traits::engine::TraitEngineExt as _;
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee};
+use rustc_errors::{error_code, DelayDm, Diagnostic};
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::{self, ImplSubject, TyCtxt};
+use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
 use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
 use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
@@ -32,10 +32,10 @@ use super::SelectionContext;
 
 /// Information pertinent to an overlapping impl error.
 #[derive(Debug)]
-pub struct OverlapError {
+pub struct OverlapError<'tcx> {
     pub with_impl: DefId,
-    pub trait_desc: String,
-    pub self_desc: Option<String>,
+    pub trait_ref: ty::TraitRef<'tcx>,
+    pub self_ty: Option<Ty<'tcx>>,
     pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
     pub involves_placeholder: bool,
 }
@@ -275,9 +275,9 @@ pub(super) fn specialization_graph_provider(
 // it negatively impacts perf.
 #[cold]
 #[inline(never)]
-fn report_overlap_conflict(
-    tcx: TyCtxt<'_>,
-    overlap: OverlapError,
+fn report_overlap_conflict<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    overlap: OverlapError<'tcx>,
     impl_def_id: LocalDefId,
     used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
     sg: &mut specialization_graph::Graph,
@@ -313,9 +313,9 @@ fn report_overlap_conflict(
     }
 }
 
-fn report_negative_positive_conflict(
-    tcx: TyCtxt<'_>,
-    overlap: &OverlapError,
+fn report_negative_positive_conflict<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    overlap: &OverlapError<'tcx>,
     local_impl_def_id: LocalDefId,
     negative_impl_def_id: DefId,
     positive_impl_def_id: DefId,
@@ -323,17 +323,17 @@ fn report_negative_positive_conflict(
 ) {
     let mut err = tcx.sess.create_err(NegativePositiveConflict {
         impl_span: tcx.def_span(local_impl_def_id),
-        trait_desc: &overlap.trait_desc,
-        self_desc: &overlap.self_desc,
+        trait_desc: overlap.trait_ref,
+        self_ty: overlap.self_ty,
         negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
         positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
     });
     sg.has_errored = Some(err.emit());
 }
 
-fn report_conflicting_impls(
-    tcx: TyCtxt<'_>,
-    overlap: OverlapError,
+fn report_conflicting_impls<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    overlap: OverlapError<'tcx>,
     impl_def_id: LocalDefId,
     used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
     sg: &mut specialization_graph::Graph,
@@ -343,12 +343,12 @@ fn report_conflicting_impls(
     // Work to be done after we've built the DiagnosticBuilder. We have to define it
     // now because the struct_lint methods don't return back the DiagnosticBuilder
     // that's passed in.
-    fn decorate<'a, 'b, G: EmissionGuarantee>(
-        tcx: TyCtxt<'_>,
-        overlap: OverlapError,
+    fn decorate<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        overlap: &OverlapError<'tcx>,
         impl_span: Span,
-        err: &'b mut DiagnosticBuilder<'a, G>,
-    ) -> &'b mut DiagnosticBuilder<'a, G> {
+        err: &mut Diagnostic,
+    ) {
         match tcx.span_of_impl(overlap.with_impl) {
             Ok(span) => {
                 err.span_label(span, "first implementation here");
@@ -357,7 +357,7 @@ fn report_conflicting_impls(
                     impl_span,
                     format!(
                         "conflicting implementation{}",
-                        overlap.self_desc.map_or_else(String::new, |ty| format!(" for `{}`", ty))
+                        overlap.self_ty.map_or_else(String::new, |ty| format!(" for `{}`", ty))
                     ),
                 );
             }
@@ -379,26 +379,28 @@ fn report_conflicting_impls(
         if overlap.involves_placeholder {
             coherence::add_placeholder_note(err);
         }
-        err
     }
 
-    let msg = format!(
-        "conflicting implementations of trait `{}`{}{}",
-        overlap.trait_desc,
-        overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")),
-        match used_to_be_allowed {
-            Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
-            _ => "",
-        }
-    );
+    let msg = DelayDm(|| {
+        format!(
+            "conflicting implementations of trait `{}`{}{}",
+            overlap.trait_ref.print_only_trait_path(),
+            overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
+            match used_to_be_allowed {
+                Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
+                _ => "",
+            }
+        )
+    });
 
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
                 || tcx.orphan_check_impl(impl_def_id).is_ok()
             {
-                let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",);
-                decorate(tcx, overlap, impl_span, &mut err);
+                let mut err = tcx.sess.struct_span_err(impl_span, msg);
+                err.code(error_code!(E0119));
+                decorate(tcx, &overlap, impl_span, &mut err);
                 Some(err.emit())
             } else {
                 Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
@@ -415,7 +417,10 @@ fn report_conflicting_impls(
                 tcx.hir().local_def_id_to_hir_id(impl_def_id),
                 impl_span,
                 msg,
-                |err| decorate(tcx, overlap, impl_span, err),
+                |err| {
+                    decorate(tcx, &overlap, impl_span, err);
+                    err
+                },
             );
         }
     };
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 63f89a33e8adc..4546c95339300 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -3,7 +3,6 @@ use super::OverlapError;
 use crate::traits;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
 
 pub use rustc_middle::traits::specialization_graph::*;
@@ -15,15 +14,15 @@ pub enum FutureCompatOverlapErrorKind {
 }
 
 #[derive(Debug)]
-pub struct FutureCompatOverlapError {
-    pub error: OverlapError,
+pub struct FutureCompatOverlapError<'tcx> {
+    pub error: OverlapError<'tcx>,
     pub kind: FutureCompatOverlapErrorKind,
 }
 
 /// The result of attempting to insert an impl into a group of children.
-enum Inserted {
+enum Inserted<'tcx> {
     /// The impl was inserted as a new child in this group of children.
-    BecameNewSibling(Option<FutureCompatOverlapError>),
+    BecameNewSibling(Option<FutureCompatOverlapError<'tcx>>),
 
     /// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
     ReplaceChildren(Vec<DefId>),
@@ -42,12 +41,12 @@ trait ChildrenExt<'tcx> {
         impl_def_id: DefId,
         simplified_self: Option<SimplifiedType>,
         overlap_mode: OverlapMode,
-    ) -> Result<Inserted, OverlapError>;
+    ) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
 }
 
-impl ChildrenExt<'_> for Children {
+impl<'tcx> ChildrenExt<'tcx> for Children {
     /// Insert an impl into this set of children without comparing to any existing impls.
-    fn insert_blindly(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
+    fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
         {
@@ -62,7 +61,7 @@ impl ChildrenExt<'_> for Children {
     /// Removes an impl from this set of children. Used when replacing
     /// an impl with a parent. The impl must be present in the list of
     /// children already.
-    fn remove_existing(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
+    fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         let vec: &mut Vec<DefId>;
         if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
@@ -82,11 +81,11 @@ impl ChildrenExt<'_> for Children {
     /// specialization relationships.
     fn insert(
         &mut self,
-        tcx: TyCtxt<'_>,
+        tcx: TyCtxt<'tcx>,
         impl_def_id: DefId,
         simplified_self: Option<SimplifiedType>,
         overlap_mode: OverlapMode,
-    ) -> Result<Inserted, OverlapError> {
+    ) -> Result<Inserted<'tcx>, OverlapError<'tcx>> {
         let mut last_lint = None;
         let mut replace_children = Vec::new();
 
@@ -103,30 +102,23 @@ impl ChildrenExt<'_> for Children {
                 impl_def_id, simplified_self, possible_sibling,
             );
 
-            let create_overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
+            let create_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>| {
                 let trait_ref = overlap.impl_header.trait_ref.unwrap();
                 let self_ty = trait_ref.self_ty();
 
-                // FIXME: should postpone string formatting until we decide to actually emit.
-                with_no_trimmed_paths!({
-                    OverlapError {
-                        with_impl: possible_sibling,
-                        trait_desc: trait_ref.print_only_trait_path().to_string(),
-                        // Only report the `Self` type if it has at least
-                        // some outer concrete shell; otherwise, it's
-                        // not adding much information.
-                        self_desc: if self_ty.has_concrete_skeleton() {
-                            Some(self_ty.to_string())
-                        } else {
-                            None
-                        },
-                        intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
-                        involves_placeholder: overlap.involves_placeholder,
-                    }
-                })
+                OverlapError {
+                    with_impl: possible_sibling,
+                    trait_ref,
+                    // Only report the `Self` type if it has at least
+                    // some outer concrete shell; otherwise, it's
+                    // not adding much information.
+                    self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } else { None },
+                    intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
+                    involves_placeholder: overlap.involves_placeholder,
+                }
             };
 
-            let report_overlap_error = |overlap: traits::coherence::OverlapResult<'_>,
+            let report_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>,
                                         last_lint: &mut _| {
                 // Found overlap, but no specialization; error out or report future-compat warning.
 
@@ -255,31 +247,31 @@ where
     }
 }
 
-pub trait GraphExt {
+pub trait GraphExt<'tcx> {
     /// Insert a local impl into the specialization graph. If an existing impl
     /// conflicts with it (has overlap, but neither specializes the other),
     /// information about the area of overlap is returned in the `Err`.
     fn insert(
         &mut self,
-        tcx: TyCtxt<'_>,
+        tcx: TyCtxt<'tcx>,
         impl_def_id: DefId,
         overlap_mode: OverlapMode,
-    ) -> Result<Option<FutureCompatOverlapError>, OverlapError>;
+    ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
 
     /// Insert cached metadata mapping from a child impl back to its parent.
-    fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId);
+    fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
 }
 
-impl GraphExt for Graph {
+impl<'tcx> GraphExt<'tcx> for Graph {
     /// Insert a local impl into the specialization graph. If an existing impl
     /// conflicts with it (has overlap, but neither specializes the other),
     /// information about the area of overlap is returned in the `Err`.
     fn insert(
         &mut self,
-        tcx: TyCtxt<'_>,
+        tcx: TyCtxt<'tcx>,
         impl_def_id: DefId,
         overlap_mode: OverlapMode,
-    ) -> Result<Option<FutureCompatOverlapError>, OverlapError> {
+    ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>> {
         assert!(impl_def_id.is_local());
 
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
@@ -376,7 +368,7 @@ impl GraphExt for Graph {
     }
 
     /// Insert cached metadata mapping from a child impl back to its parent.
-    fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId) {
+    fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId) {
         if self.parent.insert(child, parent).is_some() {
             bug!(
                 "When recording an impl from the crate store, information about its parent \
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
index 951554c77fbb5..9474e6df5677b 100644
--- a/compiler/rustc_traits/Cargo.toml
+++ b/compiler/rustc_traits/Cargo.toml
@@ -12,9 +12,9 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
-chalk-ir = "0.80.0"
-chalk-engine = "0.80.0"
-chalk-solve = "0.80.0"
+chalk-ir = "0.87.0"
+chalk-engine = "0.87.0"
+chalk-solve = "0.87.0"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../rustc_infer" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index 07f92299f72b4..d15707e5ceddb 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -142,6 +142,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             Some(CoerceUnsized)
         } else if lang_items.dispatch_from_dyn_trait() == Some(def_id) {
             Some(DispatchFromDyn)
+        } else if lang_items.tuple_trait() == Some(def_id) {
+            Some(Tuple)
         } else {
             None
         };
@@ -570,6 +572,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             CoerceUnsized => lang_items.coerce_unsized_trait(),
             DiscriminantKind => lang_items.discriminant_kind_trait(),
             DispatchFromDyn => lang_items.dispatch_from_dyn_trait(),
+            Tuple => lang_items.tuple_trait(),
         };
         def_id.map(chalk_ir::TraitId)
     }
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index b64d53e60dee6..25cedefa26127 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -507,9 +507,6 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
                 name: ty::BoundRegionKind::BrAnon(p.idx as u32, None),
             }),
             chalk_ir::LifetimeData::Static => return interner.tcx.lifetimes.re_static,
-            chalk_ir::LifetimeData::Empty(_) => {
-                bug!("Chalk should not have been passed an empty lifetime.")
-            }
             chalk_ir::LifetimeData::Erased => return interner.tcx.lifetimes.re_erased,
             chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
         };
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index 7c5f82f5ea49d..f1a51a550f579 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -18,7 +18,6 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
 }
 
 /// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
-#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
 #[inline]
 #[must_use]
 pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index bb83599369c13..c05b68e30bc90 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -140,7 +140,7 @@ impl char {
     /// assert_eq!(None, c);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
-    #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+    #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_u32(i: u32) -> Option<char> {
@@ -183,7 +183,7 @@ impl char {
     /// assert_eq!('❤', c);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
-    #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+    #[rustc_const_unstable(feature = "const_char_from_u32_unchecked", issue = "89259")]
     #[must_use]
     #[inline]
     pub const unsafe fn from_u32_unchecked(i: u32) -> char {
@@ -241,7 +241,7 @@ impl char {
     /// let _c = char::from_digit(1, 37);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
-    #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+    #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
@@ -338,7 +338,7 @@ impl char {
     /// let _ = '1'.to_digit(37);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+    #[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[inline]
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index b34a7121631c1..55552376280ab 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -110,7 +110,7 @@ pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::Into
 
 /// Converts a `u32` to a `char`. Use [`char::from_u32`] instead.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+#[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
 #[must_use]
 #[inline]
 pub const fn from_u32(i: u32) -> Option<char> {
@@ -120,7 +120,7 @@ pub const fn from_u32(i: u32) -> Option<char> {
 /// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`].
 /// instead.
 #[stable(feature = "char_from_unchecked", since = "1.5.0")]
-#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+#[rustc_const_unstable(feature = "const_char_from_u32_unchecked", issue = "89259")]
 #[must_use]
 #[inline]
 pub const unsafe fn from_u32_unchecked(i: u32) -> char {
@@ -130,7 +130,7 @@ pub const unsafe fn from_u32_unchecked(i: u32) -> char {
 
 /// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
+#[rustc_const_stable(feature = "const_char_convert", since = "CURRENT_RUSTC_VERSION")]
 #[must_use]
 #[inline]
 pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 8425354837841..2d12805270f93 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -104,7 +104,7 @@
 #![feature(const_black_box)]
 #![feature(const_caller_location)]
 #![feature(const_cell_into_inner)]
-#![feature(const_char_convert)]
+#![feature(const_char_from_u32_unchecked)]
 #![feature(const_clone)]
 #![feature(const_cmp)]
 #![feature(const_discriminant)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 7757c95de9d2a..3f491836551dc 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -1172,7 +1172,7 @@ impl<T> MaybeUninit<T> {
     /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)]
     /// use std::mem::MaybeUninit;
     ///
-    /// let val = 0x12345678i32;
+    /// let val = 0x12345678_i32;
     /// let uninit = MaybeUninit::new(val);
     /// let uninit_bytes = uninit.as_bytes();
     /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) };
@@ -1198,7 +1198,7 @@ impl<T> MaybeUninit<T> {
     /// #![feature(maybe_uninit_as_bytes)]
     /// use std::mem::MaybeUninit;
     ///
-    /// let val = 0x12345678i32;
+    /// let val = 0x12345678_i32;
     /// let mut uninit = MaybeUninit::new(val);
     /// let uninit_bytes = uninit.as_bytes_mut();
     /// if cfg!(target_endian = "little") {
diff --git a/library/std/src/os/android/net.rs b/library/std/src/os/android/net.rs
index ff96125c37bdc..7cecd1bbfaa95 100644
--- a/library/std/src/os/android/net.rs
+++ b/library/std/src/os/android/net.rs
@@ -1,4 +1,9 @@
-//! Linux and Android-specific definitions for socket options.
+//! Android-specific networking functionality.
 
 #![unstable(feature = "tcp_quickack", issue = "96256")]
-pub use crate::os::net::tcp::TcpStreamExt;
+
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+pub use crate::os::net::linux_ext::addr::SocketAddrExt;
+
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/linux/net.rs b/library/std/src/os/linux/net.rs
index ff96125c37bdc..94081c8dd31c5 100644
--- a/library/std/src/os/linux/net.rs
+++ b/library/std/src/os/linux/net.rs
@@ -1,4 +1,9 @@
-//! Linux and Android-specific definitions for socket options.
+//! Linux-specific networking functionality.
 
 #![unstable(feature = "tcp_quickack", issue = "96256")]
-pub use crate::os::net::tcp::TcpStreamExt;
+
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+pub use crate::os::net::linux_ext::addr::SocketAddrExt;
+
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/net/linux_ext/addr.rs b/library/std/src/os/net/linux_ext/addr.rs
new file mode 100644
index 0000000000000..df3fc8e6a3b66
--- /dev/null
+++ b/library/std/src/os/net/linux_ext/addr.rs
@@ -0,0 +1,64 @@
+//! Linux and Android-specific extensions to socket addresses.
+
+use crate::os::unix::net::SocketAddr;
+use crate::sealed::Sealed;
+
+/// Platform-specific extensions to [`SocketAddr`].
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+pub trait SocketAddrExt: Sealed {
+    /// Creates a Unix socket address in the abstract namespace.
+    ///
+    /// The abstract namespace is a Linux-specific extension that allows Unix
+    /// sockets to be bound without creating an entry in the filesystem.
+    /// Abstract sockets are unaffected by filesystem layout or permissions,
+    /// and no cleanup is necessary when the socket is closed.
+    ///
+    /// An abstract socket address name may contain any bytes, including zero.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if the name is longer than `SUN_LEN - 1`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(unix_socket_abstract)]
+    /// use std::os::unix::net::{UnixListener, SocketAddr};
+    /// use std::os::linux::net::SocketAddrExt;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let addr = SocketAddr::from_abstract_name(b"hidden")?;
+    ///     let listener = match UnixListener::bind_addr(&addr) {
+    ///         Ok(sock) => sock,
+    ///         Err(err) => {
+    ///             println!("Couldn't bind: {err:?}");
+    ///             return Err(err);
+    ///         }
+    ///     };
+    ///     Ok(())
+    /// }
+    /// ```
+    fn from_abstract_name<N>(name: &N) -> crate::io::Result<SocketAddr>
+    where
+        N: AsRef<[u8]>;
+
+    /// Returns the contents of this address if it is in the abstract namespace.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(unix_socket_abstract)]
+    /// use std::os::unix::net::{UnixListener, SocketAddr};
+    /// use std::os::linux::net::SocketAddrExt;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let name = b"hidden";
+    ///     let name_addr = SocketAddr::from_abstract_name(name)?;
+    ///     let socket = UnixListener::bind_addr(&name_addr)?;
+    ///     let local_addr = socket.local_addr().expect("Couldn't get local address");
+    ///     assert_eq!(local_addr.as_abstract_name(), Some(&name[..]));
+    ///     Ok(())
+    /// }
+    /// ```
+    fn as_abstract_name(&self) -> Option<&[u8]>;
+}
diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs
new file mode 100644
index 0000000000000..318ebacfd7a08
--- /dev/null
+++ b/library/std/src/os/net/linux_ext/mod.rs
@@ -0,0 +1,12 @@
+//! Linux and Android-specific networking functionality.
+
+#![doc(cfg(any(target_os = "linux", target_os = "android")))]
+
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+pub(crate) mod addr;
+
+#[unstable(feature = "tcp_quickack", issue = "96256")]
+pub(crate) mod tcp;
+
+#[cfg(test)]
+mod tests;
diff --git a/library/std/src/os/net/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs
similarity index 100%
rename from library/std/src/os/net/tcp.rs
rename to library/std/src/os/net/linux_ext/tcp.rs
diff --git a/library/std/src/os/net/tests.rs b/library/std/src/os/net/linux_ext/tests.rs
similarity index 88%
rename from library/std/src/os/net/tests.rs
rename to library/std/src/os/net/linux_ext/tests.rs
index 4704e3156913c..2db4deed03630 100644
--- a/library/std/src/os/net/tests.rs
+++ b/library/std/src/os/net/linux_ext/tests.rs
@@ -1,9 +1,8 @@
-#[cfg(any(target_os = "android", target_os = "linux",))]
 #[test]
 fn quickack() {
     use crate::{
         net::{test::next_test_ip4, TcpListener, TcpStream},
-        os::net::tcp::TcpStreamExt,
+        os::net::linux_ext::tcp::TcpStreamExt,
     };
 
     macro_rules! t {
diff --git a/library/std/src/os/net/mod.rs b/library/std/src/os/net/mod.rs
index d6d84d24ec489..5ec267c41e97c 100644
--- a/library/std/src/os/net/mod.rs
+++ b/library/std/src/os/net/mod.rs
@@ -1,7 +1,4 @@
-//! Linux and Android-specific definitions for socket options.
+//! OS-specific networking functionality.
 
-#![unstable(feature = "tcp_quickack", issue = "96256")]
-#![doc(cfg(any(target_os = "linux", target_os = "android",)))]
-pub mod tcp;
-#[cfg(test)]
-mod tests;
+#[cfg(any(target_os = "linux", target_os = "android", doc))]
+pub(super) mod linux_ext;
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 094085e19428c..81ac829d21bc8 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -1,6 +1,9 @@
 use crate::ffi::OsStr;
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+use crate::os::net::linux_ext;
 use crate::os::unix::ffi::OsStrExt;
 use crate::path::Path;
+use crate::sealed::Sealed;
 use crate::sys::cvt;
 use crate::{fmt, io, mem, ptr};
 
@@ -224,31 +227,6 @@ impl SocketAddr {
         if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
     }
 
-    /// Returns the contents of this address if it is an abstract namespace
-    /// without the leading null byte.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// #![feature(unix_socket_abstract)]
-    /// use std::os::unix::net::{UnixListener, SocketAddr};
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let namespace = b"hidden";
-    ///     let namespace_addr = SocketAddr::from_abstract_namespace(&namespace[..])?;
-    ///     let socket = UnixListener::bind_addr(&namespace_addr)?;
-    ///     let local_addr = socket.local_addr().expect("Couldn't get local address");
-    ///     assert_eq!(local_addr.as_abstract_namespace(), Some(&namespace[..]));
-    ///     Ok(())
-    /// }
-    /// ```
-    #[doc(cfg(any(target_os = "android", target_os = "linux")))]
-    #[cfg(any(doc, target_os = "android", target_os = "linux",))]
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
-    pub fn as_abstract_namespace(&self) -> Option<&[u8]> {
-        if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
-    }
-
     fn address(&self) -> AddressKind<'_> {
         let len = self.len as usize - sun_path_offset(&self.addr);
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
@@ -265,62 +243,41 @@ impl SocketAddr {
             AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
         }
     }
+}
 
-    /// Creates an abstract domain socket address from a namespace
-    ///
-    /// An abstract address does not create a file unlike traditional path-based
-    /// Unix sockets. The advantage of this is that the address will disappear when
-    /// the socket bound to it is closed, so no filesystem clean up is required.
-    ///
-    /// The leading null byte for the abstract namespace is automatically added.
-    ///
-    /// This is a Linux-specific extension. See more at [`unix(7)`].
-    ///
-    /// [`unix(7)`]: https://man7.org/linux/man-pages/man7/unix.7.html
-    ///
-    /// # Errors
-    ///
-    /// This will return an error if the given namespace is too long
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// #![feature(unix_socket_abstract)]
-    /// use std::os::unix::net::{UnixListener, SocketAddr};
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let addr = SocketAddr::from_abstract_namespace(b"hidden")?;
-    ///     let listener = match UnixListener::bind_addr(&addr) {
-    ///         Ok(sock) => sock,
-    ///         Err(err) => {
-    ///             println!("Couldn't bind: {err:?}");
-    ///             return Err(err);
-    ///         }
-    ///     };
-    ///     Ok(())
-    /// }
-    /// ```
-    #[doc(cfg(any(target_os = "android", target_os = "linux")))]
-    #[cfg(any(doc, target_os = "android", target_os = "linux",))]
-    #[unstable(feature = "unix_socket_abstract", issue = "85410")]
-    pub fn from_abstract_namespace(namespace: &[u8]) -> io::Result<SocketAddr> {
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+impl Sealed for SocketAddr {}
+
+#[doc(cfg(any(target_os = "android", target_os = "linux")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+impl linux_ext::addr::SocketAddrExt for SocketAddr {
+    fn as_abstract_name(&self) -> Option<&[u8]> {
+        if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
+    }
+
+    fn from_abstract_name<N>(name: &N) -> crate::io::Result<Self>
+    where
+        N: AsRef<[u8]>,
+    {
+        let name = name.as_ref();
         unsafe {
             let mut addr: libc::sockaddr_un = mem::zeroed();
             addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
 
-            if namespace.len() + 1 > addr.sun_path.len() {
+            if name.len() + 1 > addr.sun_path.len() {
                 return Err(io::const_io_error!(
                     io::ErrorKind::InvalidInput,
-                    "namespace must be shorter than SUN_LEN",
+                    "abstract socket name must be shorter than SUN_LEN",
                 ));
             }
 
             crate::ptr::copy_nonoverlapping(
-                namespace.as_ptr(),
+                name.as_ptr(),
                 addr.sun_path.as_mut_ptr().add(1) as *mut u8,
-                namespace.len(),
+                name.len(),
             );
-            let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t;
+            let len = (sun_path_offset(&addr) + 1 + name.len()) as libc::socklen_t;
             SocketAddr::from_parts(addr, len)
         }
     }
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index e4499f9b6a6dc..37fcfa8446b0e 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -7,6 +7,12 @@ use crate::sys_common::io::test::tmpdir;
 use crate::thread;
 use crate::time::Duration;
 
+#[cfg(target_os = "android")]
+use crate::os::android::net::SocketAddrExt;
+
+#[cfg(target_os = "linux")]
+use crate::os::linux::net::SocketAddrExt;
+
 macro_rules! or_panic {
     ($e:expr) => {
         match $e {
@@ -404,7 +410,7 @@ fn test_abstract_stream_connect() {
     let msg1 = b"hello";
     let msg2 = b"world";
 
-    let socket_addr = or_panic!(SocketAddr::from_abstract_namespace(b"namespace"));
+    let socket_addr = or_panic!(SocketAddr::from_abstract_name(b"name"));
     let listener = or_panic!(UnixListener::bind_addr(&socket_addr));
 
     let thread = thread::spawn(move || {
@@ -418,7 +424,7 @@ fn test_abstract_stream_connect() {
     let mut stream = or_panic!(UnixStream::connect_addr(&socket_addr));
 
     let peer = or_panic!(stream.peer_addr());
-    assert_eq!(peer.as_abstract_namespace().unwrap(), b"namespace");
+    assert_eq!(peer.as_abstract_name().unwrap(), b"name");
 
     or_panic!(stream.write_all(msg1));
     let mut buf = vec![];
@@ -432,7 +438,7 @@ fn test_abstract_stream_connect() {
 #[cfg(any(target_os = "android", target_os = "linux"))]
 #[test]
 fn test_abstract_stream_iter() {
-    let addr = or_panic!(SocketAddr::from_abstract_namespace(b"hidden"));
+    let addr = or_panic!(SocketAddr::from_abstract_name(b"hidden"));
     let listener = or_panic!(UnixListener::bind_addr(&addr));
 
     let thread = thread::spawn(move || {
@@ -454,13 +460,13 @@ fn test_abstract_stream_iter() {
 #[cfg(any(target_os = "android", target_os = "linux"))]
 #[test]
 fn test_abstract_datagram_bind_send_to_addr() {
-    let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns1"));
+    let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns1"));
     let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
 
     let local = or_panic!(sock1.local_addr());
-    assert_eq!(local.as_abstract_namespace().unwrap(), b"ns1");
+    assert_eq!(local.as_abstract_name().unwrap(), b"ns1");
 
-    let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns2"));
+    let addr2 = or_panic!(SocketAddr::from_abstract_name(b"ns2"));
     let sock2 = or_panic!(UnixDatagram::bind_addr(&addr2));
 
     let msg = b"hello world";
@@ -469,13 +475,13 @@ fn test_abstract_datagram_bind_send_to_addr() {
     let (len, addr) = or_panic!(sock2.recv_from(&mut buf));
     assert_eq!(msg, &buf[..]);
     assert_eq!(len, 11);
-    assert_eq!(addr.as_abstract_namespace().unwrap(), b"ns1");
+    assert_eq!(addr.as_abstract_name().unwrap(), b"ns1");
 }
 
 #[cfg(any(target_os = "android", target_os = "linux"))]
 #[test]
 fn test_abstract_datagram_connect_addr() {
-    let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns3"));
+    let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns3"));
     let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
 
     let sock = or_panic!(UnixDatagram::unbound());
@@ -489,7 +495,7 @@ fn test_abstract_datagram_connect_addr() {
     assert_eq!(addr.is_unnamed(), true);
     assert_eq!(msg, &buf[..]);
 
-    let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns4"));
+    let addr2 = or_panic!(SocketAddr::from_abstract_name(b"ns4"));
     let bsock2 = or_panic!(UnixDatagram::bind_addr(&addr2));
 
     or_panic!(sock.connect_addr(&addr2));
@@ -499,8 +505,8 @@ fn test_abstract_datagram_connect_addr() {
 
 #[cfg(any(target_os = "android", target_os = "linux"))]
 #[test]
-fn test_abstract_namespace_too_long() {
-    match SocketAddr::from_abstract_namespace(
+fn test_abstract_name_too_long() {
+    match SocketAddr::from_abstract_name(
         b"abcdefghijklmnopqrstuvwxyzabcdefghijklmn\
         opqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi\
         jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
@@ -513,11 +519,11 @@ fn test_abstract_namespace_too_long() {
 
 #[cfg(any(target_os = "android", target_os = "linux"))]
 #[test]
-fn test_abstract_namespace_no_pathname_and_not_unnamed() {
-    let namespace = b"local";
-    let addr = or_panic!(SocketAddr::from_abstract_namespace(&namespace[..]));
+fn test_abstract_no_pathname_and_not_unnamed() {
+    let name = b"local";
+    let addr = or_panic!(SocketAddr::from_abstract_name(name));
     assert_eq!(addr.as_pathname(), None);
-    assert_eq!(addr.as_abstract_namespace(), Some(&namespace[..]));
+    assert_eq!(addr.as_abstract_name(), Some(&name[..]));
     assert_eq!(addr.is_unnamed(), false);
 }
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 091a1ba70cab7..acfbd072121a1 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -674,7 +674,7 @@ impl FromWithTcx<clean::Variant> for Variant {
 impl FromWithTcx<clean::Discriminant> for Discriminant {
     fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
         Discriminant {
-            // expr is only none if going throught the inlineing path, which gets
+            // expr is only none if going through the inlineing path, which gets
             // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
             // the expr is always some.
             expr: disr.expr(tcx).unwrap(),
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index d13efe6c113be..beb7054009138 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -277,7 +277,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
 
         let e = ExternalCrate { crate_num: LOCAL_CRATE };
 
-        // FIXME(adotinthevoid): Remove this, as it's not consistant with not
+        // FIXME(adotinthevoid): Remove this, as it's not consistent with not
         // inlining foreign items.
         let foreign_trait_items = self.get_trait_items();
         let mut index = (*self.index).clone().into_inner();
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index d121a3e2aa4a9..1b373cfe5bb79 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -354,7 +354,14 @@ impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
             self.parent_scope.module = old_module;
         } else {
             match &item.kind {
-                ItemKind::Impl(box ast::Impl { of_trait: Some(..), .. }) => {
+                ItemKind::Impl(box ast::Impl { of_trait: Some(trait_ref), .. }) => {
+                    if let Some(partial_res) = self.resolver.get_partial_res(trait_ref.ref_id)
+                        && let Some(res) = partial_res.full_res()
+                        && let Some(trait_def_id) = res.opt_def_id()
+                        && !trait_def_id.is_local()
+                        && self.visited_mods.insert(trait_def_id) {
+                        self.resolve_doc_links_extern_impl(trait_def_id, false);
+                    }
                     self.all_trait_impls.push(self.resolver.local_def_id(item.id).to_def_id());
                 }
                 ItemKind::MacroDef(macro_def) if macro_def.macro_rules => {
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 4bc91fc4030e2..817b3e484194f 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -53,7 +53,7 @@ pub struct ItemSummary {
     /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
     ///
     /// Note that items can appear in multiple paths, and the one chosen is implementation
-    /// defined. Currenty, this is the full path to where the item was defined. Eg
+    /// defined. Currently, this is the full path to where the item was defined. Eg
     /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
     /// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
     pub path: Vec<String>,
@@ -351,7 +351,7 @@ pub enum Variant {
     /// A variant with unnamed fields.
     ///
     /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
-    /// instead of being ommited, because order matters.
+    /// instead of being omitted, because order matters.
     ///
     /// ```rust
     /// enum Demo {
diff --git a/src/test/rustdoc/intra-doc/issue-104145.rs b/src/test/rustdoc/intra-doc/issue-104145.rs
new file mode 100644
index 0000000000000..9ce36740d60d9
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/issue-104145.rs
@@ -0,0 +1,14 @@
+// Doc links in `Trait`'s methods are resolved because it has a local impl.
+
+// aux-build:issue-103463-aux.rs
+
+extern crate issue_103463_aux;
+use issue_103463_aux::Trait;
+
+pub struct LocalType;
+
+impl Trait for LocalType {
+    fn method() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/chalkify/closure.rs b/src/test/ui/chalkify/closure.rs
index 408e8802d862c..568e2e30c418c 100644
--- a/src/test/ui/chalkify/closure.rs
+++ b/src/test/ui/chalkify/closure.rs
@@ -1,5 +1,3 @@
-// known-bug: unknown
-// FIXME(chalk): Chalk needs support for the Tuple trait
 // compile-flags: -Z chalk
 
 fn main() -> () {
@@ -26,7 +24,7 @@ fn main() -> () {
     let mut c = b;
 
     c();
-    b(); // FIXME: reenable when this is fixed ~ ERROR
+    b(); //~ ERROR
 
     // FIXME(chalk): this doesn't quite work
     /*
diff --git a/src/test/ui/chalkify/closure.stderr b/src/test/ui/chalkify/closure.stderr
index bcee0cab96ae7..a33c0ba0d37c9 100644
--- a/src/test/ui/chalkify/closure.stderr
+++ b/src/test/ui/chalkify/closure.stderr
@@ -1,80 +1,22 @@
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:7:5
-   |
-LL |     t();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:13:5
-   |
-LL |     b();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:17:5
-   |
-LL |     c();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:18:5
+error[E0382]: borrow of moved value: `b`
+  --> $DIR/closure.rs:27:5
    |
+LL |     let mut c = b;
+   |                 - value moved here
+...
 LL |     b();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:24:5
-   |
-LL |     b();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:28:5
-   |
-LL |     c();
-   |     ^^^ the trait `Tuple` is not implemented for `()`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
-
-error[E0277]: `()` is not a tuple
-  --> $DIR/closure.rs:29:5
+   |     ^ value borrowed here after move
    |
-LL |     b(); // FIXME: reenable when this is fixed ~ ERROR
-   |     ^^^ the trait `Tuple` is not implemented for `()`
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
+  --> $DIR/closure.rs:20:9
    |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+LL |         a = 1;
+   |         ^
+help: consider mutably borrowing `b`
    |
-LL | fn main() -> () where (): Tuple {
-   |                 +++++++++++++++
+LL |     let mut c = &mut b;
+   |                 ++++
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/chalkify/trait-objects.rs b/src/test/ui/chalkify/trait-objects.rs
index 30929e943bd7f..d56abc42bf540 100644
--- a/src/test/ui/chalkify/trait-objects.rs
+++ b/src/test/ui/chalkify/trait-objects.rs
@@ -1,5 +1,4 @@
-// known-bug: unknown
-// FIXME(chalk): Chalk needs support for the Tuple trait
+// check-pass
 // compile-flags: -Z chalk
 
 use std::fmt::Display;
diff --git a/src/test/ui/chalkify/trait-objects.stderr b/src/test/ui/chalkify/trait-objects.stderr
deleted file mode 100644
index 422d39742eb55..0000000000000
--- a/src/test/ui/chalkify/trait-objects.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: the type `&dyn Fn(i32) -> _` is not well-formed (chalk)
-  --> $DIR/trait-objects.rs:11:12
-   |
-LL |     let f: &dyn Fn(i32) -> _ = &|x| x + x;
-   |            ^^^^^^^^^^^^^^^^^
-
-error[E0277]: `(i32,)` is not a tuple
-  --> $DIR/trait-objects.rs:12:5
-   |
-LL |     f(2);
-   |     ^^^^ the trait `Tuple` is not implemented for `(i32,)`
-   |
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() where (i32,): Tuple {
-   |           +++++++++++++++++++
-
-error[E0277]: expected a `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32`
-  --> $DIR/trait-objects.rs:12:5
-   |
-LL |     f(2);
-   |     ^^^^ expected an `Fn<(i32,)>` closure, found `dyn Fn(i32) -> i32`
-   |
-   = help: the trait `Fn<(i32,)>` is not implemented for `dyn Fn(i32) -> i32`
-help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
-   |
-LL | fn main() where dyn Fn(i32) -> i32: Fn<(i32,)> {
-   |           ++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
index c25c43692928a..4d7872598b1e7 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy`
+error[E0119]: conflicting implementations of trait `GoMut` for type `MyThingy`
   --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1
    |
 LL | impl GoMut for MyThingy {
diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
index 1110197734f7a..2463f38a92251 100644
--- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
+++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
   --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
    |
 LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
@@ -7,7 +7,7 @@ LL |
 LL | impl<T: MyTrait> !Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
 
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`
+error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
   --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
    |
 LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr
index 86356af256433..d40ffc48a29f9 100644
--- a/src/test/ui/coherence/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence/coherence-impls-copy.stderr
@@ -9,7 +9,7 @@ LL | impl Copy for i32 {}
    |
    = note: define and implement a trait or new type instead
 
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
+error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
   --> $DIR/coherence-impls-copy.rs:28:1
    |
 LL | impl Copy for &'static NotSync {}
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
index 85eb189e10eee..cd398426704cb 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>`
+error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>`
   --> $DIR/coherence-overlap-issue-23516.rs:8:1
    |
 LL | impl<T:Sugar> Sweet for T { }
    | ------------------------- first implementation here
 LL | impl<U:Sugar> Sweet for Box<U> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
    |
    = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
 
diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
index 6492747bb261d..94d242eaac431 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>`
+error[E0119]: conflicting implementations of trait `Foo<_>` for type `Option<_>`
   --> $DIR/coherence-projection-conflict-ty-param.rs:10:1
    |
 LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
    | ---------------------------------------- first implementation here
 LL |
 LL | impl<T, U> Foo<T> for Option<U> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<_>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Option<_>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.stderr b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
index cfcc21240e4eb..89615f0fbc63b 100644
--- a/src/test/ui/coherence/coherence-wasm-bindgen.stderr
+++ b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
@@ -1,11 +1,11 @@
-error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn std::ops::Fn(&_) -> _`
+error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn Fn(&_) -> _`
   --> $DIR/coherence-wasm-bindgen.rs:28:1
    |
 LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b)
    | ------------------------------------------------------------ first implementation here
 ...
 LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b)
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn Fn(&_) -> _`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
index db730650185e3..93486fa5f3605 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>`
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFundamentalStruct<(MyType,)>`
   --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1
    |
 LL | impl<T: lib::MyCopy> MyTrait for T { }
    | ---------------------------------- first implementation here
 ...
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFundamentalStruct<(MyType,)>`
    |
    = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
index 3bc3dffda5d1b..7432733b932a4 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>`
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyStruct<MyType>`
   --> $DIR/coherence_copy_like_err_struct.rs:19:1
    |
 LL | impl<T: lib::MyCopy> MyTrait for T { }
    | ---------------------------------- first implementation here
 ...
 LL | impl MyTrait for lib::MyStruct<MyType> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct<MyType>`
    |
    = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
diff --git a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
index 038a0199a8f27..4ddd712b27c88 100644
--- a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
+++ b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S`
+error[E0119]: conflicting implementations of trait `From<()>` for type `S`
   --> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
    |
 LL | impl From<()> for S {
diff --git a/src/test/ui/consts/invalid-inline-const-in-match-arm.rs b/src/test/ui/consts/invalid-inline-const-in-match-arm.rs
new file mode 100644
index 0000000000000..4d2d8fb1303ce
--- /dev/null
+++ b/src/test/ui/consts/invalid-inline-const-in-match-arm.rs
@@ -0,0 +1,9 @@
+#![allow(incomplete_features)]
+#![feature(inline_const_pat)]
+
+fn main() {
+    match () {
+        const { (|| {})() } => {}
+        //~^ ERROR cannot call non-const closure in constants
+    }
+}
diff --git a/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr b/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
new file mode 100644
index 0000000000000..ab594c921f91a
--- /dev/null
+++ b/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
@@ -0,0 +1,12 @@
+error[E0015]: cannot call non-const closure in constants
+  --> $DIR/invalid-inline-const-in-match-arm.rs:6:17
+   |
+LL |         const { (|| {})() } => {}
+   |                 ^^^^^^^^^
+   |
+   = note: closures need an RFC before allowed to be called in constants
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/error-codes/e0119/conflict-with-std.stderr b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
index 3ff96a6a4d65d..ef888a1c2871e 100644
--- a/src/test/ui/error-codes/e0119/conflict-with-std.stderr
+++ b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`
+error[E0119]: conflicting implementations of trait `AsRef<Q>` for type `Box<Q>`
   --> $DIR/conflict-with-std.rs:5:1
    |
 LL | impl AsRef<Q> for Box<Q> {
@@ -8,7 +8,7 @@ LL | impl AsRef<Q> for Box<Q> {
            - impl<T, A> AsRef<T> for Box<T, A>
              where A: Allocator, T: ?Sized;
 
-error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`
+error[E0119]: conflicting implementations of trait `From<S>` for type `S`
   --> $DIR/conflict-with-std.rs:12:1
    |
 LL | impl From<S> for S {
@@ -17,7 +17,7 @@ LL | impl From<S> for S {
    = note: conflicting implementation in crate `core`:
            - impl<T> From<T> for T;
 
-error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`
+error[E0119]: conflicting implementations of trait `TryFrom<X>` for type `X`
   --> $DIR/conflict-with-std.rs:19:1
    |
 LL | impl TryFrom<X> for X {
diff --git a/src/test/ui/error-codes/e0119/issue-23563.stderr b/src/test/ui/error-codes/e0119/issue-23563.stderr
index f149cef587f25..1b2d64282e1e2 100644
--- a/src/test/ui/error-codes/e0119/issue-23563.stderr
+++ b/src/test/ui/error-codes/e0119/issue-23563.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`
+error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>`
   --> $DIR/issue-23563.rs:13:1
    |
 LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
diff --git a/src/test/ui/error-codes/e0119/issue-27403.stderr b/src/test/ui/error-codes/e0119/issue-27403.stderr
index c11a50487479e..9b3345c23bb23 100644
--- a/src/test/ui/error-codes/e0119/issue-27403.stderr
+++ b/src/test/ui/error-codes/e0119/issue-27403.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`
+error[E0119]: conflicting implementations of trait `Into<_>` for type `GenX<_>`
   --> $DIR/issue-27403.rs:5:1
    |
 LL | impl<S> Into<S> for GenX<S> {
diff --git a/src/test/ui/error-codes/e0119/so-37347311.stderr b/src/test/ui/error-codes/e0119/so-37347311.stderr
index f1c2b0d29742e..99367e808419f 100644
--- a/src/test/ui/error-codes/e0119/so-37347311.stderr
+++ b/src/test/ui/error-codes/e0119/so-37347311.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`
+error[E0119]: conflicting implementations of trait `From<MyError<_>>` for type `MyError<_>`
   --> $DIR/so-37347311.rs:11:1
    |
 LL | impl<S: Storage> From<S::Error> for MyError<S> {
diff --git a/src/test/ui/issues/issue-28568.stderr b/src/test/ui/issues/issue-28568.stderr
index be3f7c627800d..960259080f739 100644
--- a/src/test/ui/issues/issue-28568.stderr
+++ b/src/test/ui/issues/issue-28568.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `MyStruct`
+error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct`
   --> $DIR/issue-28568.rs:7:1
    |
 LL | impl Drop for MyStruct {
diff --git a/src/test/ui/issues/issue-43355.stderr b/src/test/ui/issues/issue-43355.stderr
index 531130fecab1e..57adc8ad5efc6 100644
--- a/src/test/ui/issues/issue-43355.stderr
+++ b/src/test/ui/issues/issue-43355.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`
+error[E0119]: conflicting implementations of trait `Trait1<Box<_>>` for type `A`
   --> $DIR/issue-43355.rs:13:1
    |
 LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
diff --git a/src/test/ui/issues/issue-48728.rs b/src/test/ui/issues/issue-48728.rs
index 8405a30478bde..cbdc10bd2e1ea 100644
--- a/src/test/ui/issues/issue-48728.rs
+++ b/src/test/ui/issues/issue-48728.rs
@@ -1,7 +1,7 @@
 // Regression test for #48728, an ICE that occurred computing
 // coherence "help" information.
 
-#[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone`
+#[derive(Clone)] //~ ERROR conflicting implementations of trait `Clone`
 struct Node<T: ?Sized>(Box<T>);
 
 impl<T: Clone + ?Sized> Clone for Node<[T]> {
diff --git a/src/test/ui/issues/issue-48728.stderr b/src/test/ui/issues/issue-48728.stderr
index 628f026b68046..0bb46724f6166 100644
--- a/src/test/ui/issues/issue-48728.stderr
+++ b/src/test/ui/issues/issue-48728.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Node<[_]>`
+error[E0119]: conflicting implementations of trait `Clone` for type `Node<[_]>`
   --> $DIR/issue-48728.rs:4:10
    |
 LL | #[derive(Clone)]
diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
index 2cc4d382d9df9..553ab3869b338 100644
--- a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
+++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
@@ -1,36 +1,36 @@
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
    |
 LL | impl Foo for dyn Send {}
    | --------------------- first implementation here
 LL |
 LL | impl Foo for dyn Send + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
    = note: `#[deny(order_dependent_trait_objects)]` on by default
 
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
    |
 LL | impl Foo for dyn Send + Sync {}
    | ---------------------------- first implementation here
 LL |
 LL | impl Foo for dyn Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
    |
 LL | impl Foo for dyn Sync + Send {}
    | ---------------------------- first implementation here
 ...
 LL | impl Foo for dyn Send + Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -38,42 +38,42 @@ LL | impl Foo for dyn Send + Sync + Send {}
 error: aborting due to 3 previous errors
 
 Future incompatibility report: Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
    |
 LL | impl Foo for dyn Send {}
    | --------------------- first implementation here
 LL |
 LL | impl Foo for dyn Send + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
    = note: `#[deny(order_dependent_trait_objects)]` on by default
 
 Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
    |
 LL | impl Foo for dyn Send + Sync {}
    | ---------------------------- first implementation here
 LL |
 LL | impl Foo for dyn Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
    = note: `#[deny(order_dependent_trait_objects)]` on by default
 
 Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
    |
 LL | impl Foo for dyn Sync + Send {}
    | ---------------------------- first implementation here
 ...
 LL | impl Foo for dyn Send + Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/parser/recover-fn-ptr-with-generics.rs b/src/test/ui/parser/recover-fn-ptr-with-generics.rs
new file mode 100644
index 0000000000000..31de418be5f70
--- /dev/null
+++ b/src/test/ui/parser/recover-fn-ptr-with-generics.rs
@@ -0,0 +1,31 @@
+fn main() {
+    type Predicate = fn<'a>(&'a str) -> bool;
+    //~^ ERROR function pointer types may not have generic parameters
+
+    type Identity = fn<T>(T) -> T;
+    //~^ ERROR function pointer types may not have generic parameters
+    //~| ERROR cannot find type `T` in this scope
+    //~| ERROR cannot find type `T` in this scope
+
+    let _: fn<const N: usize, 'e, Q, 'f>();
+    //~^ ERROR function pointer types may not have generic parameters
+
+    let _: for<'outer> fn<'inner>();
+    //~^ ERROR function pointer types may not have generic parameters
+
+    let _: for<> fn<'r>();
+    //~^ ERROR function pointer types may not have generic parameters
+
+    type Hmm = fn<>();
+    //~^ ERROR function pointer types may not have generic parameters
+
+    let _: extern fn<'a: 'static>();
+    //~^ ERROR function pointer types may not have generic parameters
+    //~| ERROR lifetime bounds cannot be used in this context
+
+    let _: for<'any> extern "C" fn<'u>();
+    //~^ ERROR function pointer types may not have generic parameters
+
+    type QuiteBroken = fn<const>();
+    //~^ ERROR expected identifier, found `>`
+}
diff --git a/src/test/ui/parser/recover-fn-ptr-with-generics.stderr b/src/test/ui/parser/recover-fn-ptr-with-generics.stderr
new file mode 100644
index 0000000000000..1da9c18571b9e
--- /dev/null
+++ b/src/test/ui/parser/recover-fn-ptr-with-generics.stderr
@@ -0,0 +1,111 @@
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:2:24
+   |
+LL |     type Predicate = fn<'a>(&'a str) -> bool;
+   |                        ^^^^
+   |
+help: consider moving the lifetime parameter to a `for` parameter list
+   |
+LL -     type Predicate = fn<'a>(&'a str) -> bool;
+LL +     type Predicate = for<'a> fn(&'a str) -> bool;
+   |
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:5:23
+   |
+LL |     type Identity = fn<T>(T) -> T;
+   |                       ^^^
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:10:14
+   |
+LL |     let _: fn<const N: usize, 'e, Q, 'f>();
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider moving the lifetime parameters to a `for` parameter list
+   |
+LL -     let _: fn<const N: usize, 'e, Q, 'f>();
+LL +     let _: for<'e, 'f> fn();
+   |
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:13:26
+   |
+LL |     let _: for<'outer> fn<'inner>();
+   |                          ^^^^^^^^
+   |
+help: consider moving the lifetime parameter to the `for` parameter list
+   |
+LL -     let _: for<'outer> fn<'inner>();
+LL +     let _: for<'outer, 'inner> fn();
+   |
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:16:20
+   |
+LL |     let _: for<> fn<'r>();
+   |                    ^^^^
+   |
+help: consider moving the lifetime parameter to the `for` parameter list
+   |
+LL -     let _: for<> fn<'r>();
+LL +     let _: for<'r> fn();
+   |
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:19:18
+   |
+LL |     type Hmm = fn<>();
+   |                  ^^
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:22:21
+   |
+LL |     let _: extern fn<'a: 'static>();
+   |                     ^^^^^^^^^^^^^
+   |
+help: consider moving the lifetime parameter to a `for` parameter list
+   |
+LL -     let _: extern fn<'a: 'static>();
+LL +     let _: for<'a> extern fn();
+   |
+
+error: function pointer types may not have generic parameters
+  --> $DIR/recover-fn-ptr-with-generics.rs:26:35
+   |
+LL |     let _: for<'any> extern "C" fn<'u>();
+   |                                   ^^^^
+   |
+help: consider moving the lifetime parameter to the `for` parameter list
+   |
+LL -     let _: for<'any> extern "C" fn<'u>();
+LL +     let _: for<'any, 'u> extern "C" fn();
+   |
+
+error: expected identifier, found `>`
+  --> $DIR/recover-fn-ptr-with-generics.rs:29:32
+   |
+LL |     type QuiteBroken = fn<const>();
+   |                                ^ expected identifier
+
+error: lifetime bounds cannot be used in this context
+  --> $DIR/recover-fn-ptr-with-generics.rs:22:26
+   |
+LL |     let _: extern fn<'a: 'static>();
+   |                          ^^^^^^^
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/recover-fn-ptr-with-generics.rs:5:27
+   |
+LL |     type Identity = fn<T>(T) -> T;
+   |                           ^ not found in this scope
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/recover-fn-ptr-with-generics.rs:5:33
+   |
+LL |     type Identity = fn<T>(T) -> T;
+   |                                 ^ not found in this scope
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
index f515ec198adaa..36a09add4d3bb 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
@@ -10,7 +10,7 @@ LL | impl const std::ops::Add for i32 {
    |
    = note: define and implement a trait or new type instead
 
-error[E0119]: conflicting implementations of trait `std::ops::Add` for type `Int`
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
   --> $DIR/const-and-non-const-impl.rs:22:1
    |
 LL | impl std::ops::Add for Int {
diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr
index fb3d9723aff86..1fe4869ff548d 100644
--- a/src/test/ui/specialization/specialization-overlap-negative.stderr
+++ b/src/test/ui/specialization/specialization-overlap-negative.stderr
@@ -8,7 +8,7 @@ LL | #![feature(specialization)]
    = help: consider using `min_specialization` instead, which is more stable and complete
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
   --> $DIR/specialization-overlap-negative.rs:9:1
    |
 LL | unsafe impl<T: Clone> Send for TestType<T> {}
diff --git a/src/test/ui/specialization/specialization-overlap.stderr b/src/test/ui/specialization/specialization-overlap.stderr
index 98926446765aa..098bf4a70ab48 100644
--- a/src/test/ui/specialization/specialization-overlap.stderr
+++ b/src/test/ui/specialization/specialization-overlap.stderr
@@ -8,13 +8,13 @@ LL | #![feature(specialization)]
    = help: consider using `min_specialization` instead, which is more stable and complete
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>`
+error[E0119]: conflicting implementations of trait `Foo` for type `Vec<_>`
   --> $DIR/specialization-overlap.rs:5:1
    |
 LL | impl<T: Clone> Foo for T {}
    | ------------------------ first implementation here
 LL | impl<T> Foo for Vec<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::vec::Vec<_>`
+   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec<_>`
 
 error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`
   --> $DIR/specialization-overlap.rs:9:1
diff --git a/src/test/ui/traits/issue-33140-hack-boundaries.stderr b/src/test/ui/traits/issue-33140-hack-boundaries.stderr
index 58286648d4feb..80a502c6335e2 100644
--- a/src/test/ui/traits/issue-33140-hack-boundaries.stderr
+++ b/src/test/ui/traits/issue-33140-hack-boundaries.stderr
@@ -1,12 +1,12 @@
-error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:18:1
    |
 LL | impl Trait1 for dyn Send {}
    | ------------------------ first implementation here
 LL | impl Trait1 for dyn Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
 
-error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
+error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn Send + 'static)`:
   --> $DIR/issue-33140-hack-boundaries.rs:25:1
    |
 LL | impl Trait2 for dyn Send {}
@@ -14,21 +14,21 @@ LL | impl Trait2 for dyn Send {}
 LL | impl !Trait2 for dyn Send {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
 
-error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait3<(dyn Sync + 'static)>` for type `(dyn Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:32:1
    |
 LL | impl Trait3<dyn Sync> for dyn Send {}
    | ---------------------------------- first implementation here
 LL | impl Trait3<dyn Sync> for dyn Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
 
-error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:39:1
    |
 LL | impl<T: ?Sized> Trait4a for T {}
    | ----------------------------- first implementation here
 LL | impl Trait4a for dyn Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
 
 error[E0119]: conflicting implementations of trait `Trait4b` for type `()`
   --> $DIR/issue-33140-hack-boundaries.rs:46:1
@@ -38,42 +38,42 @@ LL | impl Trait4b for () {}
 LL | impl Trait4b for () {}
    | ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
 
-error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:53:1
    |
 LL | impl Trait4c for dyn Trait1 + Send {}
    | ---------------------------------- first implementation here
 LL | impl Trait4c for dyn Trait1 + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + Send + 'static)`
 
-error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`
+error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn Send`
   --> $DIR/issue-33140-hack-boundaries.rs:60:1
    |
 LL | impl<'a> Trait4d for dyn Send + 'a {}
    | ---------------------------------- first implementation here
 LL | impl<'a> Trait4d for dyn Send + 'a {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn Send`
 
-error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:67:1
    |
 LL | impl Trait5 for dyn Send {}
    | ------------------------ first implementation here
 LL | impl Trait5 for dyn Send where u32: Copy {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
 
 error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0119, E0751.
 For more information about an error, try `rustc --explain E0119`.
 Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait0` for type `(dyn std::marker::Send + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`: (E0119)
   --> $DIR/issue-33140-hack-boundaries.rs:10:1
    |
 LL | impl Trait0 for dyn Send {}
    | ------------------------ first implementation here
 LL | impl Trait0 for dyn Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/traits/issue-33140.stderr b/src/test/ui/traits/issue-33140.stderr
index 392c56a282d7e..d31281f7256e0 100644
--- a/src/test/ui/traits/issue-33140.stderr
+++ b/src/test/ui/traits/issue-33140.stderr
@@ -1,20 +1,20 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
+error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
   --> $DIR/issue-33140.rs:9:1
    |
 LL | impl Trait for dyn Send + Sync {
    | ------------------------------ first implementation here
 ...
 LL | impl Trait for dyn Sync + Send {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
 
-error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
+error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn Send + Sync + 'static)`
   --> $DIR/issue-33140.rs:22:1
    |
 LL | impl Trait2 for dyn Send + Sync {
    | ------------------------------- first implementation here
 ...
 LL | impl Trait2 for dyn Sync + Send + Sync {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
 
 error[E0592]: duplicate definitions with name `abc`
   --> $DIR/issue-33140.rs:29:5
diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
index d7039e3db6bde..a87acb1fb0976 100644
--- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
+++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`:
+error[E0751]: found both positive and negative implementation of trait `Clone` for type `&mut MyType<'_>`:
   --> $DIR/pin-unsound-issue-66544-clone.rs:7:1
    |
 LL | impl<'a> Clone for &'a mut MyType<'a> {
diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
index a0b62a8bab68f..9185e8f8430bf 100644
--- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
+++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`:
+error[E0751]: found both positive and negative implementation of trait `DerefMut` for type `&MyType<'_>`:
   --> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1
    |
 LL | impl<'a> DerefMut for &'a MyType<'a> {
diff --git a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
index 0af4df2aecb28..525401f9d69ec 100644
--- a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
+++ b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
@@ -1,10 +1,10 @@
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:86:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
    | ------------------------------------------------------ first implementation here
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -14,26 +14,26 @@ note: the lint level is defined here
 LL | #![warn(order_dependent_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:89:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
    | ------------------------------------------------------------- first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:93:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    | ------------------------------------------------------ first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -41,13 +41,13 @@ LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
 warning: 3 warnings emitted
 
 Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:86:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
    | ------------------------------------------------------ first implementation here
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -58,14 +58,14 @@ LL | #![warn(order_dependent_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:89:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
    | ------------------------------------------------------------- first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -76,14 +76,14 @@ LL | #![warn(order_dependent_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
   --> $DIR/issue-33140-traitobject-crate.rs:93:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    | ------------------------------------------------------ first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
index 910c5e29dac0e..e24ed695dc55c 100644
--- a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
+++ b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `MyStruct`
+error[E0119]: conflicting implementations of trait `Send` for type `MyStruct`
   --> $DIR/overlap-not-permitted-for-builtin-trait.rs:7:1
    |
 LL | impl !Send for MyStruct {}
diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs
index 9187c3551d7de..02c364dabf960 100644
--- a/src/tools/x/src/main.rs
+++ b/src/tools/x/src/main.rs
@@ -8,7 +8,8 @@
 //! `x.py`, in that order of preference.
 
 use std::{
-    env, io,
+    env::{self, consts::EXE_EXTENSION},
+    io,
     process::{self, Command, ExitStatus},
 };
 
@@ -27,12 +28,12 @@ fn python() -> &'static str {
 
     for dir in env::split_paths(&val) {
         // `python` should always take precedence over python2 / python3 if it exists
-        if dir.join(PYTHON).exists() {
+        if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() {
             return PYTHON;
         }
 
-        python2 |= dir.join(PYTHON2).exists();
-        python3 |= dir.join(PYTHON3).exists();
+        python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
+        python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
     }
 
     // try 3 before 2