about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-31 08:50:22 +0200
committerGitHub <noreply@github.com>2024-05-31 08:50:22 +0200
commit379233242b755af755c06a3807306f69b2e7b781 (patch)
treed51d97e287ba884d5e090f5f41bbfc7dd3c098c8
parent366da30d554719e7490950aeea5d3f3a5927e313 (diff)
parent34c56c45cff1d0029dafd7d19c524975292382af (diff)
downloadrust-379233242b755af755c06a3807306f69b2e7b781.tar.gz
rust-379233242b755af755c06a3807306f69b2e7b781.zip
Rollup merge of #125635 - fmease:mv-type-binding-assoc-item-constraint, r=compiler-errors
Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup

Rename `hir::TypeBinding` and `ast::AssocConstraint` to `AssocItemConstraint` and update all items and locals using the old terminology.

Motivation: The terminology *type binding* is extremely outdated. "Type bindings" not only include constraints on associated *types* but also on associated *constants* (feature `associated_const_equality`) and on RPITITs of associated *functions* (feature `return_type_notation`). Hence the word *item* in the new name. Furthermore, the word *binding* commonly refers to a mapping from a binder/identifier to a "value" for some definition of "value". Its use in "type binding" made sense when equality constraints (e.g., `AssocTy = Ty`) were the only kind of associated item constraint. Nowadays however, we also have *associated type bounds* (e.g., `AssocTy: Bound`) for which the term *binding* doesn't make sense.

---

Old terminology (HIR, rustdoc):

```
`TypeBinding`: (associated) type binding
├── `Constraint`: associated type bound
└── `Equality`: (associated) equality constraint (?)
    ├── `Ty`: (associated) type binding
    └── `Const`: associated const equality (constraint)
```

Old terminology (AST, abbrev.):

```
`AssocConstraint`
├── `Bound`
└── `Equality`
    ├── `Ty`
    └── `Const`
```

New terminology (AST, HIR, rustdoc):

```
`AssocItemConstraint`: associated item constraint
├── `Bound`: associated type bound
└── `Equality`: associated item equality constraint OR associated item binding (for short)
    ├── `Ty`: associated type equality constraint OR associated type binding (for short)
    └── `Const`: associated const equality constraint OR associated const binding (for short)
```

r? compiler-errors
-rw-r--r--compiler/rustc_ast/src/ast.rs45
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs14
-rw-r--r--compiler/rustc_ast/src/visit.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs51
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs31
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs16
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs32
-rw-r--r--compiler/rustc_ast_passes/src/node_count.rs4
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs12
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0229.md13
-rw-r--r--compiler/rustc_hir/src/hir.rs178
-rw-r--r--compiler/rustc_hir/src/intravisit.rs27
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs98
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs30
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs75
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs12
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs14
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_parse/src/parser/path.rs33
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs8
-rw-r--r--compiler/rustc_resolve/src/late.rs6
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs12
-rw-r--r--src/librustdoc/clean/auto_trait.rs4
-rw-r--r--src/librustdoc/clean/blanket_impl.rs4
-rw-r--r--src/librustdoc/clean/inline.rs6
-rw-r--r--src/librustdoc/clean/mod.rs79
-rw-r--r--src/librustdoc/clean/simplify.rs6
-rw-r--r--src/librustdoc/clean/types.rs47
-rw-r--r--src/librustdoc/clean/utils.rs25
-rw-r--r--src/librustdoc/html/format.rs16
-rw-r--r--src/librustdoc/html/render/search_index.rs46
-rw-r--r--src/librustdoc/json/conversions.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs54
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs8
-rw-r--r--src/tools/rustfmt/src/types.rs12
-rw-r--r--tests/rustdoc-ui/invalid_associated_const.rs4
-rw-r--r--tests/rustdoc-ui/invalid_associated_const.stderr12
-rw-r--r--tests/rustdoc-ui/issue-102467.rs4
-rw-r--r--tests/rustdoc-ui/issue-102467.stderr12
-rw-r--r--tests/ui/associated-consts/issue-102335-const.rs4
-rw-r--r--tests/ui/associated-consts/issue-102335-const.stderr12
-rw-r--r--tests/ui/associated-type-bounds/issue-102335-ty.rs8
-rw-r--r--tests/ui/associated-type-bounds/issue-102335-ty.stderr24
-rw-r--r--tests/ui/associated-type-bounds/no-gat-position.rs2
-rw-r--r--tests/ui/associated-type-bounds/no-gat-position.stderr4
-rw-r--r--tests/ui/associated-types/associated-types-eq-2.rs24
-rw-r--r--tests/ui/associated-types/associated-types-eq-2.stderr64
-rw-r--r--tests/ui/associated-types/associated-types-eq-expr-path.rs4
-rw-r--r--tests/ui/associated-types/associated-types-eq-expr-path.stderr6
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs2
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr4
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr4
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013.rs2
-rw-r--r--tests/ui/const-generics/parser-error-recovery/issue-89013.stderr4
-rw-r--r--tests/ui/error-codes/E0229.rs8
-rw-r--r--tests/ui/error-codes/E0229.stderr50
-rw-r--r--tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr4
-rw-r--r--tests/ui/fn/issue-39259.rs2
-rw-r--r--tests/ui/fn/issue-39259.stderr4
-rw-r--r--tests/ui/generic-associated-types/issue-102335-gat.rs4
-rw-r--r--tests/ui/generic-associated-types/issue-102335-gat.stderr12
-rw-r--r--tests/ui/issues/issue-23543.rs2
-rw-r--r--tests/ui/issues/issue-23543.stderr4
-rw-r--r--tests/ui/issues/issue-23544.rs2
-rw-r--r--tests/ui/issues/issue-23544.stderr4
-rw-r--r--tests/ui/issues/issue-24682.rs6
-rw-r--r--tests/ui/issues/issue-24682.stderr12
-rw-r--r--tests/ui/issues/issue-39687.rs2
-rw-r--r--tests/ui/issues/issue-39687.stderr4
-rw-r--r--tests/ui/issues/issue-43431.rs2
-rw-r--r--tests/ui/issues/issue-43431.stderr4
-rw-r--r--tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs2
-rw-r--r--tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr6
-rw-r--r--tests/ui/lifetimes/issue-95023.rs2
-rw-r--r--tests/ui/lifetimes/issue-95023.stderr4
-rw-r--r--tests/ui/methods/method-call-type-binding.rs2
-rw-r--r--tests/ui/methods/method-call-type-binding.stderr4
-rw-r--r--tests/ui/suggestions/issue-85347.rs8
-rw-r--r--tests/ui/suggestions/issue-85347.stderr12
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs2
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr4
-rw-r--r--tests/ui/traits/issue-87558.rs2
-rw-r--r--tests/ui/traits/issue-87558.stderr4
-rw-r--r--tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs2
-rw-r--r--tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr4
-rw-r--r--tests/ui/typeck/escaping_bound_vars.rs2
-rw-r--r--tests/ui/typeck/escaping_bound_vars.stderr4
-rw-r--r--tests/ui/typeck/issue-83693.rs4
-rw-r--r--tests/ui/typeck/issue-83693.stderr8
-rw-r--r--tests/ui/typeck/issue-84768.rs2
-rw-r--r--tests/ui/typeck/issue-84768.stderr4
-rw-r--r--tests/ui/typeck/issue-91267.rs2
-rw-r--r--tests/ui/typeck/issue-91267.stderr4
108 files changed, 879 insertions, 819 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 7e59b449299..7a45d909d07 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -167,7 +167,7 @@ impl PathSegment {
     }
 }
 
-/// The arguments of a path segment.
+/// The generic arguments and associated item constraints of a path segment.
 ///
 /// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
 #[derive(Clone, Encodable, Decodable, Debug)]
@@ -221,14 +221,13 @@ pub struct AngleBracketedArgs {
     pub args: ThinVec<AngleBracketedArg>,
 }
 
-/// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
-/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
+/// Either an argument for a generic parameter or a constraint on an associated item.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AngleBracketedArg {
-    /// Argument for a generic parameter.
+    /// A generic argument for a generic parameter.
     Arg(GenericArg),
-    /// Constraint for an associated item.
-    Constraint(AssocConstraint),
+    /// A constraint on an associated item.
+    Constraint(AssocItemConstraint),
 }
 
 impl AngleBracketedArg {
@@ -418,7 +417,7 @@ impl Default for WhereClause {
 /// A single predicate in a where-clause.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum WherePredicate {
-    /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
+    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
     /// A lifetime predicate (e.g., `'a: 'b + 'c`).
     RegionPredicate(WhereRegionPredicate),
@@ -2034,18 +2033,25 @@ impl UintTy {
     }
 }
 
-/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
-/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
-#[derive(Clone, Encodable, Decodable, Debug)]
-pub struct AssocConstraint {
+/// A constraint on an associated item.
+///
+/// ### Examples
+///
+/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
+/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
+/// * the `A: Bound` in `Trait<A: Bound>`
+/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
+/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
+/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct AssocItemConstraint {
     pub id: NodeId,
     pub ident: Ident,
     pub gen_args: Option<GenericArgs>,
-    pub kind: AssocConstraintKind,
+    pub kind: AssocItemConstraintKind,
     pub span: Span,
 }
 
-/// The kinds of an `AssocConstraint`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum Term {
     Ty(P<Ty>),
@@ -2064,12 +2070,17 @@ impl From<AnonConst> for Term {
     }
 }
 
-/// The kinds of an `AssocConstraint`.
+/// The kind of [associated item constraint][AssocItemConstraint].
 #[derive(Clone, Encodable, Decodable, Debug)]
-pub enum AssocConstraintKind {
-    /// E.g., `A = Bar`, `A = 3` in `Foo<A = Bar>` where A is an associated type.
+pub enum AssocItemConstraintKind {
+    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
+    ///
+    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
+    ///
+    /// Furthermore, associated type equality constraints can also be referred to as *associated type
+    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
     Equality { term: Term },
-    /// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
+    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
     Bound { bounds: GenericBounds },
 }
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index ede0dd70b30..5c581c270e4 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -175,8 +175,8 @@ pub trait MutVisitor: Sized {
         noop_visit_lifetime(l, self);
     }
 
-    fn visit_constraint(&mut self, t: &mut AssocConstraint) {
-        noop_visit_constraint(t, self);
+    fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) {
+        noop_visit_assoc_item_constraint(c, self);
     }
 
     fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
@@ -463,8 +463,8 @@ pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[
     smallvec![arm]
 }
 
-fn noop_visit_constraint<T: MutVisitor>(
-    AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint,
+fn noop_visit_assoc_item_constraint<T: MutVisitor>(
+    AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
     vis: &mut T,
 ) {
     vis.visit_id(id);
@@ -473,11 +473,11 @@ fn noop_visit_constraint<T: MutVisitor>(
         vis.visit_generic_args(gen_args);
     }
     match kind {
-        AssocConstraintKind::Equality { term } => match term {
+        AssocItemConstraintKind::Equality { term } => match term {
             Term::Ty(ty) => vis.visit_ty(ty),
             Term::Const(c) => vis.visit_anon_const(c),
         },
-        AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
+        AssocItemConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
     }
     vis.visit_span(span);
 }
@@ -607,7 +607,7 @@ fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>(
     let AngleBracketedArgs { args, span } = data;
     visit_thin_vec(args, |arg| match arg {
         AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
-        AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint),
+        AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
     });
     vis.visit_span(span);
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 6382eb6861c..b2f3b27c77e 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -246,8 +246,11 @@ pub trait Visitor<'ast>: Sized {
     fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result {
         walk_generic_arg(self, generic_arg)
     }
-    fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) -> Self::Result {
-        walk_assoc_constraint(self, constraint)
+    fn visit_assoc_item_constraint(
+        &mut self,
+        constraint: &'ast AssocItemConstraint,
+    ) -> Self::Result {
+        walk_assoc_item_constraint(self, constraint)
     }
     fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result {
         walk_attribute(self, attr)
@@ -558,7 +561,7 @@ where
                 match arg {
                     AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
                     AngleBracketedArg::Constraint(c) => {
-                        try_visit!(visitor.visit_assoc_constraint(c))
+                        try_visit!(visitor.visit_assoc_item_constraint(c))
                     }
                 }
             }
@@ -582,18 +585,18 @@ where
     }
 }
 
-pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(
+pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
     visitor: &mut V,
-    constraint: &'a AssocConstraint,
+    constraint: &'a AssocItemConstraint,
 ) -> V::Result {
     try_visit!(visitor.visit_ident(constraint.ident));
     visit_opt!(visitor, visit_generic_args, &constraint.gen_args);
     match &constraint.kind {
-        AssocConstraintKind::Equality { term } => match term {
+        AssocItemConstraintKind::Equality { term } => match term {
             Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
             Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
         },
-        AssocConstraintKind::Bound { bounds } => {
+        AssocItemConstraintKind::Bound { bounds } => {
             walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
         }
     }
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index ed3046400f6..741a44eb0c5 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -325,10 +325,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         });
     }
 
-    fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) {
-        self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding));
-        self.with_parent(type_binding.hir_id, |this| {
-            intravisit::walk_assoc_type_binding(this, type_binding)
+    fn visit_assoc_item_constraint(&mut self, constraint: &'hir AssocItemConstraint<'hir>) {
+        self.insert(constraint.span, constraint.hir_id, Node::AssocItemConstraint(constraint));
+        self.with_parent(constraint.hir_id, |this| {
+            intravisit::walk_assoc_item_constraint(this, constraint)
         })
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 278049d1347..5a80fa803f8 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -967,24 +967,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
     }
 
-    /// Given an associated type constraint like one of these:
-    ///
-    /// ```ignore (illustrative)
-    /// T: Iterator<Item: Debug>
-    ///             ^^^^^^^^^^^
-    /// T: Iterator<Item = Debug>
-    ///             ^^^^^^^^^^^^
-    /// ```
-    ///
-    /// returns a `hir::TypeBinding` representing `Item`.
-    #[instrument(level = "debug", skip(self))]
-    fn lower_assoc_ty_constraint(
+    /// Lower an associated item constraint.
+    #[instrument(level = "debug", skip_all)]
+    fn lower_assoc_item_constraint(
         &mut self,
-        constraint: &AssocConstraint,
+        constraint: &AssocItemConstraint,
         itctx: ImplTraitContext,
-    ) -> hir::TypeBinding<'hir> {
-        debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
-        // lower generic arguments of identifier in constraint
+    ) -> hir::AssocItemConstraint<'hir> {
+        debug!(?constraint, ?itctx);
+        // Lower the generic arguments for the associated item.
         let gen_args = if let Some(gen_args) = &constraint.gen_args {
             let gen_args_ctor = match gen_args {
                 GenericArgs::AngleBracketed(data) => {
@@ -1000,7 +991,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         };
                         GenericArgsCtor {
                             args: Default::default(),
-                            bindings: &[],
+                            constraints: &[],
                             parenthesized,
                             span: data.inputs_span,
                         }
@@ -1030,7 +1021,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         err.emit();
                         GenericArgsCtor {
                             args: Default::default(),
-                            bindings: &[],
+                            constraints: &[],
                             parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
                             span: data.span,
                         }
@@ -1052,14 +1043,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.arena.alloc(hir::GenericArgs::none())
         };
         let kind = match &constraint.kind {
-            AssocConstraintKind::Equality { term } => {
+            AssocItemConstraintKind::Equality { term } => {
                 let term = match term {
                     Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
                     Term::Const(c) => self.lower_anon_const(c).into(),
                 };
-                hir::TypeBindingKind::Equality { term }
+                hir::AssocItemConstraintKind::Equality { term }
             }
-            AssocConstraintKind::Bound { bounds } => {
+            AssocItemConstraintKind::Bound { bounds } => {
                 // Disallow ATB in dyn types
                 if self.is_in_dyn_type {
                     let suggestion = match itctx {
@@ -1083,18 +1074,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     });
                     let err_ty =
                         &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
-                    hir::TypeBindingKind::Equality { term: err_ty.into() }
+                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
                 } else {
-                    // Desugar `AssocTy: Bounds` into a type binding where the
+                    // Desugar `AssocTy: Bounds` into an assoc type binding where the
                     // later desugars into a trait predicate.
                     let bounds = self.lower_param_bounds(bounds, itctx);
 
-                    hir::TypeBindingKind::Constraint { bounds }
+                    hir::AssocItemConstraintKind::Bound { bounds }
                 }
             }
         };
 
-        hir::TypeBinding {
+        hir::AssocItemConstraint {
             hir_id: self.lower_node_id(constraint.id),
             ident: self.lower_ident(constraint.ident),
             gen_args,
@@ -2014,7 +2005,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         let bound_args = self.arena.alloc(hir::GenericArgs {
             args: &[],
-            bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
+            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
             parenthesized: hir::GenericArgsParentheses::No,
             span_ext: DUMMY_SP,
         });
@@ -2587,10 +2578,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 }
 
-/// Helper struct for delayed construction of GenericArgs.
+/// Helper struct for the delayed construction of [`hir::GenericArgs`].
 struct GenericArgsCtor<'hir> {
     args: SmallVec<[hir::GenericArg<'hir>; 4]>,
-    bindings: &'hir [hir::TypeBinding<'hir>],
+    constraints: &'hir [hir::AssocItemConstraint<'hir>],
     parenthesized: hir::GenericArgsParentheses,
     span: Span,
 }
@@ -2670,14 +2661,14 @@ impl<'hir> GenericArgsCtor<'hir> {
 
     fn is_empty(&self) -> bool {
         self.args.is_empty()
-            && self.bindings.is_empty()
+            && self.constraints.is_empty()
             && self.parenthesized == hir::GenericArgsParentheses::No
     }
 
     fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
         let ga = hir::GenericArgs {
             args: this.arena.alloc_from_iter(self.args),
-            bindings: self.bindings,
+            constraints: self.constraints,
             parenthesized: self.parenthesized,
             span_ext: this.lower_span(self.span),
         };
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 7679424dceb..9d38e1e6784 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -281,7 +281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             (
                 GenericArgsCtor {
                     args: Default::default(),
-                    bindings: &[],
+                    constraints: &[],
                     parenthesized: hir::GenericArgsParentheses::No,
                     span: path_span.shrink_to_hi(),
                 },
@@ -390,13 +390,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 AngleBracketedArg::Constraint(_) => None,
             })
             .collect();
-        let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
-            AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)),
-            AngleBracketedArg::Arg(_) => None,
-        }));
+        let constraints =
+            self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
+                AngleBracketedArg::Constraint(c) => {
+                    Some(self.lower_assoc_item_constraint(c, itctx))
+                }
+                AngleBracketedArg::Arg(_) => None,
+            }));
         let ctor = GenericArgsCtor {
             args,
-            bindings,
+            constraints,
             parenthesized: hir::GenericArgsParentheses::No,
             span: data.span,
         };
@@ -454,12 +457,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 Some(bound_modifier_allowed_features),
             );
         }
-        let binding = self.assoc_ty_binding(sym::Output, output_span, output_ty);
+        let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty);
 
         (
             GenericArgsCtor {
                 args,
-                bindings: arena_vec![self; binding],
+                constraints: arena_vec![self; constraint],
                 parenthesized: hir::GenericArgsParentheses::ParenSugar,
                 span: data.inputs_span,
             },
@@ -467,24 +470,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         )
     }
 
-    /// An associated type binding `$assoc_ty_name = $ty`.
+    /// An associated type binding (i.e., associated type equality constraint).
     pub(crate) fn assoc_ty_binding(
         &mut self,
         assoc_ty_name: rustc_span::Symbol,
         span: Span,
         ty: &'hir hir::Ty<'hir>,
-    ) -> hir::TypeBinding<'hir> {
+    ) -> hir::AssocItemConstraint<'hir> {
         let ident = Ident::with_dummy_span(assoc_ty_name);
-        let kind = hir::TypeBindingKind::Equality { term: ty.into() };
+        let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() };
         let args = arena_vec![self;];
-        let bindings = arena_vec![self;];
+        let constraints = arena_vec![self;];
         let gen_args = self.arena.alloc(hir::GenericArgs {
             args,
-            bindings,
+            constraints,
             parenthesized: hir::GenericArgsParentheses::No,
             span_ext: DUMMY_SP,
         });
-        hir::TypeBinding {
+        hir::AssocItemConstraint {
             hir_id: self.next_id(),
             gen_args,
             span: self.lower_span(span),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 598a3ec2d3c..435b0b6a956 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -671,7 +671,7 @@ impl<'a> AstValidator<'a> {
         let constraint_sugg = data.args.iter().filter_map(|a| match a {
             AngleBracketedArg::Arg(_) => None,
             AngleBracketedArg::Constraint(c) => {
-                Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
+                Some(pprust::to_string(|s| s.print_assoc_item_constraint(c)))
             }
         });
         format!(
@@ -1199,11 +1199,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 for arg in &data.args {
                     match arg {
                         AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
-                        // Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
-                        // are allowed to contain nested `impl Trait`.
+                        // Associated type bindings such as `Item = impl Debug` in
+                        // `Iterator<Item = Debug>` are allowed to contain nested `impl Trait`.
                         AngleBracketedArg::Constraint(constraint) => {
                             self.with_impl_trait(None, |this| {
-                                this.visit_assoc_constraint(constraint);
+                                this.visit_assoc_item_constraint(constraint);
                             });
                         }
                     }
@@ -1363,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         }
                     }
                 }
-                // The lowered form of parenthesized generic args contains a type binding.
+                // The lowered form of parenthesized generic args contains an associated type binding.
                 Some(ast::GenericArgs::Parenthesized(args)) => {
                     self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
                         span: args.span,
@@ -1589,11 +1589,13 @@ fn deny_equality_constraints(
                 let len = assoc_path.segments.len() - 1;
                 let gen_args = args.as_deref().cloned();
                 // Build `<Bar = RhsTy>`.
-                let arg = AngleBracketedArg::Constraint(AssocConstraint {
+                let arg = AngleBracketedArg::Constraint(AssocItemConstraint {
                     id: rustc_ast::node_id::DUMMY_NODE_ID,
                     ident: *ident,
                     gen_args,
-                    kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
+                    kind: AssocItemConstraintKind::Equality {
+                        term: predicate.rhs_ty.clone().into(),
+                    },
                     span: ident.span,
                 });
                 // Add `<Bar = RhsTy>` to `Foo`.
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index a522f04b21d..a9dca9b6a29 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -1,6 +1,6 @@
 use rustc_ast as ast;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
-use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};
+use rustc_ast::{attr, AssocItemConstraint, AssocItemConstraintKind, NodeId};
 use rustc_ast::{token, PatKind};
 use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
 use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
@@ -344,7 +344,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         for predicate in &g.where_clause.predicates {
             match predicate {
                 ast::WherePredicate::BoundPredicate(bound_pred) => {
-                    // A type binding, eg `for<'c> Foo: Send+Clone+'c`
+                    // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
                     self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
                 }
                 _ => {}
@@ -445,21 +445,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         visit::walk_fn(self, fn_kind)
     }
 
-    fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
-        if let AssocConstraintKind::Bound { .. } = constraint.kind {
-            if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
-                && args.inputs.is_empty()
-                && matches!(args.output, ast::FnRetTy::Default(..))
-            {
-                gate!(
-                    &self,
-                    return_type_notation,
-                    constraint.span,
-                    "return type notation is experimental"
-                );
-            }
+    fn visit_assoc_item_constraint(&mut self, constraint: &'a AssocItemConstraint) {
+        if let AssocItemConstraintKind::Bound { .. } = constraint.kind
+            && let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
+            && args.inputs.is_empty()
+            && let ast::FnRetTy::Default(..) = args.output
+        {
+            gate!(
+                &self,
+                return_type_notation,
+                constraint.span,
+                "return type notation is experimental"
+            );
         }
-        visit::walk_assoc_constraint(self, constraint)
+
+        visit::walk_assoc_item_constraint(self, constraint)
     }
 
     fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index 2128acba0ba..c61640de6f7 100644
--- a/compiler/rustc_ast_passes/src/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
@@ -119,9 +119,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
         self.count += 1;
         walk_generic_args(self, generic_args)
     }
-    fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) {
+    fn visit_assoc_item_constraint(&mut self, constraint: &AssocItemConstraint) {
         self.count += 1;
-        walk_assoc_constraint(self, constraint)
+        walk_assoc_item_constraint(self, constraint)
     }
     fn visit_attribute(&mut self, _attr: &Attribute) {
         self.count += 1;
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index f02fe4cf0a7..4c29ca0ca46 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1045,7 +1045,7 @@ impl<'a> PrintState<'a> for State<'a> {
                 self.word("<");
                 self.commasep(Inconsistent, &data.args, |s, arg| match arg {
                     ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
-                    ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c),
+                    ast::AngleBracketedArg::Constraint(c) => s.print_assoc_item_constraint(c),
                 });
                 self.word(">")
             }
@@ -1097,21 +1097,21 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) {
+    pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) {
         self.print_ident(constraint.ident);
         if let Some(args) = constraint.gen_args.as_ref() {
             self.print_generic_args(args, false)
         }
         self.space();
         match &constraint.kind {
-            ast::AssocConstraintKind::Equality { term } => {
+            ast::AssocItemConstraintKind::Equality { term } => {
                 self.word_space("=");
                 match term {
                     Term::Ty(ty) => self.print_type(ty),
                     Term::Const(c) => self.print_expr_anon_const(c, &[]),
                 }
             }
-            ast::AssocConstraintKind::Bound { bounds } => {
+            ast::AssocItemConstraintKind::Bound { bounds } => {
                 if !bounds.is_empty() {
                     self.word_nbsp(":");
                     self.print_type_bounds(bounds);
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index c2db64e7702..2cf548e28b1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::print::RegionHighlightMode;
 use rustc_middle::ty::{self, RegionVid, Ty};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
 use rustc_middle::{bug, span_bug};
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 
 use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
@@ -843,13 +843,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         }) = opaque_ty.kind
             && let Some(segment) = trait_ref.trait_ref.path.segments.last()
             && let Some(args) = segment.args
-            && let [
-                hir::TypeBinding {
-                    ident: Ident { name: sym::Output, .. },
-                    kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
-                    ..
-                },
-            ] = args.bindings
+            && let [constraint] = args.constraints
+            && constraint.ident.name == sym::Output
+            && let Some(ty) = constraint.ty()
         {
             ty
         } else {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0229.md b/compiler/rustc_error_codes/src/error_codes/E0229.md
index a8fab057d43..f4a983cb9ef 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0229.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0229.md
@@ -1,5 +1,4 @@
-An associated type binding was done outside of the type parameter declaration
-and `where` clause.
+An associated item constraint was written in an unexpected context.
 
 Erroneous code example:
 
@@ -16,12 +15,12 @@ impl Foo for isize {
     fn boo(&self) -> usize { 42 }
 }
 
-fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-// error: associated type bindings are not allowed here
+fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+// error: associated item constraint are not allowed here
 ```
 
-To solve this error, please move the type bindings in the type parameter
-declaration:
+To solve this error, please move the associated item constraints to the type
+parameter declaration:
 
 ```
 # struct Bar;
@@ -29,7 +28,7 @@ declaration:
 fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
 ```
 
-Or in the `where` clause:
+Or into the where-clause:
 
 ```
 # struct Bar;
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e64f7aeb11b..e971d0e3c14 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -300,23 +300,30 @@ impl GenericArg<'_> {
     }
 }
 
+/// The generic arguments and associated item constraints of a path segment.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct GenericArgs<'hir> {
     /// The generic arguments for this path segment.
     pub args: &'hir [GenericArg<'hir>],
-    /// Bindings (equality constraints) on associated types, if present.
-    /// E.g., `Foo<A = Bar>`.
-    pub bindings: &'hir [TypeBinding<'hir>],
-    /// Were arguments written in parenthesized form `Fn(T) -> U`?
+    /// The associated item constraints for this path segment.
+    pub constraints: &'hir [AssocItemConstraint<'hir>],
+    /// Whether the arguments were written in parenthesized form (e.g., `Fn(T) -> U`).
+    ///
     /// This is required mostly for pretty-printing and diagnostics,
     /// but also for changing lifetime elision rules to be "function-like".
     pub parenthesized: GenericArgsParentheses,
-    /// The span encompassing arguments and the surrounding brackets `<>` or `()`
+    /// The span encompassing the arguments, constraints and the surrounding brackets (`<>` or `()`).
+    ///
+    /// For example:
+    ///
+    /// ```ignore (illustrative)
     ///       Foo<A, B, AssocTy = D>           Fn(T, U, V) -> W
     ///          ^^^^^^^^^^^^^^^^^^^             ^^^^^^^^^
+    /// ```
+    ///
     /// Note that this may be:
     /// - empty, if there are no generic brackets (but there may be hidden lifetimes)
-    /// - dummy, if this was generated while desugaring
+    /// - dummy, if this was generated during desugaring
     pub span_ext: Span,
 }
 
@@ -324,39 +331,63 @@ impl<'hir> GenericArgs<'hir> {
     pub const fn none() -> Self {
         Self {
             args: &[],
-            bindings: &[],
+            constraints: &[],
             parenthesized: GenericArgsParentheses::No,
             span_ext: DUMMY_SP,
         }
     }
 
-    pub fn inputs(&self) -> &[Ty<'hir>] {
-        if self.parenthesized == GenericArgsParentheses::ParenSugar {
-            for arg in self.args {
-                match arg {
-                    GenericArg::Lifetime(_) => {}
-                    GenericArg::Type(ref ty) => {
-                        if let TyKind::Tup(ref tys) = ty.kind {
-                            return tys;
-                        }
-                        break;
-                    }
-                    GenericArg::Const(_) => {}
-                    GenericArg::Infer(_) => {}
-                }
-            }
+    /// Obtain the list of input types and the output type if the generic arguments are parenthesized.
+    ///
+    /// Returns the `Ty0, Ty1, ...` and the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
+    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
+    pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
+        if self.parenthesized != GenericArgsParentheses::ParenSugar {
+            return None;
         }
-        panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
+
+        let inputs = self
+            .args
+            .iter()
+            .find_map(|arg| {
+                let GenericArg::Type(ty) = arg else { return None };
+                let TyKind::Tup(tys) = &ty.kind else { return None };
+                Some(tys)
+            })
+            .unwrap();
+
+        Some((inputs, self.paren_sugar_output_inner()))
     }
 
-    pub fn has_err(&self) -> bool {
-        self.args.iter().any(|arg| match arg {
-            GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)),
-            _ => false,
-        }) || self.bindings.iter().any(|arg| match arg.kind {
-            TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err(_)),
-            _ => false,
-        })
+    /// Obtain the output type if the generic arguments are parenthesized.
+    ///
+    /// Returns the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
+    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
+    pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
+        (self.parenthesized == GenericArgsParentheses::ParenSugar)
+            .then(|| self.paren_sugar_output_inner())
+    }
+
+    fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
+        let [constraint] = self.constraints.try_into().unwrap();
+        debug_assert_eq!(constraint.ident.name, sym::Output);
+        constraint.ty().unwrap()
+    }
+
+    pub fn has_err(&self) -> Option<ErrorGuaranteed> {
+        self.args
+            .iter()
+            .find_map(|arg| {
+                let GenericArg::Type(ty) = arg else { return None };
+                let TyKind::Err(guar) = ty.kind else { return None };
+                Some(guar)
+            })
+            .or_else(|| {
+                self.constraints.iter().find_map(|constraint| {
+                    let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
+                    Some(guar)
+                })
+            })
     }
 
     #[inline]
@@ -383,9 +414,11 @@ impl<'hir> GenericArgs<'hir> {
             .count()
     }
 
-    /// The span encompassing the text inside the surrounding brackets.
-    /// It will also include bindings if they aren't in the form `-> Ret`
-    /// Returns `None` if the span is empty (e.g. no brackets) or dummy
+    /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets.
+    ///
+    /// Returns `None` if the span is empty (i.e., no brackets) or dummy.
+    ///
+    /// [^1]: Unless of the form `-> Ty` (see [`GenericArgsParentheses`]).
     pub fn span(&self) -> Option<Span> {
         let span_ext = self.span_ext()?;
         Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
@@ -660,9 +693,7 @@ impl<'hir> Generics<'hir> {
             |bound| {
                 let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
                     && let [.., segment] = trait_ref.path.segments
-                    && segment.args().parenthesized == GenericArgsParentheses::ParenSugar
-                    && let [binding] = segment.args().bindings
-                    && let TypeBindingKind::Equality { term: Term::Ty(ret_ty) } = binding.kind
+                    && let Some(ret_ty) = segment.args().paren_sugar_output()
                     && let ret_ty = ret_ty.peel_refs()
                     && let TyKind::TraitObject(
                         _,
@@ -748,7 +779,7 @@ impl<'hir> Generics<'hir> {
 /// A single predicate in a where-clause.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum WherePredicate<'hir> {
-    /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
+    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate<'hir>),
     /// A lifetime predicate (e.g., `'a: 'b + 'c`).
     RegionPredicate(WhereRegionPredicate<'hir>),
@@ -2356,24 +2387,43 @@ pub enum ImplItemKind<'hir> {
     Type(&'hir Ty<'hir>),
 }
 
-/// An associated item binding.
+/// A constraint on an associated item.
 ///
 /// ### Examples
 ///
-/// * `Trait<A = Ty, B = Ty>`
-/// * `Trait<G<Ty> = Ty>`
-/// * `Trait<A: Bound>`
-/// * `Trait<C = { Ct }>` (under feature `associated_const_equality`)
-/// * `Trait<f(): Bound>` (under feature `return_type_notation`)
+/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
+/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
+/// * the `A: Bound` in `Trait<A: Bound>`
+/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
+/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
+/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
-pub struct TypeBinding<'hir> {
+pub struct AssocItemConstraint<'hir> {
     pub hir_id: HirId,
     pub ident: Ident,
     pub gen_args: &'hir GenericArgs<'hir>,
-    pub kind: TypeBindingKind<'hir>,
+    pub kind: AssocItemConstraintKind<'hir>,
     pub span: Span,
 }
 
+impl<'hir> AssocItemConstraint<'hir> {
+    /// Obtain the type on the RHS of an assoc ty equality constraint if applicable.
+    pub fn ty(self) -> Option<&'hir Ty<'hir>> {
+        match self.kind {
+            AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
+            _ => None,
+        }
+    }
+
+    /// Obtain the const on the RHS of an assoc const equality constraint if applicable.
+    pub fn ct(self) -> Option<&'hir AnonConst> {
+        match self.kind {
+            AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
+            _ => None,
+        }
+    }
+}
+
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum Term<'hir> {
     Ty(&'hir Ty<'hir>),
@@ -2392,28 +2442,18 @@ impl<'hir> From<&'hir AnonConst> for Term<'hir> {
     }
 }
 
-// Represents the two kinds of type bindings.
+/// The kind of [associated item constraint][AssocItemConstraint].
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
-pub enum TypeBindingKind<'hir> {
-    /// E.g., `Foo<Bar: Send>`.
-    Constraint { bounds: &'hir [GenericBound<'hir>] },
-    /// E.g., `Foo<Bar = ()>`.
+pub enum AssocItemConstraintKind<'hir> {
+    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
+    ///
+    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
+    ///
+    /// Furthermore, associated type equality constraints can also be referred to as *associated type
+    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
     Equality { term: Term<'hir> },
-}
-
-impl TypeBinding<'_> {
-    pub fn ty(&self) -> &Ty<'_> {
-        match self.kind {
-            TypeBindingKind::Equality { term: Term::Ty(ref ty) } => ty,
-            _ => panic!("expected equality type binding for parenthesized generic args"),
-        }
-    }
-    pub fn opt_const(&self) -> Option<&'_ AnonConst> {
-        match self.kind {
-            TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c),
-            _ => None,
-        }
-    }
+    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
+    Bound { bounds: &'hir [GenericBound<'hir>] },
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
@@ -3609,7 +3649,7 @@ pub enum Node<'hir> {
     Stmt(&'hir Stmt<'hir>),
     PathSegment(&'hir PathSegment<'hir>),
     Ty(&'hir Ty<'hir>),
-    TypeBinding(&'hir TypeBinding<'hir>),
+    AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
     TraitRef(&'hir TraitRef<'hir>),
     Pat(&'hir Pat<'hir>),
     PatField(&'hir PatField<'hir>),
@@ -3658,7 +3698,7 @@ impl<'hir> Node<'hir> {
             | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
             Node::Lifetime(lt) => Some(lt.ident),
             Node::GenericParam(p) => Some(p.name.ident()),
-            Node::TypeBinding(b) => Some(b.ident),
+            Node::AssocItemConstraint(c) => Some(c.ident),
             Node::PatField(f) => Some(f.ident),
             Node::ExprField(f) => Some(f.ident),
             Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
@@ -3834,7 +3874,7 @@ impl<'hir> Node<'hir> {
         expect_stmt,          &'hir Stmt<'hir>,         Node::Stmt(n),         n;
         expect_path_segment,  &'hir PathSegment<'hir>,  Node::PathSegment(n),  n;
         expect_ty,            &'hir Ty<'hir>,           Node::Ty(n),           n;
-        expect_type_binding,  &'hir TypeBinding<'hir>,  Node::TypeBinding(n),  n;
+        expect_assoc_item_constraint,  &'hir AssocItemConstraint<'hir>,  Node::AssocItemConstraint(n),  n;
         expect_trait_ref,     &'hir TraitRef<'hir>,     Node::TraitRef(n),     n;
         expect_pat,           &'hir Pat<'hir>,          Node::Pat(n),          n;
         expect_pat_field,     &'hir PatField<'hir>,     Node::PatField(n),     n;
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 63ddb22c5ab..9bc2bbe0c64 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -453,8 +453,11 @@ pub trait Visitor<'v>: Sized {
     fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) -> Self::Result {
         walk_generic_args(self, generic_args)
     }
-    fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) -> Self::Result {
-        walk_assoc_type_binding(self, type_binding)
+    fn visit_assoc_item_constraint(
+        &mut self,
+        constraint: &'v AssocItemConstraint<'v>,
+    ) -> Self::Result {
+        walk_assoc_item_constraint(self, constraint)
     }
     fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
         Self::Result::output()
@@ -1248,23 +1251,25 @@ pub fn walk_generic_args<'v, V: Visitor<'v>>(
     generic_args: &'v GenericArgs<'v>,
 ) -> V::Result {
     walk_list!(visitor, visit_generic_arg, generic_args.args);
-    walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings);
+    walk_list!(visitor, visit_assoc_item_constraint, generic_args.constraints);
     V::Result::output()
 }
 
-pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
+pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
     visitor: &mut V,
-    type_binding: &'v TypeBinding<'v>,
+    constraint: &'v AssocItemConstraint<'v>,
 ) -> V::Result {
-    try_visit!(visitor.visit_id(type_binding.hir_id));
-    try_visit!(visitor.visit_ident(type_binding.ident));
-    try_visit!(visitor.visit_generic_args(type_binding.gen_args));
-    match type_binding.kind {
-        TypeBindingKind::Equality { ref term } => match term {
+    try_visit!(visitor.visit_id(constraint.hir_id));
+    try_visit!(visitor.visit_ident(constraint.ident));
+    try_visit!(visitor.visit_generic_args(constraint.gen_args));
+    match constraint.kind {
+        AssocItemConstraintKind::Equality { ref term } => match term {
             Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)),
             Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)),
         },
-        TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds),
+        AssocItemConstraintKind::Bound { bounds } => {
+            walk_list!(visitor, visit_param_bound, bounds)
+        }
     }
     V::Result::output()
 }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index cf492a2a3fe..67959d9dfed 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -4,6 +4,10 @@ hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_
 hir_analysis_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
 
+hir_analysis_assoc_item_constraints_not_allowed_here =
+    associated item constraints are not allowed here
+    .label = associated item constraint not allowed here
+
 hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
 
 hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
@@ -24,10 +28,6 @@ hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
 
 hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here
 
-hir_analysis_assoc_type_binding_not_allowed =
-    associated type bindings are not allowed here
-    .label = associated type not allowed here
-
 hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated type of a trait with uninferred generic parameters
     .suggestion = use a fully qualified path with inferred lifetimes
 
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 5c7733065c6..c1850f78f2f 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1468,12 +1468,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
         depth: usize,
         generic_args: &'tcx hir::GenericArgs<'tcx>,
     ) {
-        if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
-            self.visit_fn_like_elision(
-                generic_args.inputs(),
-                Some(generic_args.bindings[0].ty()),
-                false,
-            );
+        if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
+            self.visit_fn_like_elision(inputs, Some(output), false);
             return;
         }
 
@@ -1608,8 +1604,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             }
         }
 
-        // Hack: when resolving the type `XX` in binding like `dyn
-        // Foo<'b, Item = XX>`, the current object-lifetime default
+        // Hack: When resolving the type `XX` in an assoc ty binding like
+        // `dyn Foo<'b, Item = XX>`, the current object-lifetime default
         // would be to examine the trait `Foo` to check whether it has
         // a lifetime bound declared on `Item`. e.g., if `Foo` is
         // declared like so, then the default object lifetime bound in
@@ -1637,7 +1633,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
         // Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
         // in the trait ref `YY<...>` in `Item: YY<...>`.
-        for binding in generic_args.bindings {
+        for constraint in generic_args.constraints {
             let scope = Scope::ObjectLifetimeDefault {
                 lifetime: if has_lifetime_parameter {
                     None
@@ -1646,7 +1642,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 },
                 s: self.scope,
             };
-            // If the binding is parenthesized, then this must be `feature(return_type_notation)`.
+            // If the args are parenthesized, then this must be `feature(return_type_notation)`.
             // In that case, introduce a binder over all of the function's early and late bound vars.
             //
             // For example, given
@@ -1659,13 +1655,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             //    `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>`
             // this is going to expand to something like:
             //    `for<'a> for<'r, T> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
-            if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
+            if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation
+            {
                 let bound_vars = if let Some(type_def_id) = type_def_id
                     && self.tcx.def_kind(type_def_id) == DefKind::Trait
                     && let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars(
                         self.tcx,
                         type_def_id,
-                        binding.ident,
+                        constraint.ident,
                         ty::AssocKind::Fn,
                     ) {
                     bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).own_params.iter().map(
@@ -1686,22 +1683,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 } else {
                     self.tcx
                         .dcx()
-                        .span_delayed_bug(binding.ident.span, "bad return type notation here");
+                        .span_delayed_bug(constraint.ident.span, "bad return type notation here");
                     vec![]
                 };
                 self.with(scope, |this| {
                     let scope = Scope::Supertrait { bound_vars, s: this.scope };
                     this.with(scope, |this| {
                         let (bound_vars, _) = this.poly_trait_ref_binder_info();
-                        this.record_late_bound_vars(binding.hir_id, bound_vars);
-                        this.visit_assoc_type_binding(binding)
+                        this.record_late_bound_vars(constraint.hir_id, bound_vars);
+                        this.visit_assoc_item_constraint(constraint)
                     });
                 });
             } else if let Some(type_def_id) = type_def_id {
                 let bound_vars = BoundVarContext::supertrait_hrtb_vars(
                     self.tcx,
                     type_def_id,
-                    binding.ident,
+                    constraint.ident,
                     ty::AssocKind::Type,
                 )
                 .map(|(bound_vars, _)| bound_vars);
@@ -1710,10 +1707,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         bound_vars: bound_vars.unwrap_or_default(),
                         s: this.scope,
                     };
-                    this.with(scope, |this| this.visit_assoc_type_binding(binding));
+                    this.with(scope, |this| this.visit_assoc_item_constraint(constraint));
                 });
             } else {
-                self.with(scope, |this| this.visit_assoc_type_binding(binding));
+                self.with(scope, |this| this.visit_assoc_item_constraint(constraint));
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index d497617f644..c677fa92261 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -220,9 +220,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
                     .position(|arg| arg.hir_id() == hir_id)
                     .map(|index| (index, seg))
                     .or_else(|| {
-                        args.bindings
+                        args.constraints
                             .iter()
-                            .filter_map(TypeBinding::opt_const)
+                            .copied()
+                            .filter_map(AssocItemConstraint::ct)
                             .position(|ct| ct.hir_id == hir_id)
                             .map(|idx| (idx, seg))
                     })
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 1c99713b3ae..8a9d4cd4ac7 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -290,8 +290,8 @@ pub struct AmbiguousLifetimeBound {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)]
-pub struct AssocTypeBindingNotAllowed {
+#[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)]
+pub struct AssocItemConstraintsNotAllowedHere {
     #[primary_span]
     #[label]
     pub span: Span,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index b0ae73fcc4b..b6a1799c03f 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -230,32 +230,34 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         bounds
     }
 
-    /// Lower an associated item binding from HIR into `bounds`.
+    /// Lower an associated item constraint from the HIR into `bounds`.
     ///
     /// ### A Note on Binders
     ///
     /// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
     /// the `trait_ref` here will be `for<'a> T: Iterator`.
-    /// The `binding` data however is from *inside* the binder
+    /// The `constraint` data however is from *inside* the binder
     /// (e.g., `&'a u32`) and hence may reference bound regions.
-    #[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
-    pub(super) fn lower_assoc_item_binding(
+    #[instrument(level = "debug", skip(self, bounds, duplicates, path_span))]
+    pub(super) fn lower_assoc_item_constraint(
         &self,
         hir_ref_id: hir::HirId,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        binding: &hir::TypeBinding<'tcx>,
+        constraint: &hir::AssocItemConstraint<'tcx>,
         bounds: &mut Bounds<'tcx>,
-        dup_bindings: &mut FxIndexMap<DefId, Span>,
+        duplicates: &mut FxIndexMap<DefId, Span>,
         path_span: Span,
         only_self_bounds: OnlySelfBounds,
     ) -> Result<(), ErrorGuaranteed> {
         let tcx = self.tcx();
 
-        let assoc_kind = if binding.gen_args.parenthesized
+        let assoc_kind = if constraint.gen_args.parenthesized
             == hir::GenericArgsParentheses::ReturnTypeNotation
         {
             ty::AssocKind::Fn
-        } else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind {
+        } else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } =
+            constraint.kind
+        {
             ty::AssocKind::Const
         } else {
             ty::AssocKind::Type
@@ -272,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let candidate = if self.probe_trait_that_defines_assoc_item(
             trait_ref.def_id(),
             assoc_kind,
-            binding.ident,
+            constraint.ident,
         ) {
             // Simple case: The assoc item is defined in the current trait.
             trait_ref
@@ -284,14 +286,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 trait_ref.skip_binder().print_only_trait_name(),
                 None,
                 assoc_kind,
-                binding.ident,
+                constraint.ident,
                 path_span,
-                Some(binding),
+                Some(constraint),
             )?
         };
 
         let (assoc_ident, def_scope) =
-            tcx.adjust_ident_and_get_scope(binding.ident, candidate.def_id(), hir_ref_id);
+            tcx.adjust_ident_and_get_scope(constraint.ident, candidate.def_id(), hir_ref_id);
 
         // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
         // instead of calling `filter_by_name_and_kind` which would needlessly normalize the
@@ -306,26 +308,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             let reported = tcx
                 .dcx()
                 .struct_span_err(
-                    binding.span,
-                    format!("{} `{}` is private", assoc_item.kind, binding.ident),
+                    constraint.span,
+                    format!("{} `{}` is private", assoc_item.kind, constraint.ident),
                 )
-                .with_span_label(binding.span, format!("private {}", assoc_item.kind))
+                .with_span_label(constraint.span, format!("private {}", assoc_item.kind))
                 .emit();
             self.set_tainted_by_errors(reported);
         }
-        tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
+        tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), constraint.span, None);
 
-        dup_bindings
+        duplicates
             .entry(assoc_item.def_id)
             .and_modify(|prev_span| {
                 tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
-                    span: binding.span,
+                    span: constraint.span,
                     prev_span: *prev_span,
-                    item_name: binding.ident,
+                    item_name: constraint.ident,
                     def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
                 });
             })
-            .or_insert(binding.span);
+            .or_insert(constraint.span);
 
         let projection_term = if let ty::AssocKind::Fn = assoc_kind {
             let mut emitted_bad_param_err = None;
@@ -384,7 +386,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 alias_ty.into()
             } else {
                 return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
-                    span: binding.span,
+                    span: constraint.span,
                     ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
                     fn_span: tcx.hir().span_if_local(assoc_item.def_id),
                     note: (),
@@ -398,19 +400,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
             let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
 
-            let bound_vars = tcx.late_bound_vars(binding.hir_id);
+            let bound_vars = tcx.late_bound_vars(constraint.hir_id);
             ty::Binder::bind_with_vars(instantiation_output, bound_vars)
         } else {
             // Create the generic arguments for the associated type or constant by joining the
             // parent arguments (the arguments of the trait) and the own arguments (the ones of
             // the associated item itself) and construct an alias type using them.
             let alias_ty = candidate.map_bound(|trait_ref| {
-                let ident = Ident::new(assoc_item.name, binding.ident.span);
+                let ident = Ident::new(assoc_item.name, constraint.ident.span);
                 let item_segment = hir::PathSegment {
                     ident,
-                    hir_id: binding.hir_id,
+                    hir_id: constraint.hir_id,
                     res: Res::Err,
-                    args: Some(binding.gen_args),
+                    args: Some(constraint.gen_args),
                     infer_args: false,
                 };
 
@@ -426,26 +428,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             });
 
             // Provide the resolved type of the associated constant to `type_of(AnonConst)`.
-            if let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } =
-                binding.kind
+            if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } =
+                constraint.kind
             {
                 let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
-                let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, binding.hir_id);
+                let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id);
                 tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
             }
 
             alias_ty
         };
 
-        match binding.kind {
-            hir::TypeBindingKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
+        match constraint.kind {
+            hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
                 return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
-                    span: binding.span,
+                    span: constraint.span,
                 }));
             }
             // Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
             // to a projection predicate: `<T as Iterator>::Item = u32`.
-            hir::TypeBindingKind::Equality { term } => {
+            hir::AssocItemConstraintKind::Equality { term } => {
                 let term = match term {
                     hir::Term::Ty(ty) => self.lower_ty(ty).into(),
                     hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
@@ -469,18 +471,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
                 //                         ----  ----     ^^^^^^^
                 // NOTE(associated_const_equality): This error should be impossible to trigger
-                //                                  with associated const equality bounds.
+                //                                  with associated const equality constraints.
                 self.validate_late_bound_regions(
                     late_bound_in_projection_ty,
                     late_bound_in_term,
                     |br_name| {
                         struct_span_code_err!(
                             tcx.dcx(),
-                            binding.span,
+                            constraint.span,
                             E0582,
                             "binding for associated type `{}` references {}, \
-                                which does not appear in the trait input types",
-                            binding.ident,
+                             which does not appear in the trait input types",
+                            constraint.ident,
                             br_name
                         )
                     },
@@ -492,12 +494,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         projection_term,
                         term,
                     }),
-                    binding.span,
+                    constraint.span,
                 );
             }
             // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
             // to a bound involving a projection: `<T as Iterator>::Item: Debug`.
-            hir::TypeBindingKind::Constraint { bounds: hir_bounds } => {
+            hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
                 // NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
                 // a trait predicate, since we only want to add predicates for the `Self` type.
                 if !only_self_bounds.0 {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 9c687d3282b..821c5653040 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -1,5 +1,5 @@
 use crate::errors::{
-    self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
+    self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams,
     ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
 };
 use crate::fluent_generated as fluent;
@@ -121,7 +121,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         assoc_kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
-        binding: Option<&hir::TypeBinding<'tcx>>,
+        constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> ErrorGuaranteed
     where
         I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
@@ -135,7 +135,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
         }) {
             return self.complain_about_assoc_kind_mismatch(
-                assoc_item, assoc_kind, assoc_name, span, binding,
+                assoc_item, assoc_kind, assoc_name, span, constraint,
             );
         }
 
@@ -300,18 +300,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         assoc_kind: ty::AssocKind,
         ident: Ident,
         span: Span,
-        binding: Option<&hir::TypeBinding<'tcx>>,
+        constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> ErrorGuaranteed {
         let tcx = self.tcx();
 
         let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
-            && let Some(binding) = binding
-            && let hir::TypeBindingKind::Constraint { .. } = binding.kind
+            && let Some(constraint) = constraint
+            && let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
         {
-            let lo = if binding.gen_args.span_ext.is_dummy() {
+            let lo = if constraint.gen_args.span_ext.is_dummy() {
                 ident.span
             } else {
-                binding.gen_args.span_ext
+                constraint.gen_args.span_ext
             };
             Some(lo.between(span.shrink_to_hi()))
         } else {
@@ -319,8 +319,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         };
 
         // FIXME(associated_const_equality): This has quite a few false positives and negatives.
-        let wrap_in_braces_sugg = if let Some(binding) = binding
-            && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
+        let wrap_in_braces_sugg = if let Some(constraint) = constraint
+            && let Some(hir_ty) = constraint.ty()
             && let ty = self.lower_ty(hir_ty)
             && (ty.is_enum() || ty.references_error())
             && tcx.features().associated_const_equality
@@ -333,10 +333,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             None
         };
 
-        // For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since
+        // For equality constraints, we want to blame the term (RHS) instead of the item (LHS) since
         // one can argue that that's more “intuitive” to the user.
-        let (span, expected_because_label, expected, got) = if let Some(binding) = binding
-            && let hir::TypeBindingKind::Equality { term } = binding.kind
+        let (span, expected_because_label, expected, got) = if let Some(constraint) = constraint
+            && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind
         {
             let span = match term {
                 hir::Term::Ty(ty) => ty.span,
@@ -791,8 +791,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let path = poly_trait_ref.trait_ref.path.segments.last()?;
                 let args = path.args?;
 
-                Some(args.bindings.iter().filter_map(|binding| {
-                    let ident = binding.ident;
+                Some(args.constraints.iter().filter_map(|constraint| {
+                    let ident = constraint.ident;
                     let trait_def = path.res.def_id();
                     let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
                         tcx,
@@ -1192,14 +1192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     }
 }
 
-/// Emits an error regarding forbidden type binding associations
-pub fn prohibit_assoc_item_binding(
+/// Emit an error for the given associated item constraint.
+pub fn prohibit_assoc_item_constraint(
     tcx: TyCtxt<'_>,
-    binding: &hir::TypeBinding<'_>,
+    constraint: &hir::AssocItemConstraint<'_>,
     segment: Option<(DefId, &hir::PathSegment<'_>, Span)>,
 ) -> ErrorGuaranteed {
-    let mut err = tcx.dcx().create_err(AssocTypeBindingNotAllowed {
-        span: binding.span,
+    let mut err = tcx.dcx().create_err(AssocItemConstraintsNotAllowedHere {
+        span: constraint.span,
         fn_trait_expansion: if let Some((_, segment, span)) = segment
             && segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar
         {
@@ -1217,13 +1217,12 @@ pub fn prohibit_assoc_item_binding(
     // otherwise suggest the removal of the binding.
     if let Some((def_id, segment, _)) = segment
         && segment.args().parenthesized == hir::GenericArgsParentheses::No
-        && let hir::TypeBindingKind::Equality { term } = binding.kind
+        && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind
     {
         // Suggests removal of the offending binding
         let suggest_removal = |e: &mut Diag<'_>| {
-            let bindings = segment.args().bindings;
+            let constraints = segment.args().constraints;
             let args = segment.args().args;
-            let binding_span = binding.span;
 
             // Compute the span to remove based on the position
             // of the binding. We do that as follows:
@@ -1236,26 +1235,21 @@ pub fn prohibit_assoc_item_binding(
             //     the start of the next span or will simply be the
             //     span encomassing everything within the generics brackets
 
-            let Some(binding_index) = bindings.iter().position(|b| b.hir_id == binding.hir_id)
-            else {
+            let Some(index) = constraints.iter().position(|b| b.hir_id == constraint.hir_id) else {
                 bug!("a type binding exists but its HIR ID not found in generics");
             };
 
-            let preceding_span = if binding_index > 0 {
-                Some(bindings[binding_index - 1].span)
+            let preceding_span = if index > 0 {
+                Some(constraints[index - 1].span)
             } else {
                 args.last().map(|a| a.span())
             };
 
-            let next_span = if binding_index < bindings.len() - 1 {
-                Some(bindings[binding_index + 1].span)
-            } else {
-                None
-            };
+            let next_span = constraints.get(index + 1).map(|constraint| constraint.span);
 
             let removal_span = match (preceding_span, next_span) {
-                (Some(prec), _) => binding_span.with_lo(prec.hi()),
-                (None, Some(next)) => binding_span.with_hi(next.lo()),
+                (Some(prec), _) => constraint.span.with_lo(prec.hi()),
+                (None, Some(next)) => constraint.span.with_hi(next.lo()),
                 (None, None) => {
                     let Some(generics_span) = segment.args().span_ext() else {
                         bug!("a type binding exists but generic span is empty");
@@ -1269,7 +1263,7 @@ pub fn prohibit_assoc_item_binding(
             if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) {
                 e.span_suggestion_verbose(
                     removal_span,
-                    "consider removing this type binding",
+                    "consider removing this associated item binding",
                     suggestion,
                     Applicability::MaybeIncorrect,
                 );
@@ -1281,7 +1275,7 @@ pub fn prohibit_assoc_item_binding(
         let suggest_direct_use = |e: &mut Diag<'_>, sp: Span| {
             if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sp) {
                 e.span_suggestion_verbose(
-                    binding.span,
+                    constraint.span,
                     format!("to use `{snippet}` as a generic argument specify it directly"),
                     snippet,
                     Applicability::MaybeIncorrect,
@@ -1289,11 +1283,11 @@ pub fn prohibit_assoc_item_binding(
             }
         };
 
-        // Check if the type has a generic param with the
-        // same name as the assoc type name in type binding
+        // Check if the type has a generic param with the same name
+        // as the assoc type name in the associated item binding.
         let generics = tcx.generics_of(def_id);
         let matching_param =
-            generics.own_params.iter().find(|p| p.name.as_str() == binding.ident.as_str());
+            generics.own_params.iter().find(|p| p.name.as_str() == constraint.ident.as_str());
 
         // Now emit the appropriate suggestion
         if let Some(matching_param) = matching_param {
@@ -1322,8 +1316,7 @@ pub(crate) fn fn_trait_to_string(
 ) -> String {
     let args = trait_segment
         .args
-        .as_ref()
-        .and_then(|args| args.args.get(0))
+        .and_then(|args| args.args.first())
         .and_then(|arg| match arg {
             hir::GenericArg::Type(ty) => match ty.kind {
                 hir::TyKind::Tup(t) => t
@@ -1334,7 +1327,7 @@ pub(crate) fn fn_trait_to_string(
                 _ => tcx.sess.source_map().span_to_snippet(ty.span),
             }
             .map(|s| {
-                // `s.empty()` checks to see if the type is the unit tuple, if so we don't want a comma
+                // `is_empty()` checks to see if the type is the unit tuple, if so we don't want a comma
                 if parenthesized || s.is_empty() { format!("({s})") } else { format!("({s},)") }
             })
             .ok(),
@@ -1344,20 +1337,17 @@ pub(crate) fn fn_trait_to_string(
 
     let ret = trait_segment
         .args()
-        .bindings
+        .constraints
         .iter()
-        .find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
-            (true, hir::TypeBindingKind::Equality { term }) => {
-                let span = match term {
-                    hir::Term::Ty(ty) => ty.span,
-                    hir::Term::Const(c) => tcx.hir().span(c.hir_id),
-                };
-
-                (span != tcx.hir().span(trait_segment.hir_id))
-                    .then_some(tcx.sess.source_map().span_to_snippet(span).ok())
-                    .flatten()
+        .find_map(|c| {
+            if c.ident.name == sym::Output
+                && let Some(ty) = c.ty()
+                && ty.span != tcx.hir().span(trait_segment.hir_id)
+            {
+                tcx.sess.source_map().span_to_snippet(ty.span).ok()
+            } else {
+                None
             }
-            _ => None,
         })
         .unwrap_or_else(|| "()".to_string());
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index 7b67030836d..d641e33b299 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -1,6 +1,6 @@
 use super::IsMethodCall;
 use crate::hir_ty_lowering::{
-    errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch,
+    errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch,
     GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
 };
 use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
@@ -452,9 +452,9 @@ pub(crate) fn check_generic_arg_count(
         (gen_pos != GenericArgPosition::Type || seg.infer_args) && !gen_args.has_lifetime_params();
 
     if gen_pos != GenericArgPosition::Type
-        && let Some(b) = gen_args.bindings.first()
+        && let Some(c) = gen_args.constraints.first()
     {
-        prohibit_assoc_item_binding(tcx, b, None);
+        prohibit_assoc_item_constraint(tcx, c, None);
     }
 
     let explicit_late_bound =
@@ -566,17 +566,19 @@ pub(crate) fn check_generic_arg_count(
 
         debug!(?gen_args_info);
 
-        let reported = WrongNumberOfGenericArgs::new(
-            tcx,
-            gen_args_info,
-            seg,
-            gen_params,
-            params_offset,
-            gen_args,
-            def_id,
-        )
-        .diagnostic()
-        .emit_unless(gen_args.has_err());
+        let reported = gen_args.has_err().unwrap_or_else(|| {
+            WrongNumberOfGenericArgs::new(
+                tcx,
+                gen_args_info,
+                seg,
+                gen_params,
+                params_offset,
+                gen_args,
+                def_id,
+            )
+            .diagnostic()
+            .emit()
+        });
 
         Err(reported)
     };
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 997db338a43..b4305f6efb9 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -268,8 +268,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
         let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id);
 
-        if let Some((_, hir::Node::TypeBinding(binding))) = parents.next()
-            && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind
+        if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next()
+            && let Some(obj_ty) = constraint.ty()
         {
             if let Some((_, hir::Node::TraitRef(..))) = parents.next()
                 && let Some((_, hir::Node::Ty(ty))) = parents.next()
@@ -279,10 +279,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 return;
             }
 
-            let lo = if binding.gen_args.span_ext.is_dummy() {
-                binding.ident.span
+            let lo = if constraint.gen_args.span_ext.is_dummy() {
+                constraint.ident.span
             } else {
-                binding.gen_args.span_ext
+                constraint.gen_args.span_ext
             };
             let hi = obj_ty.span;
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 3f66f971b17..54b7f7f36ed 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -22,7 +22,7 @@ mod object_safety;
 use crate::bounds::Bounds;
 use crate::collect::HirPlaceholderCollector;
 use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
-use crate::hir_ty_lowering::errors::{prohibit_assoc_item_binding, GenericsArgsErrExtend};
+use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
 use crate::middle::resolve_bound_vars as rbv;
 use crate::require_c_abi_if_c_variadic;
@@ -324,8 +324,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             None,
             ty::BoundConstness::NotConst,
         );
-        if let Some(b) = item_segment.args().bindings.first() {
-            prohibit_assoc_item_binding(self.tcx(), b, Some((def_id, item_segment, span)));
+        if let Some(c) = item_segment.args().constraints.first() {
+            prohibit_assoc_item_constraint(self.tcx(), c, Some((def_id, item_segment, span)));
         }
         args
     }
@@ -335,7 +335,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// If this is a trait reference, you also need to pass the self type `self_ty`.
     /// The lowering process may involve applying defaulted type parameters.
     ///
-    /// Associated item bindings are not handled here!
+    /// Associated item constraints are not handled here! They are either lowered via
+    /// `lower_assoc_item_constraint` or rejected via `prohibit_assoc_item_constraint`.
     ///
     /// ### Example
     ///
@@ -349,7 +350,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///    which will have been resolved to a `def_id`
     /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
     ///    parameters are returned in the `GenericArgsRef`
-    /// 4. Associated type bindings like `Output = u32` are contained in `generic_args.bindings`.
+    /// 4. Associated item constraints like `Output = u32` are contained in `generic_args.constraints`.
     ///
     /// Note that the type listing given here is *exactly* what the user provided.
     ///
@@ -411,8 +412,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         // Skip processing if type has no generic parameters.
         // Traits always have `Self` as a generic parameter, which means they will not return early
-        // here and so associated type bindings will be handled regardless of whether there are any
-        // non-`Self` generic parameters.
+        // here and so associated item constraints will be handled regardless of whether there are
+        // any non-`Self` generic parameters.
         if generics.is_own_empty() {
             return (tcx.mk_args(parent_args), arg_count);
         }
@@ -621,8 +622,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             None,
             ty::BoundConstness::NotConst,
         );
-        if let Some(b) = item_segment.args().bindings.first() {
-            prohibit_assoc_item_binding(self.tcx(), b, Some((item_def_id, item_segment, span)));
+        if let Some(c) = item_segment.args().constraints.first() {
+            prohibit_assoc_item_constraint(self.tcx(), c, Some((item_def_id, item_segment, span)));
         }
         args
     }
@@ -654,13 +655,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// *Polymorphic* in the sense that it may bind late-bound vars.
     ///
-    /// This may generate auxiliary bounds if the trait reference contains associated item bindings.
+    /// This may generate auxiliary bounds iff the trait reference contains associated item constraints.
     ///
     /// ### Example
     ///
     /// Given the trait ref `Iterator<Item = u32>` and the self type `Ty`, this will add the
     ///
-    /// 1. *trait predicate* `<Ty as Iterator>` (known as `Foo: Iterator` in surface syntax) and the
+    /// 1. *trait predicate* `<Ty as Iterator>` (known as `Ty: Iterator` in the surface syntax) and the
     /// 2. *projection predicate* `<Ty as Iterator>::Item = u32`
     ///
     /// to `bounds`.
@@ -714,27 +715,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?poly_trait_ref);
         bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
 
-        let mut dup_bindings = FxIndexMap::default();
-        for binding in trait_segment.args().bindings {
-            // Don't register additional associated type bounds for negative bounds,
-            // since we should have emitten an error for them earlier, and they will
-            // not be well-formed!
+        let mut dup_constraints = FxIndexMap::default();
+        for constraint in trait_segment.args().constraints {
+            // Don't register any associated item constraints for negative bounds,
+            // since we should have emitted an error for them earlier, and they
+            // would not be well-formed!
             if polarity != ty::PredicatePolarity::Positive {
                 assert!(
                     self.tcx().dcx().has_errors().is_some(),
-                    "negative trait bounds should not have bindings",
+                    "negative trait bounds should not have assoc item constraints",
                 );
                 continue;
             }
 
             // Specify type to assert that error was already reported in `Err` case.
-            let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_binding(
+            let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
                 trait_ref.hir_ref_id,
                 poly_trait_ref,
-                binding,
+                constraint,
                 bounds,
-                &mut dup_bindings,
-                binding.span,
+                &mut dup_constraints,
+                constraint.span,
                 only_self_bounds,
             );
             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
@@ -766,8 +767,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             Some(self_ty),
             constness,
         );
-        if let Some(b) = trait_segment.args().bindings.first() {
-            prohibit_assoc_item_binding(self.tcx(), b, Some((trait_def_id, trait_segment, span)));
+        if let Some(c) = trait_segment.args().constraints.first() {
+            prohibit_assoc_item_constraint(
+                self.tcx(),
+                c,
+                Some((trait_def_id, trait_segment, span)),
+            );
         }
         ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
     }
@@ -849,7 +854,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// This fails if there is no such bound in the list of candidates or if there are multiple
     /// candidates in which case it reports ambiguity.
-    #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, binding), ret)]
+    #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]
     fn probe_single_bound_for_assoc_item<I>(
         &self,
         all_candidates: impl Fn() -> I,
@@ -858,7 +863,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         assoc_kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
-        binding: Option<&hir::TypeBinding<'tcx>>,
+        constraint: Option<&hir::AssocItemConstraint<'tcx>>,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
     where
         I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
@@ -877,7 +882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 assoc_kind,
                 assoc_name,
                 span,
-                binding,
+                constraint,
             );
             self.set_tainted_by_errors(reported);
             return Err(reported);
@@ -897,8 +902,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             });
             // Provide a more specific error code index entry for equality bindings.
             err.code(
-                if let Some(binding) = binding
-                    && let hir::TypeBindingKind::Equality { .. } = binding.kind
+                if let Some(constraint) = constraint
+                    && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
                 {
                     E0222
                 } else {
@@ -906,7 +911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 },
             );
 
-            // FIXME(#97583): Resugar equality bounds to type/const bindings.
+            // FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!).
             // FIXME: Turn this into a structured, translateable & more actionable suggestion.
             let mut where_bounds = vec![];
             for bound in [bound, bound2].into_iter().chain(matching_candidates) {
@@ -921,9 +926,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         bound_span,
                         format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
                     );
-                    if let Some(binding) = binding {
-                        match binding.kind {
-                            hir::TypeBindingKind::Equality { term } => {
+                    if let Some(constraint) = constraint {
+                        match constraint.kind {
+                            hir::AssocItemConstraintKind::Equality { term } => {
                                 let term: ty::Term<'_> = match term {
                                     hir::Term::Ty(ty) => self.lower_ty(ty).into(),
                                     hir::Term::Const(ct) => {
@@ -937,7 +942,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                 ));
                             }
                             // FIXME: Provide a suggestion.
-                            hir::TypeBindingKind::Constraint { bounds: _ } => {}
+                            hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
                         }
                     } else {
                         err.span_suggestion_verbose(
@@ -1540,8 +1545,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         for segment in segments {
             // Only emit the first error to avoid overloading the user with error messages.
-            if let Some(b) = segment.args().bindings.first() {
-                return Err(prohibit_assoc_item_binding(self.tcx(), b, None));
+            if let Some(c) = segment.args().constraints.first() {
+                return Err(prohibit_assoc_item_constraint(self.tcx(), c, None));
             }
         }
 
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 9ddba7a6e7a..5d435a8edf9 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -489,7 +489,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
                 .in_definition_order()
                 .filter(|item| item.kind == AssocKind::Type)
                 .filter(|item| {
-                    !self.gen_args.bindings.iter().any(|binding| binding.ident.name == item.name)
+                    !self
+                        .gen_args
+                        .constraints
+                        .iter()
+                        .any(|constraint| constraint.ident.name == item.name)
                 })
                 .map(|item| item.name.to_ident_string())
                 .collect()
@@ -679,11 +683,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
                     (last_lt.span().shrink_to_hi(), false)
                 };
                 let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
-                let has_bindings = !self.gen_args.bindings.is_empty();
+                let has_constraints = !self.gen_args.constraints.is_empty();
 
                 let sugg_prefix = if is_first { "" } else { ", " };
                 let sugg_suffix =
-                    if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" };
+                    if is_first && (has_non_lt_args || has_constraints) { ", " } else { "" };
 
                 let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
                 debug!("sugg: {:?}", sugg);
@@ -741,7 +745,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
 
                 let sugg_prefix = if is_first { "" } else { ", " };
                 let sugg_suffix =
-                    if is_first && !self.gen_args.bindings.is_empty() { ", " } else { "" };
+                    if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" };
 
                 let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
                 debug!("sugg: {:?}", sugg);
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 62abdf0afab..a8e0b3fc079 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -89,7 +89,7 @@ impl<'a> State<'a> {
             Node::Stmt(a) => self.print_stmt(a),
             Node::PathSegment(a) => self.print_path_segment(a),
             Node::Ty(a) => self.print_type(a),
-            Node::TypeBinding(a) => self.print_type_binding(a),
+            Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
             Node::TraitRef(a) => self.print_trait_ref(a),
             Node::Pat(a) => self.print_pat(a),
             Node::PatField(a) => self.print_patfield(a),
@@ -1135,7 +1135,7 @@ impl<'a> State<'a> {
         self.print_ident(segment.ident);
 
         let generic_args = segment.args();
-        if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
+        if !generic_args.args.is_empty() || !generic_args.constraints.is_empty() {
             self.print_generic_args(generic_args, true);
         }
 
@@ -1676,9 +1676,9 @@ impl<'a> State<'a> {
                     });
                 }
 
-                for binding in generic_args.bindings {
+                for constraint in generic_args.constraints {
                     start_or_comma(self);
-                    self.print_type_binding(binding);
+                    self.print_assoc_item_constraint(constraint);
                 }
 
                 if !empty.get() {
@@ -1686,13 +1686,15 @@ impl<'a> State<'a> {
                 }
             }
             hir::GenericArgsParentheses::ParenSugar => {
+                let (inputs, output) = generic_args.paren_sugar_inputs_output().unwrap();
+
                 self.word("(");
-                self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty));
+                self.commasep(Inconsistent, inputs, |s, ty| s.print_type(ty));
                 self.word(")");
 
                 self.space_if_not_bol();
                 self.word_space("->");
-                self.print_type(generic_args.bindings[0].ty());
+                self.print_type(output);
             }
             hir::GenericArgsParentheses::ReturnTypeNotation => {
                 self.word("(..)");
@@ -1700,19 +1702,19 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
-        self.print_ident(binding.ident);
-        self.print_generic_args(binding.gen_args, false);
+    fn print_assoc_item_constraint(&mut self, constraint: &hir::AssocItemConstraint<'_>) {
+        self.print_ident(constraint.ident);
+        self.print_generic_args(constraint.gen_args, false);
         self.space();
-        match binding.kind {
-            hir::TypeBindingKind::Equality { ref term } => {
+        match constraint.kind {
+            hir::AssocItemConstraintKind::Equality { ref term } => {
                 self.word_space("=");
                 match term {
                     Term::Ty(ty) => self.print_type(ty),
                     Term::Const(ref c) => self.print_anon_const(c),
                 }
             }
-            hir::TypeBindingKind::Constraint { bounds } => {
+            hir::AssocItemConstraintKind::Bound { bounds } => {
                 self.print_bounds(":", bounds);
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 7cefe189bd6..5723b73a328 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -848,19 +848,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
                     && let Some(hir::PathSegment { args: Some(generic_args), .. }) =
                         trait_ref.trait_ref.path.segments.last()
-                    && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
-                    && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
-                        ty_binding.kind
+                    && let [constraint] = generic_args.constraints
+                    && let Some(ty) = constraint.ty()
                 {
                     // Check if async function's return type was omitted.
                     // Don't emit suggestions if the found type is `impl Future<...>`.
                     debug!(?found);
                     if found.is_suggestable(self.tcx, false) {
-                        if term.span.is_empty() {
+                        if ty.span.is_empty() {
                             err.subdiagnostic(
                                 self.dcx(),
                                 errors::AddReturnTypeSuggestion::Add {
-                                    span: term.span,
+                                    span: ty.span,
                                     found: found.to_string(),
                                 },
                             );
@@ -868,10 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         } else {
                             err.subdiagnostic(
                                 self.dcx(),
-                                errors::ExpectedReturnTypeLabel::Other {
-                                    span: term.span,
-                                    expected,
-                                },
+                                errors::ExpectedReturnTypeLabel::Other { span: ty.span, expected },
                             );
                         }
                     }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 665cd883d44..639c98155e7 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -925,7 +925,7 @@ impl<'hir> Map<'hir> {
                     .with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
             }
             Node::Ty(ty) => ty.span,
-            Node::TypeBinding(tb) => tb.span,
+            Node::AssocItemConstraint(constraint) => constraint.span,
             Node::TraitRef(tr) => tr.path.span,
             Node::Pat(pat) => pat.span,
             Node::PatField(field) => field.span,
@@ -1190,7 +1190,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         Node::Stmt(_) => node_str("stmt"),
         Node::PathSegment(_) => node_str("path segment"),
         Node::Ty(_) => node_str("type"),
-        Node::TypeBinding(_) => node_str("type binding"),
+        Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
         Node::TraitRef(_) => node_str("trait ref"),
         Node::Pat(_) => node_str("pat"),
         Node::PatField(_) => node_str("pattern field"),
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index d845e8ab90d..fcedc1a4af3 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -7,8 +7,8 @@ use ast::token::IdentIsRaw;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::{
-    self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
-    AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
+    self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint,
+    AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
     Path, PathSegment, QSelf,
 };
 use rustc_errors::{Applicability, Diag, PResult};
@@ -720,10 +720,7 @@ impl<'a> Parser<'a> {
                         ));
                     }
                     let kind = if self.eat(&token::Colon) {
-                        // Parse associated type constraint bound.
-
-                        let bounds = self.parse_generic_bounds()?;
-                        AssocConstraintKind::Bound { bounds }
+                        AssocItemConstraintKind::Bound { bounds: self.parse_generic_bounds()? }
                     } else if self.eat(&token::Eq) {
                         self.parse_assoc_equality_term(
                             ident,
@@ -735,17 +732,17 @@ impl<'a> Parser<'a> {
                     };
 
                     let span = lo.to(self.prev_token.span);
-                    // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
-                    if let AssocConstraintKind::Bound { .. } = kind {
-                        if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
-                            && args.inputs.is_empty()
-                            && matches!(args.output, ast::FnRetTy::Default(..))
-                        {
-                            self.psess.gated_spans.gate(sym::return_type_notation, span);
-                        }
+
+                    if let AssocItemConstraintKind::Bound { .. } = kind
+                        && let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
+                        && args.inputs.is_empty()
+                        && let ast::FnRetTy::Default(..) = args.output
+                    {
+                        self.psess.gated_spans.gate(sym::return_type_notation, span);
                     }
+
                     let constraint =
-                        AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
+                        AssocItemConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
                     Ok(Some(AngleBracketedArg::Constraint(constraint)))
                 } else {
                     // we only want to suggest `:` and `=` in contexts where the previous token
@@ -772,7 +769,7 @@ impl<'a> Parser<'a> {
         ident: Ident,
         gen_args: Option<&GenericArgs>,
         eq: Span,
-    ) -> PResult<'a, AssocConstraintKind> {
+    ) -> PResult<'a, AssocItemConstraintKind> {
         let arg = self.parse_generic_arg(None)?;
         let span = ident.span.to(self.prev_token.span);
         let term = match arg {
@@ -820,7 +817,7 @@ impl<'a> Parser<'a> {
                 return Err(err);
             }
         };
-        Ok(AssocConstraintKind::Equality { term })
+        Ok(AssocItemConstraintKind::Equality { term })
     }
 
     /// We do not permit arbitrary expressions as const arguments. They must be one of:
@@ -941,7 +938,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Given a arg inside of generics, we try to destructure it as if it were the LHS in
-    /// `LHS = ...`, i.e. an associated type binding.
+    /// `LHS = ...`, i.e. an associated item binding.
     /// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the
     /// identifier, and any GAT arguments.
     fn get_ident_from_generic_arg(
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 6bb9cff5319..d49298781a2 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -477,9 +477,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
         hir_visit::walk_generic_args(self, ga)
     }
 
-    fn visit_assoc_type_binding(&mut self, type_binding: &'v hir::TypeBinding<'v>) {
-        self.record("TypeBinding", Id::Node(type_binding.hir_id), type_binding);
-        hir_visit::walk_assoc_type_binding(self, type_binding)
+    fn visit_assoc_item_constraint(&mut self, constraint: &'v hir::AssocItemConstraint<'v>) {
+        self.record("AssocItemConstraint", Id::Node(constraint.hir_id), constraint);
+        hir_visit::walk_assoc_item_constraint(self, constraint)
     }
 
     fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
@@ -688,7 +688,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
         ast_visit::walk_path_segment(self, path_segment)
     }
 
-    // `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one
+    // `GenericArgs` has one inline use (in `ast::AssocItemConstraint::gen_args`) and one
     // non-inline use (in `ast::PathSegment::args`). The latter case is more
     // common, so we implement `visit_generic_args` and tolerate the double
     // counting in the former case.
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index bcdd6716cc3..bcf2c9a9206 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1148,7 +1148,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
         self.diag_metadata.currently_processing_generic_args = prev;
     }
 
-    fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) {
+    fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) {
         self.visit_ident(constraint.ident);
         if let Some(ref gen_args) = constraint.gen_args {
             // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
@@ -1157,13 +1157,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
             });
         }
         match constraint.kind {
-            AssocConstraintKind::Equality { ref term } => match term {
+            AssocItemConstraintKind::Equality { ref term } => match term {
                 Term::Ty(ty) => self.visit_ty(ty),
                 Term::Const(c) => {
                     self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
                 }
             },
-            AssocConstraintKind::Bound { ref bounds } => {
+            AssocItemConstraintKind::Bound { ref bounds } => {
                 self.record_lifetime_params_for_impl_trait(constraint.id);
                 walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
             }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 9daa22f89d2..ec24eac4a9d 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -508,7 +508,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 let ast::AngleBracketedArg::Constraint(constraint) = param else {
                     continue;
                 };
-                let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else {
+                let ast::AssocItemConstraintKind::Bound { bounds } = &constraint.kind else {
                     continue;
                 };
                 for bound in bounds {
@@ -3390,11 +3390,11 @@ fn mk_where_bound_predicate(
         };
         let mut segments = ThinVec::from(preceding);
 
-        let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocConstraint {
+        let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocItemConstraint {
             id: DUMMY_NODE_ID,
             ident: last.ident,
             gen_args: None,
-            kind: ast::AssocConstraintKind::Equality {
+            kind: ast::AssocItemConstraintKind::Equality {
                 term: ast::Term::Ty(ast::ptr::P(ast::Ty {
                     kind: ast::TyKind::Path(None, poly_trait_ref.trait_ref.path.clone()),
                     id: DUMMY_NODE_ID,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 9336148fd67..8dcbac88880 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -450,7 +450,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     }
 
     /// When after several dereferencing, the reference satisfies the trait
-    /// binding. This function provides dereference suggestion for this
+    /// bound. This function provides dereference suggestion for this
     /// specific situation.
     fn suggest_dereferences(
         &self,
@@ -777,7 +777,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     }
 
     /// We tried to apply the bound to an `fn` or closure. Check whether calling it would
-    /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
+    /// evaluate to a type that *would* satisfy the trait bound. If it would, suggest calling
     /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
     fn suggest_fn_call(
         &self,
@@ -1240,7 +1240,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         let param_env = obligation.param_env;
 
-        // Try to apply the original trait binding obligation by borrowing.
+        // Try to apply the original trait bound by borrowing.
         let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
                                  blacklist: &[DefId]|
          -> bool {
@@ -4903,14 +4903,12 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
         // `async fn` should always lower to a single bound... but don't ICE.
         return None;
     };
-    let Some(hir::PathSegment { args: Some(generics), .. }) =
-        trait_ref.trait_ref.path.segments.last()
+    let Some(hir::PathSegment { args: Some(args), .. }) = trait_ref.trait_ref.path.segments.last()
     else {
         // desugaring to a single path segment for `Future<...>`.
         return None;
     };
-    let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
-        generics.bindings.get(0).map(|binding| binding.kind)
+    let Some(future_output_ty) = args.constraints.first().and_then(|constraint| constraint.ty())
     else {
         // Also should never happen.
         return None;
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index bccad29e0a9..ac927e9a194 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -11,7 +11,7 @@ use thin_vec::ThinVec;
 
 use crate::clean::{self, simplify, Lifetime};
 use crate::clean::{
-    clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_bindings,
+    clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_constraints,
     clean_ty_generics,
 };
 use crate::core::DocContext;
@@ -121,7 +121,7 @@ fn synthesize_auto_trait_impl<'tcx>(
         kind: Box::new(clean::ImplItem(Box::new(clean::Impl {
             safety: hir::Safety::Safe,
             generics,
-            trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref, ThinVec::new())),
+            trait_: Some(clean_trait_ref_with_constraints(cx, trait_ref, ThinVec::new())),
             for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None),
             items: Vec::new(),
             polarity,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 29be3a70d54..4c7a2ecdb53 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -10,7 +10,7 @@ use thin_vec::ThinVec;
 
 use crate::clean;
 use crate::clean::{
-    clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty_generics,
+    clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_constraints, clean_ty_generics,
 };
 use crate::core::DocContext;
 
@@ -95,7 +95,7 @@ pub(crate) fn synthesize_blanket_impls(
                     ),
                     // FIXME(eddyb) compute both `trait_` and `for_` from
                     // the post-inference `trait_ref`, as it's more accurate.
-                    trait_: Some(clean_trait_ref_with_bindings(
+                    trait_: Some(clean_trait_ref_with_constraints(
                         cx,
                         ty::Binder::dummy(trait_ref.instantiate_identity()),
                         ThinVec::new(),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 2919a4c4beb..c7366ce1a68 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -20,7 +20,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
 
 use crate::clean::{
     self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
-    clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_bindings,
+    clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_constraints,
     clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes,
     AttributesExt, ImplKind, ItemId, Type,
 };
@@ -566,7 +566,7 @@ pub(crate) fn build_impl(
     };
     let polarity = tcx.impl_polarity(did);
     let trait_ = associated_trait
-        .map(|t| clean_trait_ref_with_bindings(cx, ty::Binder::dummy(t), ThinVec::new()));
+        .map(|t| clean_trait_ref_with_constraints(cx, ty::Binder::dummy(t), ThinVec::new()));
     if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
@@ -688,7 +688,7 @@ fn build_module_items(
                                     name: prim_ty.as_sym(),
                                     args: clean::GenericArgs::AngleBracketed {
                                         args: Default::default(),
-                                        bindings: ThinVec::new(),
+                                        constraints: ThinVec::new(),
                                     },
                                 }],
                             },
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 73737da482d..839bfdf44af 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -231,10 +231,10 @@ fn clean_generic_bound<'tcx>(
     })
 }
 
-pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
+pub(crate) fn clean_trait_ref_with_constraints<'tcx>(
     cx: &mut DocContext<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
-    bindings: ThinVec<TypeBinding>,
+    constraints: ThinVec<AssocItemConstraint>,
 ) -> Path {
     let kind = cx.tcx.def_kind(trait_ref.def_id()).into();
     if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
@@ -245,7 +245,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
         cx,
         trait_ref.def_id(),
         true,
-        bindings,
+        constraints,
         trait_ref.map_bound(|tr| tr.args),
     );
 
@@ -254,14 +254,14 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
     path
 }
 
-fn clean_poly_trait_ref_with_bindings<'tcx>(
+fn clean_poly_trait_ref_with_constraints<'tcx>(
     cx: &mut DocContext<'tcx>,
     poly_trait_ref: ty::PolyTraitRef<'tcx>,
-    bindings: ThinVec<TypeBinding>,
+    constraints: ThinVec<AssocItemConstraint>,
 ) -> GenericBound {
     GenericBound::TraitBound(
         PolyTrait {
-            trait_: clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings),
+            trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
             generic_params: clean_bound_vars(poly_trait_ref.bound_vars()),
         },
         hir::TraitBoundModifier::None,
@@ -395,7 +395,7 @@ fn clean_poly_trait_predicate<'tcx>(
     let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
     Some(WherePredicate::BoundPredicate {
         ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None, None),
-        bounds: vec![clean_poly_trait_ref_with_bindings(cx, poly_trait_ref, ThinVec::new())],
+        bounds: vec![clean_poly_trait_ref_with_constraints(cx, poly_trait_ref, ThinVec::new())],
         bound_params: Vec::new(),
     })
 }
@@ -481,8 +481,11 @@ fn clean_projection<'tcx>(
         return clean_middle_opaque_bounds(cx, bounds);
     }
 
-    let trait_ =
-        clean_trait_ref_with_bindings(cx, ty.map_bound(|ty| ty.trait_ref(cx.tcx)), ThinVec::new());
+    let trait_ = clean_trait_ref_with_constraints(
+        cx,
+        ty.map_bound(|ty| ty.trait_ref(cx.tcx)),
+        ThinVec::new(),
+    );
     let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None, None);
     let self_def_id = if let Some(def_id) = def_id {
         cx.tcx.opt_parent(def_id).or(Some(def_id))
@@ -522,7 +525,7 @@ fn projection_to_path_segment<'tcx>(
                 def_id,
             )
             .into(),
-            bindings: Default::default(),
+            constraints: Default::default(),
         },
     }
 }
@@ -1453,8 +1456,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
                             _ => return true,
                         }
                         match &assoc.args {
-                            GenericArgs::AngleBracketed { args, bindings } => {
-                                if !bindings.is_empty()
+                            GenericArgs::AngleBracketed { args, constraints } => {
+                                if !constraints.is_empty()
                                     || generics
                                         .params
                                         .iter()
@@ -2135,7 +2138,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
 
             let bindings = obj
                 .projection_bounds()
-                .map(|pb| TypeBinding {
+                .map(|pb| AssocItemConstraint {
                     assoc: projection_to_path_segment(
                         pb.map_bound(|pb| {
                             pb
@@ -2149,7 +2152,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
                         }),
                         cx,
                     ),
-                    kind: TypeBindingKind::Equality {
+                    kind: AssocItemConstraintKind::Equality {
                         term: clean_middle_term(pb.map_bound(|pb| pb.term), cx),
                     },
                 })
@@ -2198,7 +2201,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
                             def_id,
                         )
                         .into(),
-                        bindings: Default::default(),
+                        constraints: Default::default(),
                     },
                 },
                 should_show_cast: false,
@@ -2304,14 +2307,14 @@ fn clean_middle_opaque_bounds<'tcx>(
                 .filter_map(|bound| {
                     if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
                         if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() {
-                            Some(TypeBinding {
+                            Some(AssocItemConstraint {
                                 assoc: projection_to_path_segment(
                                     // FIXME: This needs to be made resilient for `AliasTerm`s that
                                     // are associated consts.
                                     bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
                                     cx,
                                 ),
-                                kind: TypeBindingKind::Equality {
+                                kind: AssocItemConstraintKind::Equality {
                                     term: clean_middle_term(bound.kind().rebind(proj.term), cx),
                                 },
                             })
@@ -2324,7 +2327,7 @@ fn clean_middle_opaque_bounds<'tcx>(
                 })
                 .collect();
 
-            Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings))
+            Some(clean_poly_trait_ref_with_constraints(cx, trait_ref, bindings))
         })
         .collect::<Vec<_>>();
 
@@ -2505,11 +2508,12 @@ fn clean_generic_args<'tcx>(
     cx: &mut DocContext<'tcx>,
 ) -> GenericArgs {
     // FIXME(return_type_notation): Fix RTN parens rendering
-    if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
-        let output = clean_ty(generic_args.bindings[0].ty(), cx);
-        let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
-        let inputs =
-            generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
+    if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
+        let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
+        let output = match output.kind {
+            hir::TyKind::Tup(&[]) => None,
+            _ => Some(Box::new(clean_ty(output, cx))),
+        };
         GenericArgs::Parenthesized { inputs, output }
     } else {
         let args = generic_args
@@ -2536,9 +2540,12 @@ fn clean_generic_args<'tcx>(
             })
             .collect::<Vec<_>>()
             .into();
-        let bindings =
-            generic_args.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::<ThinVec<_>>();
-        GenericArgs::AngleBracketed { args, bindings }
+        let constraints = generic_args
+            .constraints
+            .iter()
+            .map(|c| clean_assoc_item_constraint(c, cx))
+            .collect::<ThinVec<_>>();
+        GenericArgs::AngleBracketed { args, constraints }
     }
 }
 
@@ -3107,20 +3114,20 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
     })
 }
 
-fn clean_type_binding<'tcx>(
-    type_binding: &hir::TypeBinding<'tcx>,
+fn clean_assoc_item_constraint<'tcx>(
+    constraint: &hir::AssocItemConstraint<'tcx>,
     cx: &mut DocContext<'tcx>,
-) -> TypeBinding {
-    TypeBinding {
+) -> AssocItemConstraint {
+    AssocItemConstraint {
         assoc: PathSegment {
-            name: type_binding.ident.name,
-            args: clean_generic_args(type_binding.gen_args, cx),
+            name: constraint.ident.name,
+            args: clean_generic_args(constraint.gen_args, cx),
         },
-        kind: match type_binding.kind {
-            hir::TypeBindingKind::Equality { ref term } => {
-                TypeBindingKind::Equality { term: clean_hir_term(term, cx) }
+        kind: match constraint.kind {
+            hir::AssocItemConstraintKind::Equality { ref term } => {
+                AssocItemConstraintKind::Equality { term: clean_hir_term(term, cx) }
             }
-            hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
+            hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound {
                 bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(),
             },
         },
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 5a3ccb6239a..af61eb6ae8d 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -90,10 +90,10 @@ pub(crate) fn merge_bounds(
         let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
 
         match last.args {
-            PP::AngleBracketed { ref mut bindings, .. } => {
-                bindings.push(clean::TypeBinding {
+            PP::AngleBracketed { ref mut constraints, .. } => {
+                constraints.push(clean::AssocItemConstraint {
                     assoc: assoc.clone(),
-                    kind: clean::TypeBindingKind::Equality { term: rhs.clone() },
+                    kind: clean::AssocItemConstraintKind::Equality { term: rhs.clone() },
                 });
             }
             PP::Parenthesized { ref mut output, .. } => match output {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 711aef34c27..3f84da310dd 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1626,9 +1626,9 @@ impl Type {
         if let Type::ImplTrait(mut v) = self
             && let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop()
             && let Some(segment) = trait_.segments.pop()
-            && let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
-            && let Some(binding) = bindings.pop()
-            && let TypeBindingKind::Equality { term } = binding.kind
+            && let GenericArgs::AngleBracketed { mut constraints, .. } = segment.args
+            && let Some(constraint) = constraints.pop()
+            && let AssocItemConstraintKind::Equality { term } = constraint.kind
             && let Term::Type(ty) = term
         {
             ty
@@ -2260,34 +2260,38 @@ impl GenericArg {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub(crate) enum GenericArgs {
-    AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec<TypeBinding> },
+    AngleBracketed { args: Box<[GenericArg]>, constraints: ThinVec<AssocItemConstraint> },
     Parenthesized { inputs: Box<[Type]>, output: Option<Box<Type>> },
 }
 
 impl GenericArgs {
     pub(crate) fn is_empty(&self) -> bool {
         match self {
-            GenericArgs::AngleBracketed { args, bindings } => {
-                args.is_empty() && bindings.is_empty()
+            GenericArgs::AngleBracketed { args, constraints } => {
+                args.is_empty() && constraints.is_empty()
             }
             GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
         }
     }
-    pub(crate) fn bindings<'a>(&'a self) -> Box<dyn Iterator<Item = TypeBinding> + 'a> {
+    pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> {
         match self {
-            GenericArgs::AngleBracketed { bindings, .. } => Box::new(bindings.iter().cloned()),
+            GenericArgs::AngleBracketed { constraints, .. } => {
+                Box::new(constraints.iter().cloned())
+            }
             GenericArgs::Parenthesized { output, .. } => Box::new(
                 output
                     .as_ref()
-                    .map(|ty| TypeBinding {
+                    .map(|ty| AssocItemConstraint {
                         assoc: PathSegment {
                             name: sym::Output,
                             args: GenericArgs::AngleBracketed {
                                 args: Vec::new().into_boxed_slice(),
-                                bindings: ThinVec::new(),
+                                constraints: ThinVec::new(),
                             },
                         },
-                        kind: TypeBindingKind::Equality { term: Term::Type((**ty).clone()) },
+                        kind: AssocItemConstraintKind::Equality {
+                            term: Term::Type((**ty).clone()),
+                        },
                     })
                     .into_iter(),
             ),
@@ -2546,18 +2550,27 @@ pub(crate) struct ProcMacro {
     pub(crate) helpers: Vec<Symbol>,
 }
 
-/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
-/// `A: Send + Sync` in `Foo<A: Send + Sync>`).
+/// A constraint on an associated item.
+///
+/// ### Examples
+///
+/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
+/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
+/// * the `A: Bound` in `Trait<A: Bound>`
+/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
+/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
+/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub(crate) struct TypeBinding {
+pub(crate) struct AssocItemConstraint {
     pub(crate) assoc: PathSegment,
-    pub(crate) kind: TypeBindingKind,
+    pub(crate) kind: AssocItemConstraintKind,
 }
 
+/// The kind of [associated item constraint][AssocItemConstraint].
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub(crate) enum TypeBindingKind {
+pub(crate) enum AssocItemConstraintKind {
     Equality { term: Term },
-    Constraint { bounds: Vec<GenericBound> },
+    Bound { bounds: Vec<GenericBound> },
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 803650beaf6..24a01414c70 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -2,9 +2,10 @@ use crate::clean::auto_trait::synthesize_auto_trait_impls;
 use crate::clean::blanket_impl::synthesize_blanket_impls;
 use crate::clean::render_macro_matchers::render_macro_matcher;
 use crate::clean::{
-    clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
-    ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
-    PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind,
+    clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline,
+    AssocItemConstraint, AssocItemConstraintKind, Crate, ExternalCrate, Generic, GenericArg,
+    GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, PathSegment, Primitive,
+    PrimitiveType, Term, Type,
 };
 use crate::core::DocContext;
 use crate::html::format::visibility_to_src_with_space;
@@ -200,11 +201,11 @@ fn can_elide_generic_arg<'tcx>(
     actual.skip_binder() == default.skip_binder()
 }
 
-fn clean_middle_generic_args_with_bindings<'tcx>(
+fn clean_middle_generic_args_with_constraints<'tcx>(
     cx: &mut DocContext<'tcx>,
     did: DefId,
     has_self: bool,
-    bindings: ThinVec<TypeBinding>,
+    constraints: ThinVec<AssocItemConstraint>,
     ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
 ) -> GenericArgs {
     let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did);
@@ -219,17 +220,19 @@ fn clean_middle_generic_args_with_bindings<'tcx>(
             // The trait's first substitution is the one after self, if there is one.
             match ty.skip_binder().kind() {
                 ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
-                _ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
+                _ => return GenericArgs::AngleBracketed { args: args.into(), constraints },
             };
-        let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
-            TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => {
+        let output = constraints.into_iter().next().and_then(|binding| match binding.kind {
+            AssocItemConstraintKind::Equality { term: Term::Type(ty) }
+                if ty != Type::Tuple(Vec::new()) =>
+            {
                 Some(Box::new(ty))
             }
             _ => None,
         });
         GenericArgs::Parenthesized { inputs, output }
     } else {
-        GenericArgs::AngleBracketed { args: args.into(), bindings }
+        GenericArgs::AngleBracketed { args: args.into(), constraints }
     }
 }
 
@@ -237,7 +240,7 @@ pub(super) fn clean_middle_path<'tcx>(
     cx: &mut DocContext<'tcx>,
     did: DefId,
     has_self: bool,
-    bindings: ThinVec<TypeBinding>,
+    constraints: ThinVec<AssocItemConstraint>,
     args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
 ) -> Path {
     let def_kind = cx.tcx.def_kind(did);
@@ -246,7 +249,7 @@ pub(super) fn clean_middle_path<'tcx>(
         res: Res::Def(def_kind, did),
         segments: thin_vec![PathSegment {
             name,
-            args: clean_middle_generic_args_with_bindings(cx, did, has_self, bindings, args),
+            args: clean_middle_generic_args_with_constraints(cx, did, has_self, constraints, args),
         }],
     }
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 57949001774..d20cef745ab 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -420,8 +420,8 @@ impl clean::GenericArgs {
     fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
         display_fn(move |f| {
             match self {
-                clean::GenericArgs::AngleBracketed { args, bindings } => {
-                    if !args.is_empty() || !bindings.is_empty() {
+                clean::GenericArgs::AngleBracketed { args, constraints } => {
+                    if !args.is_empty() || !constraints.is_empty() {
                         if f.alternate() {
                             f.write_str("<")?;
                         } else {
@@ -439,15 +439,15 @@ impl clean::GenericArgs {
                                 write!(f, "{}", arg.print(cx))?;
                             }
                         }
-                        for binding in bindings.iter() {
+                        for constraint in constraints.iter() {
                             if comma {
                                 f.write_str(", ")?;
                             }
                             comma = true;
                             if f.alternate() {
-                                write!(f, "{:#}", binding.print(cx))?;
+                                write!(f, "{:#}", constraint.print(cx))?;
                             } else {
-                                write!(f, "{}", binding.print(cx))?;
+                                write!(f, "{}", constraint.print(cx))?;
                             }
                         }
                         if f.alternate() {
@@ -1706,7 +1706,7 @@ impl clean::ImportSource {
     }
 }
 
-impl clean::TypeBinding {
+impl clean::AssocItemConstraint {
     pub(crate) fn print<'a, 'tcx: 'a>(
         &'a self,
         cx: &'a Context<'tcx>,
@@ -1715,11 +1715,11 @@ impl clean::TypeBinding {
             f.write_str(self.assoc.name.as_str())?;
             self.assoc.args.print(cx).fmt(f)?;
             match self.kind {
-                clean::TypeBindingKind::Equality { ref term } => {
+                clean::AssocItemConstraintKind::Equality { ref term } => {
                     f.write_str(" = ")?;
                     term.print(cx).fmt(f)?;
                 }
-                clean::TypeBindingKind::Constraint { ref bounds } => {
+                clean::AssocItemConstraintKind::Bound { ref bounds } => {
                     if !bounds.is_empty() {
                         f.write_str(": ")?;
                         print_generic_bounds(bounds, cx).fmt(f)?;
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index e635c1e611d..bc8bdffc331 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -727,7 +727,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
                         name: *name,
                         args: clean::GenericArgs::AngleBracketed {
                             args: Vec::new().into_boxed_slice(),
-                            bindings: ThinVec::new(),
+                            constraints: ThinVec::new(),
                         },
                     })
                     .collect(),
@@ -1049,7 +1049,7 @@ fn simplify_fn_type<'tcx, 'a>(
         // So in here, we can add it directly and look for its own type parameters (so for `Option`,
         // we will look for them but not for `T`).
         let mut ty_generics = Vec::new();
-        let mut ty_bindings = Vec::new();
+        let mut ty_constraints = Vec::new();
         if let Some(arg_generics) = arg.generic_args() {
             for ty in arg_generics.into_iter().filter_map(|gen| match gen {
                 clean::GenericArg::Type(ty) => Some(ty),
@@ -1067,14 +1067,14 @@ fn simplify_fn_type<'tcx, 'a>(
                     cache,
                 );
             }
-            for binding in arg_generics.bindings() {
-                simplify_fn_binding(
+            for constraint in arg_generics.constraints() {
+                simplify_fn_constraint(
                     self_,
                     generics,
-                    &binding,
+                    &constraint,
                     tcx,
                     recurse + 1,
-                    &mut ty_bindings,
+                    &mut ty_constraints,
                     rgen,
                     is_return,
                     cache,
@@ -1137,7 +1137,7 @@ fn simplify_fn_type<'tcx, 'a>(
                             *stored_bounds = type_bounds;
                         }
                     }
-                    ty_bindings.push((
+                    ty_constraints.push((
                         RenderTypeId::AssociatedType(name),
                         vec![RenderType {
                             id: Some(RenderTypeId::Index(idx)),
@@ -1152,17 +1152,17 @@ fn simplify_fn_type<'tcx, 'a>(
         if id.is_some() || !ty_generics.is_empty() {
             res.push(RenderType {
                 id,
-                bindings: if ty_bindings.is_empty() { None } else { Some(ty_bindings) },
+                bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
                 generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
             });
         }
     }
 }
 
-fn simplify_fn_binding<'tcx, 'a>(
+fn simplify_fn_constraint<'tcx, 'a>(
     self_: Option<&'a Type>,
     generics: &Generics,
-    binding: &'a clean::TypeBinding,
+    constraint: &'a clean::AssocItemConstraint,
     tcx: TyCtxt<'tcx>,
     recurse: usize,
     res: &mut Vec<(RenderTypeId, Vec<RenderType>)>,
@@ -1170,9 +1170,9 @@ fn simplify_fn_binding<'tcx, 'a>(
     is_return: bool,
     cache: &Cache,
 ) {
-    let mut ty_binding_constraints = Vec::new();
-    let ty_binding_assoc = RenderTypeId::AssociatedType(binding.assoc.name);
-    for gen in &binding.assoc.args {
+    let mut ty_constraints = Vec::new();
+    let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name);
+    for gen in &constraint.assoc.args {
         match gen {
             clean::GenericArg::Type(arg) => simplify_fn_type(
                 self_,
@@ -1180,7 +1180,7 @@ fn simplify_fn_binding<'tcx, 'a>(
                 &arg,
                 tcx,
                 recurse + 1,
-                &mut ty_binding_constraints,
+                &mut ty_constraints,
                 rgen,
                 is_return,
                 cache,
@@ -1190,11 +1190,11 @@ fn simplify_fn_binding<'tcx, 'a>(
             | clean::GenericArg::Infer => {}
         }
     }
-    for binding in binding.assoc.args.bindings() {
-        simplify_fn_binding(
+    for constraint in constraint.assoc.args.constraints() {
+        simplify_fn_constraint(
             self_,
             generics,
-            &binding,
+            &constraint,
             tcx,
             recurse + 1,
             res,
@@ -1203,8 +1203,8 @@ fn simplify_fn_binding<'tcx, 'a>(
             cache,
         );
     }
-    match &binding.kind {
-        clean::TypeBindingKind::Equality { term } => {
+    match &constraint.kind {
+        clean::AssocItemConstraintKind::Equality { term } => {
             if let clean::Term::Type(arg) = &term {
                 simplify_fn_type(
                     self_,
@@ -1212,14 +1212,14 @@ fn simplify_fn_binding<'tcx, 'a>(
                     arg,
                     tcx,
                     recurse + 1,
-                    &mut ty_binding_constraints,
+                    &mut ty_constraints,
                     rgen,
                     is_return,
                     cache,
                 );
             }
         }
-        clean::TypeBindingKind::Constraint { bounds } => {
+        clean::AssocItemConstraintKind::Bound { bounds } => {
             for bound in &bounds[..] {
                 if let Some(path) = bound.get_trait_path() {
                     let ty = Type::Path { path };
@@ -1229,7 +1229,7 @@ fn simplify_fn_binding<'tcx, 'a>(
                         &ty,
                         tcx,
                         recurse + 1,
-                        &mut ty_binding_constraints,
+                        &mut ty_constraints,
                         rgen,
                         is_return,
                         cache,
@@ -1238,7 +1238,7 @@ fn simplify_fn_binding<'tcx, 'a>(
             }
         }
     }
-    res.push((ty_binding_assoc, ty_binding_constraints));
+    res.push((ty_constrained_assoc, ty_constraints));
 }
 
 /// Return the full list of types when bounds have been resolved.
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7f5c12219b8..7e6a19aa52e 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -153,9 +153,9 @@ impl FromWithTcx<clean::GenericArgs> for GenericArgs {
     fn from_tcx(args: clean::GenericArgs, tcx: TyCtxt<'_>) -> Self {
         use clean::GenericArgs::*;
         match args {
-            AngleBracketed { args, bindings } => GenericArgs::AngleBracketed {
+            AngleBracketed { args, constraints } => GenericArgs::AngleBracketed {
                 args: args.into_vec().into_tcx(tcx),
-                bindings: bindings.into_tcx(tcx),
+                bindings: constraints.into_tcx(tcx),
             },
             Parenthesized { inputs, output } => GenericArgs::Parenthesized {
                 inputs: inputs.into_vec().into_tcx(tcx),
@@ -187,22 +187,22 @@ impl FromWithTcx<clean::Constant> for Constant {
     }
 }
 
-impl FromWithTcx<clean::TypeBinding> for TypeBinding {
-    fn from_tcx(binding: clean::TypeBinding, tcx: TyCtxt<'_>) -> Self {
+impl FromWithTcx<clean::AssocItemConstraint> for TypeBinding {
+    fn from_tcx(constraint: clean::AssocItemConstraint, tcx: TyCtxt<'_>) -> Self {
         TypeBinding {
-            name: binding.assoc.name.to_string(),
-            args: binding.assoc.args.into_tcx(tcx),
-            binding: binding.kind.into_tcx(tcx),
+            name: constraint.assoc.name.to_string(),
+            args: constraint.assoc.args.into_tcx(tcx),
+            binding: constraint.kind.into_tcx(tcx),
         }
     }
 }
 
-impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
-    fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self {
-        use clean::TypeBindingKind::*;
+impl FromWithTcx<clean::AssocItemConstraintKind> for TypeBindingKind {
+    fn from_tcx(kind: clean::AssocItemConstraintKind, tcx: TyCtxt<'_>) -> Self {
+        use clean::AssocItemConstraintKind::*;
         match kind {
             Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
-            Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
+            Bound { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index dc935ed3d7f..2b389d4f9b1 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
-    GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
+    GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, AssocItemConstraint,
     WherePredicate,
 };
 use rustc_hir_analysis::lower_ty;
@@ -54,9 +54,9 @@ fn emit_lint(
     poly_trait: &rustc_hir::PolyTraitRef<'_>,
     bounds: GenericBounds<'_>,
     index: usize,
-    // The bindings that were implied, used for suggestion purposes since removing a bound with associated types
-    // means we might need to then move it to a different bound
-    implied_bindings: &[TypeBinding<'_>],
+    // The constraints that were implied, used for suggestion purposes since removing a bound with
+    // associated types means we might need to then move it to a different bound.
+    implied_constraints: &[AssocItemConstraint<'_>],
     bound: &ImplTraitBound<'_>,
 ) {
     let implied_by = snippet(cx, bound.span, "..");
@@ -83,29 +83,29 @@ fn emit_lint(
 
             let mut sugg = vec![(implied_span_extended, String::new())];
 
-            // We also might need to include associated type binding that were specified in the implied bound,
+            // We also might need to include associated item constraints that were specified in the implied bound,
             // but omitted in the implied-by bound:
             // `fn f() -> impl Deref<Target = u8> + DerefMut`
             // If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`
-            let omitted_assoc_tys: Vec<_> = implied_bindings
+            let omitted_constraints: Vec<_> = implied_constraints
                 .iter()
-                .filter(|binding| !bound.bindings.iter().any(|b| b.ident == binding.ident))
+                .filter(|constraint| !bound.constraints.iter().any(|c| c.ident == constraint.ident))
                 .collect();
 
-            if !omitted_assoc_tys.is_empty() {
-                // `<>` needs to be added if there aren't yet any generic arguments or bindings
-                let needs_angle_brackets = bound.args.is_empty() && bound.bindings.is_empty();
-                let insert_span = match (bound.args, bound.bindings) {
-                    ([.., arg], [.., binding]) => arg.span().max(binding.span).shrink_to_hi(),
+            if !omitted_constraints.is_empty() {
+                // `<>` needs to be added if there aren't yet any generic arguments or constraints
+                let needs_angle_brackets = bound.args.is_empty() && bound.constraints.is_empty();
+                let insert_span = match (bound.args, bound.constraints) {
+                    ([.., arg], [.., constraint]) => arg.span().max(constraint.span).shrink_to_hi(),
                     ([.., arg], []) => arg.span().shrink_to_hi(),
-                    ([], [.., binding]) => binding.span.shrink_to_hi(),
+                    ([], [.., constraint]) => constraint.span.shrink_to_hi(),
                     ([], []) => bound.span.shrink_to_hi(),
                 };
 
-                let mut associated_tys_sugg = if needs_angle_brackets {
+                let mut constraints_sugg = if needs_angle_brackets {
                     "<".to_owned()
                 } else {
-                    // If angle brackets aren't needed (i.e., there are already generic arguments or bindings),
+                    // If angle brackets aren't needed (i.e., there are already generic arguments or constraints),
                     // we need to add a comma:
                     // `impl A<B, C >`
                     //             ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:
@@ -113,16 +113,16 @@ fn emit_lint(
                     ", ".to_owned()
                 };
 
-                for (index, binding) in omitted_assoc_tys.into_iter().enumerate() {
+                for (index, constraint) in omitted_constraints.into_iter().enumerate() {
                     if index > 0 {
-                        associated_tys_sugg += ", ";
+                        constraints_sugg += ", ";
                     }
-                    associated_tys_sugg += &snippet(cx, binding.span, "..");
+                    constraints_sugg += &snippet(cx, constraint.span, "..");
                 }
                 if needs_angle_brackets {
-                    associated_tys_sugg += ">";
+                    constraints_sugg += ">";
                 }
-                sugg.push((insert_span, associated_tys_sugg));
+                sugg.push((insert_span, constraints_sugg));
             }
 
             diag.multipart_suggestion_with_style(
@@ -229,8 +229,8 @@ struct ImplTraitBound<'tcx> {
     trait_def_id: DefId,
     /// The generic arguments on the `impl Trait` bound
     args: &'tcx [GenericArg<'tcx>],
-    /// The associated types on this bound
-    bindings: &'tcx [TypeBinding<'tcx>],
+    /// The associated item constraints of this bound
+    constraints: &'tcx [AssocItemConstraint<'tcx>],
 }
 
 /// Given an `impl Trait` type, gets all the supertraits from each bound ("implied bounds").
@@ -253,7 +253,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
                 Some(ImplTraitBound {
                     predicates,
                     args: path.args.map_or([].as_slice(), |p| p.args),
-                    bindings: path.args.map_or([].as_slice(), |p| p.bindings),
+                    constraints: path.args.map_or([].as_slice(), |p| p.constraints),
                     trait_def_id,
                     span: bound.span(),
                 })
@@ -310,20 +310,20 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
         if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
             && let [.., path] = poly_trait.trait_ref.path.segments
             && let implied_args = path.args.map_or([].as_slice(), |a| a.args)
-            && let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
+            && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
             && let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
             && let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)
             // If the implied bound has a type binding that also exists in the implied-by trait,
             // then we shouldn't lint. See #11880 for an example.
             && let assocs = cx.tcx.associated_items(bound.trait_def_id)
-            && !implied_bindings.iter().any(|binding| {
+            && !implied_constraints.iter().any(|constraint| {
                 assocs
-                    .filter_by_name_unhygienic(binding.ident.name)
+                    .filter_by_name_unhygienic(constraint.ident.name)
                     .next()
                     .is_some_and(|assoc| assoc.kind == ty::AssocKind::Type)
                 })
         {
-            emit_lint(cx, poly_trait, bounds, index, implied_bindings, bound);
+            emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound);
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 97a245b76d4..2091e74665f 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::{
     AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
     ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath,
-    TraitItemRef, TyKind, TypeBindingKind,
+    TraitItemRef, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
@@ -307,17 +307,12 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
         && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
         && let Some(segment) = trait_ref.trait_ref.path.segments.last()
         && let Some(generic_args) = segment.args
-        && generic_args.bindings.len() == 1
-        && let TypeBindingKind::Equality {
-            term:
-                rustc_hir::Term::Ty(rustc_hir::Ty {
-                    kind: TyKind::Path(QPath::Resolved(_, path)),
-                    ..
-                }),
-        } = &generic_args.bindings[0].kind
-        && path.segments.len() == 1
+        && let [constraint] = generic_args.constraints
+        && let Some(ty) = constraint.ty()
+        && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
+        && let [segment] = path.segments
     {
-        return Some(&path.segments[0]);
+        return Some(segment);
     }
 
     None
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 4cd5f3b81e5..25c7e5d38b3 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -4,8 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
-    FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind,
-    TypeBindingKind,
+    FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -138,10 +137,9 @@ fn future_trait_ref<'tcx>(
 fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> {
     if let Some(segment) = trait_ref.path.segments.last()
         && let Some(args) = segment.args
-        && args.bindings.len() == 1
-        && let binding = &args.bindings[0]
-        && binding.ident.name == sym::Output
-        && let TypeBindingKind::Equality { term: Term::Ty(output) } = binding.kind
+        && let [constraint] = args.constraints
+        && constraint.ident.name == sym::Output
+        && let Some(output) = constraint.ty()
     {
         return Some(output);
     }
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index d4a5f547211..bbdde3049db 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -108,7 +108,7 @@ pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
 pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool {
     match (l, r) {
         (AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r),
-        (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_constraint(l, r),
+        (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_item_constraint(l, r),
         _ => false,
     }
 }
@@ -802,8 +802,8 @@ fn eq_term(l: &Term, r: &Term) -> bool {
     }
 }
 
-pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
-    use AssocConstraintKind::*;
+pub fn eq_assoc_item_constraint(l: &AssocItemConstraint, r: &AssocItemConstraint) -> bool {
+    use AssocItemConstraintKind::*;
     eq_id(l.ident, r.ident)
         && match (&l.kind, &r.kind) {
             (Equality { term: l }, Equality { term: r }) => eq_term(l, r),
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 817d4095eb5..c649c179468 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -9,7 +9,7 @@ use rustc_hir::MatchSource::TryDesugar;
 use rustc_hir::{
     ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
     GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
-    PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
+    PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, AssocItemConstraint,
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::LateContext;
@@ -486,7 +486,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool {
         if left.parenthesized == right.parenthesized {
             over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work
-                && over(left.bindings, right.bindings, |l, r| self.eq_type_binding(l, r))
+                && over(left.constraints, right.constraints, |l, r| self.eq_assoc_type_binding(l, r))
         } else {
             false
         }
@@ -518,8 +518,8 @@ impl HirEqInterExpr<'_, '_, '_> {
         }
     }
 
-    fn eq_type_binding(&mut self, left: &TypeBinding<'_>, right: &TypeBinding<'_>) -> bool {
-        left.ident.name == right.ident.name && self.eq_ty(left.ty(), right.ty())
+    fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool {
+        left.ident.name == right.ident.name && self.eq_ty(left.ty().expect("expected assoc type binding"), right.ty().expect("expected assoc type binding"))
     }
 
     fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool {
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 75dea90d994..7d14d9e727a 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -140,7 +140,7 @@ pub(crate) enum SegmentParam<'a> {
     Const(&'a ast::AnonConst),
     LifeTime(&'a ast::Lifetime),
     Type(&'a ast::Ty),
-    Binding(&'a ast::AssocConstraint),
+    Binding(&'a ast::AssocItemConstraint),
 }
 
 impl<'a> SegmentParam<'a> {
@@ -175,9 +175,9 @@ impl<'a> Rewrite for SegmentParam<'a> {
     }
 }
 
-impl Rewrite for ast::AssocConstraint {
+impl Rewrite for ast::AssocItemConstraint {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        use ast::AssocConstraintKind::{Bound, Equality};
+        use ast::AssocItemConstraintKind::{Bound, Equality};
 
         let mut result = String::with_capacity(128);
         result.push_str(rewrite_ident(context, self.ident));
@@ -205,14 +205,14 @@ impl Rewrite for ast::AssocConstraint {
     }
 }
 
-impl Rewrite for ast::AssocConstraintKind {
+impl Rewrite for ast::AssocItemConstraintKind {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         match self {
-            ast::AssocConstraintKind::Equality { term } => match term {
+            ast::AssocItemConstraintKind::Equality { term } => match term {
                 Term::Ty(ty) => ty.rewrite(context, shape),
                 Term::Const(c) => c.rewrite(context, shape),
             },
-            ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
+            ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
         }
     }
 }
diff --git a/tests/rustdoc-ui/invalid_associated_const.rs b/tests/rustdoc-ui/invalid_associated_const.rs
index 6f211a383a6..f93834268f6 100644
--- a/tests/rustdoc-ui/invalid_associated_const.rs
+++ b/tests/rustdoc-ui/invalid_associated_const.rs
@@ -2,8 +2,8 @@
 
 trait T {
     type A: S<C<X = 0i32> = 34>;
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait S {
diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr
index 5eaddc2b8c9..6e5ddc44982 100644
--- a/tests/rustdoc-ui/invalid_associated_const.stderr
+++ b/tests/rustdoc-ui/invalid_associated_const.stderr
@@ -1,22 +1,22 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/invalid_associated_const.rs:4:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/invalid_associated_const.rs:4:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
diff --git a/tests/rustdoc-ui/issue-102467.rs b/tests/rustdoc-ui/issue-102467.rs
index a27e6156979..d9bd48103d2 100644
--- a/tests/rustdoc-ui/issue-102467.rs
+++ b/tests/rustdoc-ui/issue-102467.rs
@@ -5,8 +5,8 @@
 
 trait T {
     type A: S<C<X = 0i32> = 34>;
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait S {
diff --git a/tests/rustdoc-ui/issue-102467.stderr b/tests/rustdoc-ui/issue-102467.stderr
index 119ca949e99..99f91102319 100644
--- a/tests/rustdoc-ui/issue-102467.stderr
+++ b/tests/rustdoc-ui/issue-102467.stderr
@@ -1,22 +1,22 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102467.rs:7:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102467.rs:7:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs
index 969c2c43b71..fd922cd0f1d 100644
--- a/tests/ui/associated-consts/issue-102335-const.rs
+++ b/tests/ui/associated-consts/issue-102335-const.rs
@@ -2,8 +2,8 @@
 
 trait T {
     type A: S<C<X = 0i32> = 34>;
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait S {
diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/associated-consts/issue-102335-const.stderr
index 905d7c75c20..dc1631220e2 100644
--- a/tests/ui/associated-consts/issue-102335-const.stderr
+++ b/tests/ui/associated-consts/issue-102335-const.stderr
@@ -1,22 +1,22 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-const.rs:4:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-const.rs:4:17
    |
 LL |     type A: S<C<X = 0i32> = 34>;
-   |                 ^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<X = 0i32> = 34>;
    |                ~~~~~~~~~~
diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.rs b/tests/ui/associated-type-bounds/issue-102335-ty.rs
index b2df68b18ae..86bde6367a4 100644
--- a/tests/ui/associated-type-bounds/issue-102335-ty.rs
+++ b/tests/ui/associated-type-bounds/issue-102335-ty.rs
@@ -1,13 +1,13 @@
 trait T {
     type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait T2 {
     type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait Q {}
diff --git a/tests/ui/associated-type-bounds/issue-102335-ty.stderr b/tests/ui/associated-type-bounds/issue-102335-ty.stderr
index cf30b0a4f6c..cd585f7f7d8 100644
--- a/tests/ui/associated-type-bounds/issue-102335-ty.stderr
+++ b/tests/ui/associated-type-bounds/issue-102335-ty.stderr
@@ -1,45 +1,45 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-ty.rs:2:17
    |
 LL |     type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
-   |                 ^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
    |                ~~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-ty.rs:2:17
    |
 LL |     type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
-   |                 ^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
    |                ~~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-ty.rs:8:17
    |
 LL |     type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
-   |                 ^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
    |                 ~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-ty.rs:8:17
    |
 LL |     type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
-   |                 ^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
    |                 ~~~~~~~~~~
diff --git a/tests/ui/associated-type-bounds/no-gat-position.rs b/tests/ui/associated-type-bounds/no-gat-position.rs
index 5005c5027f4..cb62c882468 100644
--- a/tests/ui/associated-type-bounds/no-gat-position.rs
+++ b/tests/ui/associated-type-bounds/no-gat-position.rs
@@ -4,7 +4,7 @@ pub trait Iter {
     type Item<'a>: 'a where Self: 'a;
 
     fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
-    //~^ ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
 }
 
 impl Iter for () {
diff --git a/tests/ui/associated-type-bounds/no-gat-position.stderr b/tests/ui/associated-type-bounds/no-gat-position.stderr
index c348d33c3a9..e167ac1fda4 100644
--- a/tests/ui/associated-type-bounds/no-gat-position.stderr
+++ b/tests/ui/associated-type-bounds/no-gat-position.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/no-gat-position.rs:6:56
    |
 LL |     fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
-   |                                                        ^^^^^^^^^ associated type not allowed here
+   |                                                        ^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs
index 43b0208461e..f0a7d1e46b1 100644
--- a/tests/ui/associated-types/associated-types-eq-2.rs
+++ b/tests/ui/associated-types/associated-types-eq-2.rs
@@ -18,14 +18,14 @@ impl Tr1 for isize {
 // Test for when the assoc type is
 // specified as an equality constraint
 impl Tr1<A = usize> for usize {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR not all trait items implemented, missing: `A`
     fn boo(&self) -> usize { 42 }
 }
 
 // Test for a wronngly used equality constraint in a func arg
 fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 
 
 
@@ -38,28 +38,28 @@ trait Tr2<T1, T2, T3> {
 // (Note: E0229 is emitted only for the first erroneous equality
 // constraint (T2) not for any subequent ones (e.g. T3))
 impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
 }
 
 // Test for when equality constraint's ident matches a
 // generic param's ident but has different case
 impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
 }
 
 // Test for when equality constraint's ident
 // matches none of the generic param idents
 impl Tr2<i32, X = Qux, Y = usize> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
 }
 
 // Test for when the term in equality constraint is itself generic
 struct GenericTerm<T> { _t: T }
 impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR trait takes 3 generic arguments but 2 generic arguments were supplied
 }
 
@@ -74,7 +74,7 @@ trait Tr3<const N: i32, T2, T3> {
 // (Deliberately spread over multiple lines to test that
 // our suggestion spans are kosher in the face of such formatting)
 impl Tr3<N
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
 //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
 = 42, T2 = Qux, T3 = usize> for Bar {
@@ -83,7 +83,7 @@ impl Tr3<N
 // Test for when equality constraint's ident
 // matches the const param's ident but has a different case
 impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
 //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
 }
@@ -91,14 +91,14 @@ impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
 // Test for when equality constraint's ident
 // matches the const param ident but the constraint is a type arg
 impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
 }
 
 // Test for when equality constraint's ident
 // matches a type param ident but the constraint is a const arg
 impl Tr3<42, T2 = 42, T3 = usize> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
 //~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
 }
@@ -106,7 +106,7 @@ impl Tr3<42, T2 = 42, T3 = usize> for Bar {
 // Test for when equality constraint's ident
 // matches none of the param idents
 impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
 //~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
 }
@@ -117,7 +117,7 @@ impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
 struct St<'a, T> { v: &'a T }
 
 impl<'a, T> St<'a , T = Qux> {
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied
 }
 
diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr
index b68c82f590c..53e4e59128e 100644
--- a/tests/ui/associated-types/associated-types-eq-2.stderr
+++ b/tests/ui/associated-types/associated-types-eq-2.stderr
@@ -43,13 +43,13 @@ LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:20:10
    |
 LL | impl Tr1<A = usize> for usize {
-   |          ^^^^^^^^^ associated type not allowed here
+   |          ^^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr1<A = usize> for usize {
    |         ~~~~~~~~~~~
@@ -63,13 +63,13 @@ LL |     type A;
 LL | impl Tr1<A = usize> for usize {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `A` in implementation
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:27:31
    |
 LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
-   |                               ^^^^^ associated type not allowed here
+   |                               ^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
    |                              ~~~~~~~
@@ -92,11 +92,11 @@ help: add missing generic arguments
 LL | impl Tr2<i32, T2, T3, T2 = Qux, T3 = usize> for Bar {
    |             ++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:40:15
    |
 LL | impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
-   |               ^^^^^^^^ associated type not allowed here
+   |               ^^^^^^^^ associated item constraint not allowed here
    |
 help: to use `Qux` as a generic argument specify it directly
    |
@@ -121,13 +121,13 @@ help: add missing generic arguments
 LL | impl Tr2<i32, T2, T3, t2 = Qux, T3 = usize> for Qux {
    |             ++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:47:15
    |
 LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
-   |               ^^^^^^^^ associated type not allowed here
+   |               ^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
    |             ~~~~~~~~~~
@@ -150,13 +150,13 @@ help: add missing generic arguments
 LL | impl Tr2<i32, T2, T3, X = Qux, Y = usize> for Bar {
    |             ++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:54:15
    |
 LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
-   |               ^^^^^^^ associated type not allowed here
+   |               ^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
    |             ~~~~~~~~~
@@ -179,11 +179,11 @@ help: add missing generic argument
 LL | impl Tr2<i32, Qux, T3, T3 = GenericTerm<i32>> for Bar {
    |                  ++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:61:20
    |
 LL | impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
-   |                    ^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here
+   |                    ^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here
    |
 help: to use `GenericTerm<i32>` as a generic argument specify it directly
    |
@@ -206,7 +206,7 @@ help: add missing generic arguments
 LL | impl Tr3<N, T2, T3, N
    |          ++++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:76:10
    |
 LL |   impl Tr3<N
@@ -215,7 +215,7 @@ LL | |
 LL | |
 LL | |
 LL | | = 42, T2 = Qux, T3 = usize> for Bar {
-   | |____^ associated type not allowed here
+   | |____^ associated item constraint not allowed here
    |
 help: to use `42` as a generic argument specify it directly
    |
@@ -238,13 +238,13 @@ help: add missing generic arguments
 LL | impl Tr3<N, T2, T3, n = 42, T2 = Qux, T3 = usize> for Qux {
    |          ++++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:85:10
    |
 LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
-   |          ^^^^^^ associated type not allowed here
+   |          ^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
    |          ~~~~~~~
@@ -265,13 +265,13 @@ help: add missing generic arguments
 LL | impl Tr3<N, T2, T3, N = u32, T2 = Qux, T3 = usize> for Bar {
    |          ++++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:93:10
    |
 LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
-   |          ^^^^^^^ associated type not allowed here
+   |          ^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
    |          ~~~~~~~~
@@ -294,13 +294,13 @@ help: add missing generic arguments
 LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar {
    |            ++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:100:14
    |
 LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
-   |              ^^^^^^^ associated type not allowed here
+   |              ^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
    |            ~~~~~~~~~
@@ -321,13 +321,13 @@ help: add missing generic arguments
 LL | impl Tr3<N, T2, T3, X = 42, Y = Qux, Z = usize> for Bar {
    |          ++++++++++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:108:10
    |
 LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
-   |          ^^^^^^ associated type not allowed here
+   |          ^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
    |          ~~~~~~~
@@ -348,11 +348,11 @@ help: add missing generic argument
 LL | impl<'a, T> St<'a, T , T = Qux> {
    |                  +++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-2.rs:119:21
    |
 LL | impl<'a, T> St<'a , T = Qux> {
-   |                     ^^^^^^^ associated type not allowed here
+   |                     ^^^^^^^ associated item constraint not allowed here
    |
 help: to use `Qux` as a generic argument specify it directly
    |
diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.rs b/tests/ui/associated-types/associated-types-eq-expr-path.rs
index 143992f29f1..4561e596c66 100644
--- a/tests/ui/associated-types/associated-types-eq-expr-path.rs
+++ b/tests/ui/associated-types/associated-types-eq-expr-path.rs
@@ -11,6 +11,6 @@ impl Foo for isize {
 }
 
 pub fn main() {
-    let x: isize = Foo::<A=usize>::bar();
-    //~^ ERROR associated type bindings are not allowed here
+    let x: isize = Foo::<A = usize>::bar();
+    //~^ ERROR associated item constraints are not allowed here
 }
diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.stderr b/tests/ui/associated-types/associated-types-eq-expr-path.stderr
index 7559f3b7c2e..3d0e3e61eca 100644
--- a/tests/ui/associated-types/associated-types-eq-expr-path.stderr
+++ b/tests/ui/associated-types/associated-types-eq-expr-path.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/associated-types-eq-expr-path.rs:14:26
    |
-LL |     let x: isize = Foo::<A=usize>::bar();
-   |                          ^^^^^^^ associated type not allowed here
+LL |     let x: isize = Foo::<A = usize>::bar();
+   |                          ^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
index 68a750778ad..637678692bd 100644
--- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
@@ -8,7 +8,7 @@ trait Super1<'a> {
 }
 
 impl Super1<'_, bar(): Send> for () {}
-//~^ ERROR associated type bindings are not allowed here
+//~^ ERROR associated item constraints are not allowed here
 //~| ERROR not all trait items implemented
 
 fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
index d925c7316b6..b07c5735dff 100644
--- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
@@ -7,11 +7,11 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/rtn-in-impl-signature.rs:10:17
    |
 LL | impl Super1<'_, bar(): Send> for () {}
-   |                 ^^^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^^^ associated item constraint not allowed here
 
 error[E0046]: not all trait items implemented, missing: `bar`
   --> $DIR/rtn-in-impl-signature.rs:10:1
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
index 79743abe409..fbf1553c182 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
@@ -8,7 +8,7 @@ const T: usize = 42;
 
 impl Foo<N = 3> for Bar {
 //~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
-//~| ERROR associated type bindings are not allowed here
+//~| ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
         [0u8; 3]
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
index 941764a575e..a132859b412 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
@@ -24,11 +24,11 @@ help: add missing generic argument
 LL | impl Foo<N, N = 3> for Bar {
    |          ++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-89013-no-kw.rs:9:10
    |
 LL | impl Foo<N = 3> for Bar {
-   |          ^^^^^ associated type not allowed here
+   |          ^^^^^ associated item constraint not allowed here
    |
 help: to use `3` as a generic argument specify it directly
    |
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
index 335d0d94e83..c9c7ff3a170 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
@@ -9,7 +9,7 @@ const T: usize = 42;
 impl Foo<N = const 3> for Bar {
 //~^ ERROR expected lifetime, type, or constant, found keyword `const`
 //~| ERROR trait takes 1 generic
-//~| ERROR associated type bindings are not allowed here
+//~| ERROR associated item constraints are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
         [0u8; 3]
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
index a4c9e065c15..2fdd1208565 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
@@ -36,11 +36,11 @@ help: add missing generic argument
 LL | impl Foo<N, N = const 3> for Bar {
    |          ++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-89013.rs:9:10
    |
 LL | impl Foo<N = const 3> for Bar {
-   |          ^^^^^^^^^^^ associated type not allowed here
+   |          ^^^^^^^^^^^ associated item constraint not allowed here
    |
 help: to use `3` as a generic argument specify it directly
    |
diff --git a/tests/ui/error-codes/E0229.rs b/tests/ui/error-codes/E0229.rs
index 558baae37f7..da2758dfba8 100644
--- a/tests/ui/error-codes/E0229.rs
+++ b/tests/ui/error-codes/E0229.rs
@@ -10,10 +10,10 @@ impl Foo for isize {
     fn boo(&self) -> usize { 42 }
 }
 
-fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-//~^ ERROR associated type bindings are not allowed here [E0229]
-//~| ERROR associated type bindings are not allowed here [E0229]
-//~| ERROR associated type bindings are not allowed here [E0229]
+fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+//~^ ERROR associated item constraints are not allowed here [E0229]
+//~| ERROR associated item constraints are not allowed here [E0229]
+//~| ERROR associated item constraints are not allowed here [E0229]
 //~| ERROR the trait bound `I: Foo` is not satisfied
 //~| ERROR the trait bound `I: Foo` is not satisfied
 
diff --git a/tests/ui/error-codes/E0229.stderr b/tests/ui/error-codes/E0229.stderr
index ae7dc9ac265..7d9cedc3bdc 100644
--- a/tests/ui/error-codes/E0229.stderr
+++ b/tests/ui/error-codes/E0229.stderr
@@ -1,58 +1,58 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/E0229.rs:13:25
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                         ^^^^^ associated type not allowed here
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                         ^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                        ~~~~~~~
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                        ~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/E0229.rs:13:25
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                         ^^^^^ associated type not allowed here
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                         ^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                        ~~~~~~~
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                        ~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/E0229.rs:13:25
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                         ^^^^^ associated type not allowed here
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                         ^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                        ~~~~~~~
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                        ~~~~~~~~~
 
 error[E0277]: the trait bound `I: Foo` is not satisfied
   --> $DIR/E0229.rs:13:15
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |               ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I`
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I`
    |
 help: consider restricting type parameter `I`
    |
-LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
+LL | fn baz<I: Foo>(x: &<I as Foo<A = Bar>>::A) {}
    |         +++++
 
 error[E0277]: the trait bound `I: Foo` is not satisfied
-  --> $DIR/E0229.rs:13:37
+  --> $DIR/E0229.rs:13:39
    |
-LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
-   |                                     ^^ the trait `Foo` is not implemented for `I`
+LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
+   |                                       ^^ the trait `Foo` is not implemented for `I`
    |
 help: consider restricting type parameter `I`
    |
-LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
+LL | fn baz<I: Foo>(x: &<I as Foo<A = Bar>>::A) {}
    |         +++++
 
 error: aborting due to 5 previous errors
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs
index b8ce9c85b72..ff528274c59 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs
@@ -16,7 +16,7 @@ impl Fn<()> for Foo {
 }
 struct Foo1;
 impl FnOnce() for Foo1 {
-    //~^ ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
     //~| ERROR manual implementations of `FnOnce` are experimental
     //~| ERROR not all trait items implemented
     extern "rust-call" fn call_once(self, args: ()) -> () {}
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index c3f161469e3..ed9ecc732b5 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -105,11 +105,11 @@ LL | impl FnOnce() for Foo1 {
    |
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
    |
 LL | impl FnOnce() for Foo1 {
-   |      ^^^^^^^^ associated type not allowed here
+   |      ^^^^^^^^ associated item constraint not allowed here
    |
 help: parenthesized trait syntax expands to `FnOnce<(), Output=()>`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
diff --git a/tests/ui/fn/issue-39259.rs b/tests/ui/fn/issue-39259.rs
index 16983b652fc..d4569a9094b 100644
--- a/tests/ui/fn/issue-39259.rs
+++ b/tests/ui/fn/issue-39259.rs
@@ -4,7 +4,7 @@
 struct S;
 
 impl Fn(u32) -> u32 for S {
-    //~^ ERROR associated type bindings are not allowed here [E0229]
+    //~^ ERROR associated item constraints are not allowed here [E0229]
     //~| ERROR expected a `FnMut(u32)` closure, found `S`
     fn call(&self) -> u32 {
         //~^ ERROR method `call` has 1 parameter but the declaration in trait `call` has 2
diff --git a/tests/ui/fn/issue-39259.stderr b/tests/ui/fn/issue-39259.stderr
index 47150a3c155..095a5c47231 100644
--- a/tests/ui/fn/issue-39259.stderr
+++ b/tests/ui/fn/issue-39259.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-39259.rs:6:17
    |
 LL | impl Fn(u32) -> u32 for S {
-   |                 ^^^ associated type not allowed here
+   |                 ^^^ associated item constraint not allowed here
    |
 help: parenthesized trait syntax expands to `Fn<(u32,), Output=u32>`
   --> $DIR/issue-39259.rs:6:6
diff --git a/tests/ui/generic-associated-types/issue-102335-gat.rs b/tests/ui/generic-associated-types/issue-102335-gat.rs
index 3a4a0c10771..0be6ee3930f 100644
--- a/tests/ui/generic-associated-types/issue-102335-gat.rs
+++ b/tests/ui/generic-associated-types/issue-102335-gat.rs
@@ -1,7 +1,7 @@
 trait T {
     type A: S<C<(), i32 = ()> = ()>;
-    //~^ ERROR associated type bindings are not allowed here
-    //~| ERROR associated type bindings are not allowed here
+    //~^ ERROR associated item constraints are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
 
 trait Q {}
diff --git a/tests/ui/generic-associated-types/issue-102335-gat.stderr b/tests/ui/generic-associated-types/issue-102335-gat.stderr
index 23b114a3a55..b4772486e6e 100644
--- a/tests/ui/generic-associated-types/issue-102335-gat.stderr
+++ b/tests/ui/generic-associated-types/issue-102335-gat.stderr
@@ -1,22 +1,22 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-gat.rs:2:21
    |
 LL |     type A: S<C<(), i32 = ()> = ()>;
-   |                     ^^^^^^^^ associated type not allowed here
+   |                     ^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<(), i32 = ()> = ()>;
    |                   ~~~~~~~~~~
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-102335-gat.rs:2:21
    |
 LL |     type A: S<C<(), i32 = ()> = ()>;
-   |                     ^^^^^^^^ associated type not allowed here
+   |                     ^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type A: S<C<(), i32 = ()> = ()>;
    |                   ~~~~~~~~~~
diff --git a/tests/ui/issues/issue-23543.rs b/tests/ui/issues/issue-23543.rs
index 843e1a8a83a..248bf77a708 100644
--- a/tests/ui/issues/issue-23543.rs
+++ b/tests/ui/issues/issue-23543.rs
@@ -5,7 +5,7 @@ struct Foo;
 pub trait D {
     fn f<T>(self)
         where T<Bogus = Foo>: A;
-        //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~^ ERROR associated item constraints are not allowed here [E0229]
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-23543.stderr b/tests/ui/issues/issue-23543.stderr
index d917a4c51d5..17243aefbbc 100644
--- a/tests/ui/issues/issue-23543.stderr
+++ b/tests/ui/issues/issue-23543.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-23543.rs:7:17
    |
 LL |         where T<Bogus = Foo>: A;
-   |                 ^^^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-23544.rs b/tests/ui/issues/issue-23544.rs
index 6ad00b2fba4..bbd05a59353 100644
--- a/tests/ui/issues/issue-23544.rs
+++ b/tests/ui/issues/issue-23544.rs
@@ -3,7 +3,7 @@ pub trait A: Copy {}
 pub trait D {
     fn f<T>(self)
         where T<Bogus = Self::AlsoBogus>: A;
-        //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~^ ERROR associated item constraints are not allowed here [E0229]
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-23544.stderr b/tests/ui/issues/issue-23544.stderr
index 2a7e93f0eb7..8d652a9da27 100644
--- a/tests/ui/issues/issue-23544.stderr
+++ b/tests/ui/issues/issue-23544.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-23544.rs:5:17
    |
 LL |         where T<Bogus = Self::AlsoBogus>: A;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-24682.rs b/tests/ui/issues/issue-24682.rs
index 0d1ab73417c..1bd42f3cbe3 100644
--- a/tests/ui/issues/issue-24682.rs
+++ b/tests/ui/issues/issue-24682.rs
@@ -2,17 +2,17 @@ trait A: Sized {
     type N;
     fn x() ->
         Self<
-          N= //~ ERROR associated type bindings are not allowed here
+          N= //~ ERROR associated item constraints are not allowed here
           Self::N> {
         loop {}
     }
     fn y(&self) ->
         std
-           <N=()> //~ ERROR associated type bindings are not allowed here
+           <N=()> //~ ERROR associated item constraints are not allowed here
            ::option::Option<()>
     { None }
     fn z(&self) ->
-        u32<N=()> //~ ERROR associated type bindings are not allowed here
+        u32<N=()> //~ ERROR associated item constraints are not allowed here
     { 42 }
 
 }
diff --git a/tests/ui/issues/issue-24682.stderr b/tests/ui/issues/issue-24682.stderr
index e1943bf4d68..a107e8b52cd 100644
--- a/tests/ui/issues/issue-24682.stderr
+++ b/tests/ui/issues/issue-24682.stderr
@@ -1,21 +1,21 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-24682.rs:5:11
    |
 LL | /           N=
 LL | |           Self::N> {
-   | |_________________^ associated type not allowed here
+   | |_________________^ associated item constraint not allowed here
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-24682.rs:11:13
    |
 LL |            <N=()>
-   |             ^^^^ associated type not allowed here
+   |             ^^^^ associated item constraint not allowed here
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-24682.rs:15:13
    |
 LL |         u32<N=()>
-   |             ^^^^ associated type not allowed here
+   |             ^^^^ associated item constraint not allowed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-39687.rs b/tests/ui/issues/issue-39687.rs
index cbb721fbb57..58f981b63d1 100644
--- a/tests/ui/issues/issue-39687.rs
+++ b/tests/ui/issues/issue-39687.rs
@@ -2,5 +2,5 @@
 
 fn main() {
     <fn() as Fn()>::call;
-    //~^ ERROR associated type bindings are not allowed here [E0229]
+    //~^ ERROR associated item constraints are not allowed here [E0229]
 }
diff --git a/tests/ui/issues/issue-39687.stderr b/tests/ui/issues/issue-39687.stderr
index f4742115a19..87e5fdc2d8f 100644
--- a/tests/ui/issues/issue-39687.stderr
+++ b/tests/ui/issues/issue-39687.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-39687.rs:4:14
    |
 LL |     <fn() as Fn()>::call;
-   |              ^^^^ associated type not allowed here
+   |              ^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-43431.rs b/tests/ui/issues/issue-43431.rs
index e7ec35105f7..0286336910e 100644
--- a/tests/ui/issues/issue-43431.rs
+++ b/tests/ui/issues/issue-43431.rs
@@ -7,7 +7,7 @@ trait CallSingle<A, B> {
 impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
     fn call(&self, a: A) -> B {
         <Self as Fn(A) -> B>::call(self, (a,))
-        //~^ ERROR associated type bindings are not allowed here
+        //~^ ERROR associated item constraints are not allowed here
     }
 }
 
diff --git a/tests/ui/issues/issue-43431.stderr b/tests/ui/issues/issue-43431.stderr
index 6d47ba27162..27a720408e4 100644
--- a/tests/ui/issues/issue-43431.stderr
+++ b/tests/ui/issues/issue-43431.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-43431.rs:9:27
    |
 LL |         <Self as Fn(A) -> B>::call(self, (a,))
-   |                           ^ associated type not allowed here
+   |                           ^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs
index a47e71afcf0..78069e682c1 100644
--- a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs
+++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs
@@ -3,6 +3,6 @@
 struct Foo {}
 impl Foo {
     fn bar(foo: Foo<Target = usize>) {}
-    //~^ associated type bindings are not allowed here
+    //~^ associated item constraints are not allowed here
 }
 fn main() {}
diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr
index d6da842e6ab..f8d919fd68b 100644
--- a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr
+++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr
@@ -1,10 +1,10 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21
    |
 LL |     fn bar(foo: Foo<Target = usize>) {}
-   |                     ^^^^^^^^^^^^^^ associated type not allowed here
+   |                     ^^^^^^^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     fn bar(foo: Foo<Target = usize>) {}
    |                    ~~~~~~~~~~~~~~~~
diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs
index ee39a8c49c0..7a67297c763 100644
--- a/tests/ui/lifetimes/issue-95023.rs
+++ b/tests/ui/lifetimes/issue-95023.rs
@@ -2,7 +2,7 @@ struct ErrorKind;
 struct Error(ErrorKind);
 impl Fn(&isize) for Error {
     //~^ ERROR manual implementations of `Fn` are experimental [E0183]
-    //~^^ ERROR associated type bindings are not allowed here [E0229]
+    //~^^ ERROR associated item constraints are not allowed here [E0229]
     //~| ERROR not all trait items implemented
     //~| ERROR expected a `FnMut(&isize)` closure, found `Error`
     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr
index c4285dbf4bd..feec4f83f78 100644
--- a/tests/ui/lifetimes/issue-95023.stderr
+++ b/tests/ui/lifetimes/issue-95023.stderr
@@ -20,11 +20,11 @@ LL | impl Fn(&isize) for Error {
    |
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-95023.rs:3:6
    |
 LL | impl Fn(&isize) for Error {
-   |      ^^^^^^^^^^ associated type not allowed here
+   |      ^^^^^^^^^^ associated item constraint not allowed here
    |
 help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
   --> $DIR/issue-95023.rs:3:6
diff --git a/tests/ui/methods/method-call-type-binding.rs b/tests/ui/methods/method-call-type-binding.rs
index f547ca8d1c2..290c66fabe3 100644
--- a/tests/ui/methods/method-call-type-binding.rs
+++ b/tests/ui/methods/method-call-type-binding.rs
@@ -1,3 +1,3 @@
 fn main() {
-    0.clone::<T = u8>(); //~ ERROR associated type bindings are not allowed here
+    0.clone::<T = u8>(); //~ ERROR associated item constraints are not allowed here
 }
diff --git a/tests/ui/methods/method-call-type-binding.stderr b/tests/ui/methods/method-call-type-binding.stderr
index 54d855d340e..1acb0b2e12b 100644
--- a/tests/ui/methods/method-call-type-binding.stderr
+++ b/tests/ui/methods/method-call-type-binding.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/method-call-type-binding.rs:2:15
    |
 LL |     0.clone::<T = u8>();
-   |               ^^^^^^ associated type not allowed here
+   |               ^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/issue-85347.rs b/tests/ui/suggestions/issue-85347.rs
index 95e76e76cfa..5d1a902af30 100644
--- a/tests/ui/suggestions/issue-85347.rs
+++ b/tests/ui/suggestions/issue-85347.rs
@@ -3,12 +3,12 @@ trait Foo {
     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
     //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
     //~| HELP add missing
-    //~| ERROR associated type bindings are not allowed here
-    //~| HELP consider removing this type binding
+    //~| ERROR associated item constraints are not allowed here
+    //~| HELP consider removing this associated item binding
     //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
     //~| HELP add missing
-    //~| ERROR associated type bindings are not allowed here
-    //~| HELP consider removing this type binding
+    //~| ERROR associated item constraints are not allowed here
+    //~| HELP consider removing this associated item binding
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr
index de0aa09ce49..b3616041c4c 100644
--- a/tests/ui/suggestions/issue-85347.stderr
+++ b/tests/ui/suggestions/issue-85347.stderr
@@ -14,13 +14,13 @@ help: add missing lifetime argument
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
    |                                              +++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-85347.rs:3:46
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
-   |                                              ^^^^^^^^^^^^^ associated type not allowed here
+   |                                              ^^^^^^^^^^^^^ associated item constraint not allowed here
    |
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
    |                                             ~~~~~~~~~~~~~~~
@@ -42,14 +42,14 @@ help: add missing lifetime argument
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
    |                                              +++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-85347.rs:3:46
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
-   |                                              ^^^^^^^^^^^^^ associated type not allowed here
+   |                                              ^^^^^^^^^^^^^ associated item constraint not allowed here
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider removing this type binding
+help: consider removing this associated item binding
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
    |                                             ~~~~~~~~~~~~~~~
diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs
index c98eec4af01..99f943d71e9 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs
+++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs
@@ -8,5 +8,5 @@ fn main() {
     //~| HELP you might have meant to write a path instead of an associated type bound
     //~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied
     //~| HELP add missing generic argument
-    //~| ERROR associated type bindings are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 }
diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
index 834c141ec3e..56b6a69a283 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
@@ -20,11 +20,11 @@ help: add missing generic argument
 LL |     let _: Vec<T, A:B> = A::B;
    |                ++
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/type-ascription-instead-of-path-in-type.rs:6:16
    |
 LL |     let _: Vec<A:B> = A::B;
-   |                ^^^ associated type not allowed here
+   |                ^^^ associated item constraint not allowed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/traits/issue-87558.rs b/tests/ui/traits/issue-87558.rs
index 76f0f7453dd..61a24f6b967 100644
--- a/tests/ui/traits/issue-87558.rs
+++ b/tests/ui/traits/issue-87558.rs
@@ -2,7 +2,7 @@ struct ErrorKind;
 struct Error(ErrorKind);
 impl Fn(&isize) for Error {
     //~^ ERROR manual implementations of `Fn` are experimental
-    //~| ERROR associated type bindings are not allowed here
+    //~| ERROR associated item constraints are not allowed here
     //~| ERROR closure, found `Error`
     //~| ERROR not all trait items implemented, missing: `call`
     fn from() {} //~ ERROR method `from` is not a member of trait `Fn`
diff --git a/tests/ui/traits/issue-87558.stderr b/tests/ui/traits/issue-87558.stderr
index 1ce273a9f25..21d8fc0f567 100644
--- a/tests/ui/traits/issue-87558.stderr
+++ b/tests/ui/traits/issue-87558.stderr
@@ -12,11 +12,11 @@ LL | impl Fn(&isize) for Error {
    |
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-87558.rs:3:6
    |
 LL | impl Fn(&isize) for Error {
-   |      ^^^^^^^^^^ associated type not allowed here
+   |      ^^^^^^^^^^ associated item constraint not allowed here
    |
 help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
   --> $DIR/issue-87558.rs:3:6
diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
index 050b7b44b4e..3defe0cb44d 100644
--- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
+++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
@@ -5,6 +5,6 @@ type Pat<const START: u32, const END: u32> =
     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
 //~^ ERROR type and const arguments are not allowed on const parameter `START`
 //~| ERROR type arguments are not allowed on const parameter `END`
-//~| ERROR associated type bindings are not allowed here
+//~| ERROR associated item constraints are not allowed here
 
 fn main() {}
diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
index 40effe924da..7f4e6e314f5 100644
--- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
+++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr
@@ -26,11 +26,11 @@ note: const parameter `END` defined here
 LL | type Pat<const START: u32, const END: u32> =
    |                                  ^^^
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/bad_const_generics_args_on_const_param.rs:5:67
    |
 LL |     std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
-   |                                                                   ^^^^^^^^^^ associated type not allowed here
+   |                                                                   ^^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/typeck/escaping_bound_vars.rs b/tests/ui/typeck/escaping_bound_vars.rs
index 985a3fdbccf..3cde041f185 100644
--- a/tests/ui/typeck/escaping_bound_vars.rs
+++ b/tests/ui/typeck/escaping_bound_vars.rs
@@ -10,7 +10,7 @@ pub fn test()
 where
     (): Test<{ 1 + (<() as Elide(&())>::call) }>,
     //~^ ERROR cannot capture late-bound lifetime in constant
-    //~| ERROR associated type bindings are not allowed here
+    //~| ERROR associated item constraints are not allowed here
 {
 }
 
diff --git a/tests/ui/typeck/escaping_bound_vars.stderr b/tests/ui/typeck/escaping_bound_vars.stderr
index bd9c95fab97..f383099ce13 100644
--- a/tests/ui/typeck/escaping_bound_vars.stderr
+++ b/tests/ui/typeck/escaping_bound_vars.stderr
@@ -6,11 +6,11 @@ LL |     (): Test<{ 1 + (<() as Elide(&())>::call) }>,
    |                                  |
    |                                  lifetime defined here
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/escaping_bound_vars.rs:11:28
    |
 LL |     (): Test<{ 1 + (<() as Elide(&())>::call) }>,
-   |                            ^^^^^^^^^^ associated type not allowed here
+   |                            ^^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/typeck/issue-83693.rs b/tests/ui/typeck/issue-83693.rs
index a4255822056..02a0bb30d7c 100644
--- a/tests/ui/typeck/issue-83693.rs
+++ b/tests/ui/typeck/issue-83693.rs
@@ -8,12 +8,12 @@ impl F {
     fn call() {
         <Self as Fn(&TestResult)>::call
         //~^ ERROR: cannot find type `TestResult` in this scope [E0412]
-        //~| associated type bindings are not allowed here [E0229]
+        //~| associated item constraints are not allowed here [E0229]
     }
 }
 
 fn call() {
     <x as Fn(&usize)>::call
     //~^ ERROR: cannot find type `x` in this scope [E0412]
-    //~| ERROR: associated type bindings are not allowed here [E0229]
+    //~| ERROR: associated item constraints are not allowed here [E0229]
 }
diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr
index ce4f73b820a..34bca426116 100644
--- a/tests/ui/typeck/issue-83693.stderr
+++ b/tests/ui/typeck/issue-83693.stderr
@@ -19,17 +19,17 @@ error[E0412]: cannot find type `x` in this scope
 LL |     <x as Fn(&usize)>::call
    |      ^ not found in this scope
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-83693.rs:9:18
    |
 LL |         <Self as Fn(&TestResult)>::call
-   |                  ^^^^^^^^^^^^^^^ associated type not allowed here
+   |                  ^^^^^^^^^^^^^^^ associated item constraint not allowed here
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-83693.rs:16:11
    |
 LL |     <x as Fn(&usize)>::call
-   |           ^^^^^^^^^^ associated type not allowed here
+   |           ^^^^^^^^^^ associated item constraint not allowed here
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/typeck/issue-84768.rs b/tests/ui/typeck/issue-84768.rs
index ffa92823b42..3ba5dffcf07 100644
--- a/tests/ui/typeck/issue-84768.rs
+++ b/tests/ui/typeck/issue-84768.rs
@@ -5,6 +5,6 @@
 
 fn transform_mut<F>(f: F) where F: for<'b> FnOnce(&'b mut u8) {
     <F as FnOnce(&mut u8)>::call_once(f, 1)
-    //~^ ERROR: associated type bindings are not allowed here [E0229]
+    //~^ ERROR: associated item constraints are not allowed here [E0229]
     //~| ERROR: mismatched types [E0308]
 }
diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr
index 3d2d53f5c76..72784ba59c9 100644
--- a/tests/ui/typeck/issue-84768.stderr
+++ b/tests/ui/typeck/issue-84768.stderr
@@ -1,8 +1,8 @@
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-84768.rs:7:11
    |
 LL |     <F as FnOnce(&mut u8)>::call_once(f, 1)
-   |           ^^^^^^^^^^^^^^^ associated type not allowed here
+   |           ^^^^^^^^^^^^^^^ associated item constraint not allowed here
 
 error[E0308]: mismatched types
   --> $DIR/issue-84768.rs:7:42
diff --git a/tests/ui/typeck/issue-91267.rs b/tests/ui/typeck/issue-91267.rs
index 4e39cfab5b4..1bffa09e643 100644
--- a/tests/ui/typeck/issue-91267.rs
+++ b/tests/ui/typeck/issue-91267.rs
@@ -3,6 +3,6 @@
 fn main() {
     type_ascribe!(0, u8<e<5>=e>)
     //~^ ERROR: cannot find type `e` in this scope [E0412]
-    //~| ERROR: associated type bindings are not allowed here [E0229]
+    //~| ERROR: associated item constraints are not allowed here [E0229]
     //~| ERROR: mismatched types [E0308]
 }
diff --git a/tests/ui/typeck/issue-91267.stderr b/tests/ui/typeck/issue-91267.stderr
index 399309d0ec4..d16b1997e9f 100644
--- a/tests/ui/typeck/issue-91267.stderr
+++ b/tests/ui/typeck/issue-91267.stderr
@@ -4,11 +4,11 @@ error[E0412]: cannot find type `e` in this scope
 LL |     type_ascribe!(0, u8<e<5>=e>)
    |                              ^ not found in this scope
 
-error[E0229]: associated type bindings are not allowed here
+error[E0229]: associated item constraints are not allowed here
   --> $DIR/issue-91267.rs:4:25
    |
 LL |     type_ascribe!(0, u8<e<5>=e>)
-   |                         ^^^^^^ associated type not allowed here
+   |                         ^^^^^^ associated item constraint not allowed here
 
 error[E0308]: mismatched types
   --> $DIR/issue-91267.rs:4:5