about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0045.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0092.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0161.md7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0579.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0622.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0743.md2
-rw-r--r--compiler/rustc_hir_analysis/src/check/expr.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/inherited.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs19
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs13
-rw-r--r--compiler/rustc_transmute/src/lib.rs15
-rw-r--r--library/core/src/slice/raw.rs24
-rw-r--r--library/core/src/str/traits.rs14
-rw-r--r--src/librustdoc/clean/mod.rs9
-rw-r--r--src/librustdoc/clean/simplify.rs39
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css7
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css12
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css9
-rw-r--r--src/librustdoc/html/static/css/themes/light.css5
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html1
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html1
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs40
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs40
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102571.rs24
-rw-r--r--src/test/ui/impl-trait/in-trait/issue-102571.stderr14
-rw-r--r--src/test/ui/transmutability/issue-101739-1.rs21
-rw-r--r--src/test/ui/transmutability/issue-101739-1.stderr16
-rw-r--r--src/test/ui/transmutability/issue-101739-2.rs37
-rw-r--r--src/test/ui/transmutability/issue-101739-2.stderr20
31 files changed, 325 insertions, 86 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0045.md b/compiler/rustc_error_codes/src/error_codes/E0045.md
index 143c693bf7c..1cb214531e8 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0045.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0045.md
@@ -3,9 +3,7 @@ Variadic parameters have been used on a non-C ABI function.
 Erroneous code example:
 
 ```compile_fail,E0045
-#![feature(unboxed_closures)]
-
-extern "rust-call" {
+extern "Rust" {
     fn foo(x: u8, ...); // error!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index 496174b28ef..5cbe2a188b0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
@@ -19,6 +19,6 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
-    fn atomic_fence(); // ok!
+    fn atomic_fence_seqcst(); // ok!
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md
index ebd2c97698b..643990ef1c7 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0161.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0161.md
@@ -3,7 +3,6 @@ A value was moved whose size was not known at compile time.
 Erroneous code example:
 
 ```compile_fail,E0161
-#![feature(box_syntax)]
 trait Bar {
     fn f(self);
 }
@@ -13,7 +12,7 @@ impl Bar for i32 {
 }
 
 fn main() {
-    let b: Box<dyn Bar> = box (0 as i32);
+    let b: Box<dyn Bar> = Box::new(0i32);
     b.f();
     // error: cannot move a value of type dyn Bar: the size of dyn Bar cannot
     //        be statically determined
@@ -27,8 +26,6 @@ either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
 it around as usual. Example:
 
 ```
-#![feature(box_syntax)]
-
 trait Bar {
     fn f(&self);
 }
@@ -38,7 +35,7 @@ impl Bar for i32 {
 }
 
 fn main() {
-    let b: Box<dyn Bar> = box (0 as i32);
+    let b: Box<dyn Bar> = Box::new(0i32);
     b.f();
     // ok!
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md
index f554242a3d4..e7e6fb68256 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0579.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0579.md
@@ -8,9 +8,9 @@ Erroneous code example:
 fn main() {
     match 5u32 {
         // This range is ok, albeit pointless.
-        1 .. 2 => {}
+        1..2 => {}
         // This range is empty, and the compiler can tell.
-        5 .. 5 => {} // error!
+        5..5 => {} // error!
     }
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md
index 990a2549412..3ba3ed10e5c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0622.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0622.md
@@ -5,7 +5,7 @@ Erroneous code example:
 ```compile_fail,E0622
 #![feature(intrinsics)]
 extern "rust-intrinsic" {
-    pub static breakpoint : fn(); // error: intrinsic must be a function
+    pub static breakpoint: fn(); // error: intrinsic must be a function
 }
 
 fn main() { unsafe { breakpoint(); } }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0743.md b/compiler/rustc_error_codes/src/error_codes/E0743.md
index ddd3136df0c..a19d3ef96e9 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0743.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0743.md
@@ -3,8 +3,6 @@ The C-variadic type `...` has been nested inside another type.
 Erroneous code example:
 
 ```compile_fail,E0743
-#![feature(c_variadic)]
-
 fn foo2(x: u8, y: &...) {} // error!
 ```
 
diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs
index 09362eab673..b9459887c46 100644
--- a/compiler/rustc_hir_analysis/src/check/expr.rs
+++ b/compiler/rustc_hir_analysis/src/check/expr.rs
@@ -542,7 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // been resolved or we errored. This is important as we can only check transmute
                 // on concrete types, but the output type may not be known yet (it would only
                 // be known if explicitly specified via turbofish).
-                self.deferred_transmute_checks.borrow_mut().push((from, to, expr.span));
+                self.deferred_transmute_checks.borrow_mut().push((from, to, expr.hir_id));
             }
             if !tcx.features().unsized_fn_params {
                 // We want to remove some Sized bounds from std functions,
diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
index 55902aafb35..44d7973d632 100644
--- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
@@ -50,8 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(in super::super) fn check_transmutes(&self) {
         let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut();
         debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len());
-        for (from, to, span) in deferred_transmute_checks.drain(..) {
-            self.check_transmute(span, from, to);
+        for (from, to, hir_id) in deferred_transmute_checks.drain(..) {
+            self.check_transmute(from, to, hir_id);
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/inherited.rs b/compiler/rustc_hir_analysis/src/check/inherited.rs
index 37c830d4e38..2546227e138 100644
--- a/compiler/rustc_hir_analysis/src/check/inherited.rs
+++ b/compiler/rustc_hir_analysis/src/check/inherited.rs
@@ -55,7 +55,7 @@ pub struct Inherited<'a, 'tcx> {
 
     pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,
 
-    pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, Span)>>,
+    pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, hir::HirId)>>,
 
     pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>,
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index c604c8af8d2..13a80030415 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -1,3 +1,4 @@
+use hir::HirId;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
@@ -6,7 +7,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
 use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy};
 use rustc_session::lint;
-use rustc_span::{Span, Symbol, DUMMY_SP};
+use rustc_span::{Symbol, DUMMY_SP};
 use rustc_target::abi::{Pointer, VariantIdx};
 use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
 
@@ -40,11 +41,13 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
+    pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
+        let tcx = self.tcx;
+        let span = tcx.hir().span(hir_id);
         let convert = |ty: Ty<'tcx>| {
             let ty = self.resolve_vars_if_possible(ty);
-            let ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
-            (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty)
+            let ty = tcx.normalize_erasing_regions(self.param_env, ty);
+            (SizeSkeleton::compute(ty, tcx, self.param_env), ty)
         };
         let (sk_from, from) = convert(from);
         let (sk_to, to) = convert(to);
@@ -57,9 +60,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Special-case transmuting from `typeof(function)` and
             // `Option<typeof(function)>` to present a clearer error.
-            let from = unpack_option_like(self.tcx, from);
-            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&self.tcx) {
-                struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type")
+            let from = unpack_option_like(tcx, from);
+            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&tcx) {
+                struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type")
                     .note(&format!("source type: {from}"))
                     .note(&format!("target type: {to}"))
                     .help("cast with `as` to a pointer instead")
@@ -83,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let mut err = struct_span_err!(
-            self.tcx.sess,
+            tcx.sess,
             span,
             E0512,
             "cannot transmute between types of different sizes, \
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index f69ac076820..82d7c0a97cb 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -927,7 +927,7 @@ pub trait PrettyPrinter<'tcx>:
                         // unless we can find out what generator return type it comes from.
                         let term = if let Some(ty) = term.skip_binder().ty()
                             && let ty::Projection(proj) = ty.kind()
-                            && let assoc = tcx.associated_item(proj.item_def_id)
+                            && let Some(assoc) = tcx.opt_associated_item(proj.item_def_id)
                             && assoc.trait_container(tcx) == tcx.lang_items().gen_trait()
                             && assoc.name == rustc_span::sym::Return
                         {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index dd49dcecf77..5c8a76401d2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -11,9 +11,10 @@ use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_infer::infer::InferOk;
 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
-use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
-use rustc_middle::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
-use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
+use rustc_middle::ty::{
+    self, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef,
+    ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
+};
 use rustc_span::def_id::DefId;
 
 use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
@@ -289,8 +290,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let scope = type_at(2).skip_binder();
 
-        let assume =
-            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3));
+        let Some(assume) =
+            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)) else {
+                return Err(Unimplemented);
+            };
 
         let cause = obligation.cause.clone();
 
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 64cd70d3678..51f2eb8606a 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -115,7 +115,7 @@ mod rustc {
             tcx: TyCtxt<'tcx>,
             param_env: ParamEnv<'tcx>,
             c: Const<'tcx>,
-        ) -> Self {
+        ) -> Option<Self> {
             use rustc_middle::ty::ScalarInt;
             use rustc_middle::ty::TypeVisitable;
             use rustc_span::symbol::sym;
@@ -123,10 +123,15 @@ mod rustc {
             let c = c.eval(tcx, param_env);
 
             if let Some(err) = c.error_reported() {
-                return Self { alignment: true, lifetimes: true, safety: true, validity: true };
+                return Some(Self {
+                    alignment: true,
+                    lifetimes: true,
+                    safety: true,
+                    validity: true,
+                });
             }
 
-            let adt_def = c.ty().ty_adt_def().expect("The given `Const` must be an ADT.");
+            let adt_def = c.ty().ty_adt_def()?;
 
             assert_eq!(
                 tcx.require_lang_item(LangItem::TransmuteOpts, None),
@@ -148,12 +153,12 @@ mod rustc {
                 fields[field_idx].unwrap_leaf() == ScalarInt::TRUE
             };
 
-            Self {
+            Some(Self {
                 alignment: get_field(sym::alignment),
                 lifetimes: get_field(sym::lifetimes),
                 safety: get_field(sym::safety),
                 validity: get_field(sym::validity),
-            }
+            })
         }
     }
 }
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index f1e8bc79bf4..3c5abd215a4 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -188,6 +188,10 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
 ///
 /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements.
 ///
+/// # Panics
+///
+/// This function panics if `T` is a Zero-Sized Type (“ZST”).
+///
 /// # Caveat
 ///
 /// The lifetime for the returned slice is inferred from its usage. To
@@ -219,9 +223,15 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
     unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
 }
 
-/// Performs the same functionality as [`from_ptr_range`], except that a
+/// Forms a mutable slice from a pointer range.
+///
+/// This is the same functionality as [`from_ptr_range`], except that a
 /// mutable slice is returned.
 ///
+/// This function is useful for interacting with foreign interfaces which
+/// use two pointers to refer to a range of elements in memory, as is
+/// common in C++.
+///
 /// # Safety
 ///
 /// Behavior is undefined if any of the following conditions are violated:
@@ -247,6 +257,18 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
 ///
 /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements.
 ///
+/// # Panics
+///
+/// This function panics if `T` is a Zero-Sized Type (“ZST”).
+///
+/// # Caveat
+///
+/// The lifetime for the returned slice is inferred from its usage. To
+/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
+/// source lifetime is safe in the context, such as by providing a helper
+/// function taking the lifetime of a host value for the slice, or by explicit
+/// annotation.
+///
 /// # Examples
 ///
 /// ```
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 18f2ce6edc7..d3ed811b157 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -507,7 +507,6 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 ///
 /// ```
 /// use std::str::FromStr;
-/// use std::num::ParseIntError;
 ///
 /// #[derive(Debug, PartialEq)]
 /// struct Point {
@@ -515,18 +514,21 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 ///     y: i32
 /// }
 ///
+/// #[derive(Debug, PartialEq, Eq)]
+/// struct ParsePointError;
+///
 /// impl FromStr for Point {
-///     type Err = ParseIntError;
+///     type Err = ParsePointError;
 ///
 ///     fn from_str(s: &str) -> Result<Self, Self::Err> {
 ///         let (x, y) = s
 ///             .strip_prefix('(')
 ///             .and_then(|s| s.strip_suffix(')'))
 ///             .and_then(|s| s.split_once(','))
-///             .unwrap();
+///             .ok_or(ParsePointError)?;
 ///
-///         let x_fromstr = x.parse::<i32>()?;
-///         let y_fromstr = y.parse::<i32>()?;
+///         let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?;
+///         let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?;
 ///
 ///         Ok(Point { x: x_fromstr, y: y_fromstr })
 ///     }
@@ -538,6 +540,8 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
 /// // Implicit calls, through parse
 /// assert_eq!("(1,2)".parse(), expected);
 /// assert_eq!("(1,2)".parse::<Point>(), expected);
+/// // Invalid input string
+/// assert!(Point::from_str("(1 2)").is_err());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr: Sized {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 704292c1048..c61175ecebf 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1176,6 +1176,15 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
             }
 
             if let ty::TraitContainer = assoc_item.container {
+                // FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs,
+                //                e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in
+                //                `type Assoc<T: Copy> where T: Display`. This also means that we
+                //                later incorrectly render `where T: ?Sized`.
+                //
+                //                The result of `tcx.explicit_predicates_of` *does* contain them but
+                //                it does not contain the other bounds / predicates we need.
+                //                Either merge those two interned lists somehow or refactor
+                //                `clean_ty_generics` to call `explicit_item_bounds` by itself.
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
                 let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
                 let mut generics =
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index af7813a7740..f82ea8969ab 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -14,7 +14,6 @@
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty;
-use rustc_span::Symbol;
 
 use crate::clean;
 use crate::clean::GenericArgs as PP;
@@ -26,21 +25,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     //
     // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to
     // the order of the generated bounds.
-    let mut params: FxIndexMap<Symbol, (Vec<_>, Vec<_>)> = FxIndexMap::default();
+    let mut tybounds = FxIndexMap::default();
     let mut lifetimes = Vec::new();
     let mut equalities = Vec::new();
-    let mut tybounds = Vec::new();
 
     for clause in clauses {
         match clause {
-            WP::BoundPredicate { ty, bounds, bound_params } => match ty {
-                clean::Generic(s) => {
-                    let (b, p) = params.entry(s).or_default();
-                    b.extend(bounds);
-                    p.extend(bound_params);
-                }
-                t => tybounds.push((t, (bounds, bound_params))),
-            },
+            WP::BoundPredicate { ty, bounds, bound_params } => {
+                let (b, p): &mut (Vec<_>, Vec<_>) = tybounds.entry(ty).or_default();
+                b.extend(bounds);
+                p.extend(bound_params);
+            }
             WP::RegionPredicate { lifetime, bounds } => {
                 lifetimes.push((lifetime, bounds));
             }
@@ -49,14 +44,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     }
 
     // Look for equality predicates on associated types that can be merged into
-    // general bound predicates
+    // general bound predicates.
     equalities.retain(|&(ref lhs, ref rhs)| {
-        let Some((self_, trait_did, name)) = lhs.projection() else {
-            return true;
-        };
-        let clean::Generic(generic) = self_ else { return true };
-        let Some((bounds, _)) = params.get_mut(generic) else { return true };
-
+        let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
+        // FIXME(fmease): We don't handle HRTBs correctly here.
+        //                Pass `_bound_params` (higher-rank lifetimes) to a modified version of
+        //                `merge_bounds`. That vector is currently always empty though since we
+        //                don't keep track of late-bound lifetimes when cleaning projection
+        //                predicates to cleaned equality predicates while we should first query
+        //                them with `collect_referenced_late_bound_regions` and then store them
+        //                (or something similar). For prior art, see `clean::auto_trait`.
+        let Some((bounds, _bound_params)) = tybounds.get_mut(ty) else { return true };
         merge_bounds(cx, bounds, trait_did, name, rhs)
     });
 
@@ -65,11 +63,6 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses.extend(
         lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
     );
-    clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate {
-        ty: clean::Generic(k),
-        bounds,
-        bound_params: params,
-    }));
     clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate {
         ty,
         bounds,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 45433fd9b65..5f034723c33 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1050,6 +1050,13 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	margin-bottom: 5px;
 	font-size: 0.875rem;
 	font-weight: normal;
+	color: var(--main-color);
+	background-color: var(--stab-background-color);
+}
+
+.stab.portability > code {
+	background: none;
+	color: var(--stab-code-color);
 }
 
 .stab .emoji {
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 1c317aa7cfe..219e6509d20 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -37,6 +37,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--link-color: #39afd7;
 	--sidebar-link-color: #53b1db;
 	--sidebar-current-link-background-color: transparent;
+	--stab-background-color: #314559;
+	--stab-code-color: #e6e1cf;
 }
 
 .slider {
@@ -155,16 +157,6 @@ details.rustdoc-toggle > summary::before {
 	color: #000;
 }
 
-.stab {
-	color: #c5c5c5;
-	background: #314559 !important;
-}
-
-.stab.portability > code {
-	color: #e6e1cf;
-	background: none;
-}
-
 .result-name .primitive > i, .result-name .keyword > i {
 	color: #788797;
 }
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index a8204eebe54..0b598db82ee 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -32,6 +32,8 @@
 	--link-color: #d2991d;
 	--sidebar-link-color: #fdbf35;
 	--sidebar-current-link-background-color: #444;
+	--stab-background-color: #314559;
+	--stab-code-color: #e6e1cf;
 }
 
 .slider {
@@ -114,13 +116,6 @@ details.rustdoc-toggle > summary::before {
 	filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
 }
 
-.stab { background: #314559; }
-
-.stab.portability > code {
-	color: #e6e1cf;
-	background: none;
-}
-
 .src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 8fb60b6f887..fe1cf10bc2f 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -32,6 +32,8 @@
 	--link-color: #3873ad;
 	--sidebar-link-color: #356da4;
 	--sidebar-current-link-background-color: #fff;
+	--stab-background-color: #fff5d6;
+	--stab-code-color: #000;
 }
 
 .slider {
@@ -102,9 +104,6 @@ body.source .example-wrap pre.rust a {
 	filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
 }
 
-.stab { background: #FFF5D6; border-color: #FFC600; }
-.stab.portability > code { background: none; }
-
 .src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
new file mode 100644
index 00000000000..927a1a42a1f
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds_with_bindings/trait.Support.html" title="trait assoc_item_trait_bounds_with_bindings::Support">Support</a>&lt;Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt;</h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html
new file mode 100644
index 00000000000..69d84e1b2c1
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out9" class="associatedtype">Out9</a>: <a class="trait" href="{{channel}}/core/ops/function/trait.FnMut.html" title="trait core::ops::function::FnMut">FnMut</a>(<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>) -&gt; <a class="primitive" href="{{channel}}/std/primitive.bool.html">bool</a> + <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a></h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
new file mode 100644
index 00000000000..b026f399a56
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
@@ -0,0 +1,40 @@
+// Regression test for issues #77763, #84579 and #102142.
+#![crate_name = "main"]
+
+// aux-build:assoc_item_trait_bounds_with_bindings.rs
+// build-aux-docs
+// ignore-cross-compile
+extern crate assoc_item_trait_bounds_with_bindings as aux;
+
+// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters
+//                of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed.
+// FIXME(fmease): Print the `for<>` parameter list in the bounds of
+//                `Main::Out{6,11,12}`.
+
+// @has main/trait.Main.html
+// @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>'
+// @has - '//*[@id="associatedtype.Out1"]' 'type Out1: Support<Item = Self::Item>'
+// @has - '//*[@id="associatedtype.Out2"]' 'type Out2<T>: Support<Item = T>'
+// @has - '//*[@id="associatedtype.Out3"]' 'type Out3: Support<Produce<()> = bool>'
+// @has - '//*[@id="associatedtype.Out4"]' 'type Out4<T>: Support<Produce<T> = T>'
+// @has - '//*[@id="associatedtype.Out5"]' "type Out5: Support<Output<'static> = &'static ()>"
+// @has - '//*[@id="associatedtype.Out6"]' "type Out6: Support<Output<'a> = &'a ()>"
+// @has - '//*[@id="associatedtype.Out7"]' "type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated"
+// @has - '//*[@id="associatedtype.Out8"]' "type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>"
+// @has - '//*[@id="associatedtype.Out9"]' "type Out9: FnMut(i32) -> bool + Clone"
+// @has - '//*[@id="associatedtype.Out10"]' "type Out10<'q>: Support<Output<'q> = ()>"
+// @has - '//*[@id="associatedtype.Out11"]' "type Out11: Helper<A<'s> = &'s (), B<'r> = ()>"
+// @has - '//*[@id="associatedtype.Out12"]' "type Out12: Helper<B<'w> = Cow<'w, str>, A<'w> = bool>"
+//
+// Snapshots: Check that we do not render any where-clauses for those associated types since all of
+// the trait bounds contained within were moved to the bounds of the respective item.
+//
+// @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]'
+// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
+//
+// @has - '//*[@id="tymethod.make"]' \
+// "fn make<F>(F, impl FnMut(&str) -> bool)\
+// where \
+//     F: FnOnce(u32) -> String, \
+//     Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>"
+pub use aux::Main;
diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
new file mode 100644
index 00000000000..7225f2dca10
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
@@ -0,0 +1,40 @@
+pub trait Main {
+    type Item;
+
+    type Out0: Support<Item = ()>;
+    type Out1: Support<Item = Self::Item>;
+    type Out2<T>: Support<Item = T>;
+    type Out3: Support<Produce<()> = bool>;
+    type Out4<T>: Support<Produce<T> = T>;
+    type Out5: Support<Output<'static> = &'static ()>;
+    type Out6: for<'a> Support<Output<'a> = &'a ()>;
+    type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated;
+    type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>;
+    type Out9: FnMut(i32) -> bool + Clone;
+    type Out10<'q>: Support<Output<'q> = ()>;
+    type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>;
+    type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>;
+
+    fn make<F>(_: F, _: impl FnMut(&str) -> bool)
+    where
+        F: FnOnce(u32) -> String,
+        Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>;
+}
+
+pub trait Support {
+    type Item;
+    type Output<'a>;
+    type Produce<T>;
+}
+
+pub trait Protocol<K> {
+    type Q0;
+    type Q1;
+}
+
+pub trait Unrelated {}
+
+pub trait Helper {
+    type A<'q>;
+    type B<'q>;
+}
diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.rs b/src/test/ui/impl-trait/in-trait/issue-102571.rs
new file mode 100644
index 00000000000..61c91e64417
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102571.rs
@@ -0,0 +1,24 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+use std::ops::Deref;
+
+trait Foo {
+    fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
+}
+
+struct A;
+
+impl Foo for A {
+    fn bar(self) -> &'static str {
+        "Hello, world"
+    }
+}
+
+fn foo<T: Foo>(t: T) {
+    let () = t.bar();
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.stderr b/src/test/ui/impl-trait/in-trait/issue-102571.stderr
new file mode 100644
index 00000000000..87219941d91
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/issue-102571.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-102571.rs:20:9
+   |
+LL |     let () = t.bar();
+   |         ^^   ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
+   |         |
+   |         expected associated type, found `()`
+   |
+   = note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
+                    found unit type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/transmutability/issue-101739-1.rs b/src/test/ui/transmutability/issue-101739-1.rs
new file mode 100644
index 00000000000..bcb8b158edf
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-1.rs
@@ -0,0 +1,21 @@
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::BikeshedIntrinsicFrom;
+
+    pub fn is_transmutable<Src, Context, const ASSUME_ALIGNMENT: bool>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
+        //~^ ERROR mismatched types
+    {
+    }
+}
+
+fn via_const() {
+    struct Context;
+    struct Src;
+
+    assert::is_transmutable::<Src, Context, false>();
+}
+
+fn main() {}
diff --git a/src/test/ui/transmutability/issue-101739-1.stderr b/src/test/ui/transmutability/issue-101739-1.stderr
new file mode 100644
index 00000000000..5fa741f26fd
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-1.stderr
@@ -0,0 +1,16 @@
+error[E0412]: cannot find type `Dst` in this scope
+  --> $DIR/issue-101739-1.rs:8:9
+   |
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
+   |         ^^^ not found in this scope
+
+error[E0308]: mismatched types
+  --> $DIR/issue-101739-1.rs:8:50
+   |
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
+   |                                                  ^^^^^^^^^^^^^^^^ expected struct `Assume`, found `bool`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0412.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/transmutability/issue-101739-2.rs b/src/test/ui/transmutability/issue-101739-2.rs
new file mode 100644
index 00000000000..964a7e49ee6
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-2.rs
@@ -0,0 +1,37 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+mod assert {
+    use std::mem::BikeshedIntrinsicFrom;
+
+    pub fn is_transmutable<
+        Src,
+        Dst,
+        Context,
+        const ASSUME_ALIGNMENT: bool,
+        const ASSUME_LIFETIMES: bool,
+        const ASSUME_VALIDITY: bool,
+        const ASSUME_VISIBILITY: bool,
+    >()
+    where
+        Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+            Src,
+            Context,
+            ASSUME_ALIGNMENT,
+            ASSUME_LIFETIMES,
+            ASSUME_VALIDITY,
+            ASSUME_VISIBILITY,
+        >,
+    {}
+}
+
+fn via_const() {
+    struct Context;
+    #[repr(C)] struct Src;
+    #[repr(C)] struct Dst;
+
+    const FALSE: bool = false;
+
+    assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>();
+}
diff --git a/src/test/ui/transmutability/issue-101739-2.stderr b/src/test/ui/transmutability/issue-101739-2.stderr
new file mode 100644
index 00000000000..3f83d6583b0
--- /dev/null
+++ b/src/test/ui/transmutability/issue-101739-2.stderr
@@ -0,0 +1,20 @@
+error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+  --> $DIR/issue-101739-2.rs:18:14
+   |
+LL |           Dst: BikeshedIntrinsicFrom<
+   |                ^^^^^^^^^^^^^^^^^^^^^ expected at most 3 generic arguments
+...
+LL | /             ASSUME_LIFETIMES,
+LL | |             ASSUME_VALIDITY,
+LL | |             ASSUME_VISIBILITY,
+   | |_____________________________- help: remove these generic arguments
+   |
+note: trait defined here, with at most 3 generic parameters: `Src`, `Context`, `ASSUME`
+  --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
+   |
+LL | pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
+   |                  ^^^^^^^^^^^^^^^^^^^^^ ---  -------  ------------------------------------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.