@@ -3,8 +3,8 @@ use clippy_utils::source::snippet;
33use rustc_errors:: { Applicability , SuggestionStyle } ;
44use rustc_hir:: def_id:: DefId ;
55use rustc_hir:: {
6- GenericArg , GenericBound , GenericBounds , ItemKind , PredicateOrigin , TraitBoundModifier , TyKind , TypeBinding ,
7- WherePredicate ,
6+ AssocItemConstraint , GenericArg , GenericBound , GenericBounds , ItemKind , PredicateOrigin , TraitBoundModifier ,
7+ TyKind , WherePredicate ,
88} ;
99use rustc_hir_analysis:: lower_ty;
1010use rustc_lint:: { LateContext , LateLintPass } ;
@@ -54,9 +54,9 @@ fn emit_lint(
5454 poly_trait : & rustc_hir:: PolyTraitRef < ' _ > ,
5555 bounds : GenericBounds < ' _ > ,
5656 index : usize ,
57- // The bindings that were implied, used for suggestion purposes since removing a bound with associated types
58- // means we might need to then move it to a different bound
59- implied_bindings : & [ TypeBinding < ' _ > ] ,
57+ // The constraints that were implied, used for suggestion purposes since removing a bound with
58+ // associated types means we might need to then move it to a different bound.
59+ implied_constraints : & [ AssocItemConstraint < ' _ > ] ,
6060 bound : & ImplTraitBound < ' _ > ,
6161) {
6262 let implied_by = snippet ( cx, bound. span , ".." ) ;
@@ -83,46 +83,46 @@ fn emit_lint(
8383
8484 let mut sugg = vec ! [ ( implied_span_extended, String :: new( ) ) ] ;
8585
86- // We also might need to include associated type binding that were specified in the implied bound,
87- // but omitted in the implied-by bound:
86+ // We also might need to include associated item constraints that were specified in the implied
87+ // bound, but omitted in the implied-by bound:
8888 // `fn f() -> impl Deref<Target = u8> + DerefMut`
8989 // If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`
90- let omitted_assoc_tys : Vec < _ > = implied_bindings
90+ let omitted_constraints : Vec < _ > = implied_constraints
9191 . iter ( )
92- . filter ( |binding | !bound. bindings . iter ( ) . any ( |b| b . ident == binding . ident ) )
92+ . filter ( |constraint | !bound. constraints . iter ( ) . any ( |c| c . ident == constraint . ident ) )
9393 . collect ( ) ;
9494
95- if !omitted_assoc_tys . is_empty ( ) {
96- // `<>` needs to be added if there aren't yet any generic arguments or bindings
97- let needs_angle_brackets = bound. args . is_empty ( ) && bound. bindings . is_empty ( ) ;
98- let insert_span = match ( bound. args , bound. bindings ) {
99- ( [ .., arg] , [ .., binding ] ) => arg. span ( ) . max ( binding . span ) . shrink_to_hi ( ) ,
95+ if !omitted_constraints . is_empty ( ) {
96+ // `<>` needs to be added if there aren't yet any generic arguments or constraints
97+ let needs_angle_brackets = bound. args . is_empty ( ) && bound. constraints . is_empty ( ) ;
98+ let insert_span = match ( bound. args , bound. constraints ) {
99+ ( [ .., arg] , [ .., constraint ] ) => arg. span ( ) . max ( constraint . span ) . shrink_to_hi ( ) ,
100100 ( [ .., arg] , [ ] ) => arg. span ( ) . shrink_to_hi ( ) ,
101- ( [ ] , [ .., binding ] ) => binding . span . shrink_to_hi ( ) ,
101+ ( [ ] , [ .., constraint ] ) => constraint . span . shrink_to_hi ( ) ,
102102 ( [ ] , [ ] ) => bound. span . shrink_to_hi ( ) ,
103103 } ;
104104
105- let mut associated_tys_sugg = if needs_angle_brackets {
105+ let mut constraints_sugg = if needs_angle_brackets {
106106 "<" . to_owned ( )
107107 } else {
108- // If angle brackets aren't needed (i.e., there are already generic arguments or bindings ),
108+ // If angle brackets aren't needed (i.e., there are already generic arguments or constraints ),
109109 // we need to add a comma:
110110 // `impl A<B, C >`
111111 // ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:
112112 // `impl A<B, C Assoc=i32>`
113113 ", " . to_owned ( )
114114 } ;
115115
116- for ( index, binding ) in omitted_assoc_tys . into_iter ( ) . enumerate ( ) {
116+ for ( index, constraint ) in omitted_constraints . into_iter ( ) . enumerate ( ) {
117117 if index > 0 {
118- associated_tys_sugg += ", " ;
118+ constraints_sugg += ", " ;
119119 }
120- associated_tys_sugg += & snippet ( cx, binding . span , ".." ) ;
120+ constraints_sugg += & snippet ( cx, constraint . span , ".." ) ;
121121 }
122122 if needs_angle_brackets {
123- associated_tys_sugg += ">" ;
123+ constraints_sugg += ">" ;
124124 }
125- sugg. push ( ( insert_span, associated_tys_sugg ) ) ;
125+ sugg. push ( ( insert_span, constraints_sugg ) ) ;
126126 }
127127
128128 diag. multipart_suggestion_with_style (
@@ -229,8 +229,8 @@ struct ImplTraitBound<'tcx> {
229229 trait_def_id : DefId ,
230230 /// The generic arguments on the `impl Trait` bound
231231 args : & ' tcx [ GenericArg < ' tcx > ] ,
232- /// The associated types on this bound
233- bindings : & ' tcx [ TypeBinding < ' tcx > ] ,
232+ /// The associated item constraints of this bound
233+ constraints : & ' tcx [ AssocItemConstraint < ' tcx > ] ,
234234}
235235
236236/// 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
253253 Some ( ImplTraitBound {
254254 predicates,
255255 args : path. args . map_or ( [ ] . as_slice ( ) , |p| p. args ) ,
256- bindings : path. args . map_or ( [ ] . as_slice ( ) , |p| p. bindings ) ,
256+ constraints : path. args . map_or ( [ ] . as_slice ( ) , |p| p. constraints ) ,
257257 trait_def_id,
258258 span : bound. span ( ) ,
259259 } )
@@ -310,20 +310,20 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
310310 if let GenericBound :: Trait ( poly_trait, TraitBoundModifier :: None ) = bound
311311 && let [ .., path] = poly_trait. trait_ref . path . segments
312312 && let implied_args = path. args . map_or ( [ ] . as_slice ( ) , |a| a. args )
313- && let implied_bindings = path. args . map_or ( [ ] . as_slice ( ) , |a| a. bindings )
313+ && let implied_constraints = path. args . map_or ( [ ] . as_slice ( ) , |a| a. constraints )
314314 && let Some ( def_id) = poly_trait. trait_ref . path . res . opt_def_id ( )
315315 && let Some ( bound) = find_bound_in_supertraits ( cx, def_id, implied_args, & supertraits)
316316 // If the implied bound has a type binding that also exists in the implied-by trait,
317317 // then we shouldn't lint. See #11880 for an example.
318318 && let assocs = cx. tcx . associated_items ( bound. trait_def_id )
319- && !implied_bindings . iter ( ) . any ( |binding | {
319+ && !implied_constraints . iter ( ) . any ( |constraint | {
320320 assocs
321- . filter_by_name_unhygienic ( binding . ident . name )
321+ . filter_by_name_unhygienic ( constraint . ident . name )
322322 . next ( )
323323 . is_some_and ( |assoc| assoc. kind == ty:: AssocKind :: Type )
324324 } )
325325 {
326- emit_lint ( cx, poly_trait, bounds, index, implied_bindings , bound) ;
326+ emit_lint ( cx, poly_trait, bounds, index, implied_constraints , bound) ;
327327 }
328328 }
329329}
0 commit comments