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
commitfebfa5157c8b3ce7430c07b2e0d84972d2e48cc0 (patch)
tree3eabd142ad1ee807a5671f1baf84d3e95a2fe0e4
parent51347ba3c762a36ddb8fa617ed2354e8d90132ce (diff)
parent040edea332a2767aed540b725c38a37167e17fdb (diff)
downloadrust-febfa5157c8b3ce7430c07b2e0d84972d2e48cc0.tar.gz
rust-febfa5157c8b3ce7430c07b2e0d84972d2e48cc0.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--clippy_lints/src/implied_bounds_in_impls.rs54
-rw-r--r--clippy_lints/src/len_zero.rs17
-rw-r--r--clippy_lints/src/manual_async_fn.rs10
-rw-r--r--clippy_utils/src/ast_utils.rs6
-rw-r--r--clippy_utils/src/hir_utils.rs8
5 files changed, 44 insertions, 51 deletions
diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs
index dc935ed3d7f..2b389d4f9b1 100644
--- a/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/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/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 97a245b76d4..2091e74665f 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/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/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs
index 4cd5f3b81e5..25c7e5d38b3 100644
--- a/clippy_lints/src/manual_async_fn.rs
+++ b/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/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs
index d4a5f547211..bbdde3049db 100644
--- a/clippy_utils/src/ast_utils.rs
+++ b/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/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 817d4095eb5..c649c179468 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/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 {