From 040edea332a2767aed540b725c38a37167e17fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 27 May 2024 23:53:46 +0200 Subject: [PATCH] Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup --- clippy_lints/src/implied_bounds_in_impls.rs | 54 ++++++++++----------- clippy_lints/src/len_zero.rs | 17 +++---- clippy_lints/src/manual_async_fn.rs | 10 ++-- clippy_utils/src/ast_utils.rs | 6 +-- clippy_utils/src/hir_utils.rs | 8 +-- 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 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 + DerefMut` // If we're going to suggest removing `Deref<..>`, we'll need to put `` 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` // ^ 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::{ 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_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 9f285621e0c..36634817fc9 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -9,7 +9,7 @@ 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 @@ pub fn eq_path(&mut self, left: &Path<'_>, right: &Path<'_>) -> bool { 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 @@ pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool { } } - 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 {