about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-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
9 files changed, 173 insertions, 172 deletions
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 1475e53c47c..24a1df70e05 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 749f78e7920..455ed7d39cb 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 d9d36f5299b..7be661ba74d 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 4b1c0da6ce1..fd59fb4d284 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(
@@ -1545,8 +1550,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);