@@ -103,7 +103,6 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
103103 fn check_generics ( & mut self , cx : & LateContext < ' tcx > , gen : & ' tcx Generics < ' _ > ) {
104104 self . check_type_repetition ( cx, gen) ;
105105 check_trait_bound_duplication ( cx, gen) ;
106- check_bounds_or_where_duplication ( cx, gen) ;
107106 }
108107
109108 fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
@@ -234,7 +233,7 @@ impl TraitBounds {
234233}
235234
236235fn check_trait_bound_duplication ( cx : & LateContext < ' _ > , gen : & ' _ Generics < ' _ > ) {
237- if gen. span . from_expansion ( ) || gen . params . is_empty ( ) || gen . predicates . is_empty ( ) {
236+ if gen. span . from_expansion ( ) {
238237 return ;
239238 }
240239
@@ -254,9 +253,9 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
254253 if let WherePredicate :: BoundPredicate ( bound_predicate) = pred;
255254 if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = bound_predicate. bounded_ty. kind;
256255 then {
257- return Some ( bound_predicate . bounds . iter ( ) . filter_map ( |t| {
258- Some ( ( path . res , into_comparable_trait_ref ( t . trait_ref ( ) ? ) ) )
259- } ) )
256+ return Some (
257+ rollup_traits ( cx , bound_predicate . bounds , "these where clauses contain repeated elements" )
258+ . into_keys ( ) . map ( |trait_ref| ( path . res , trait_ref ) ) )
260259 }
261260 }
262261 None
@@ -277,19 +276,18 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
277276 if !bound_predicate. span. from_expansion( ) ;
278277 if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = bound_predicate. bounded_ty. kind;
279278 then {
280- for t in bound_predicate. bounds {
281- if let Some ( trait_ref) = t. trait_ref( ) {
282- let key = ( path. res, into_comparable_trait_ref( trait_ref) ) ;
283- if where_predicates. contains( & key) {
284- span_lint_and_help(
285- cx,
286- TRAIT_DUPLICATION_IN_BOUNDS ,
287- t. span( ) ,
288- "this trait bound is already specified in the where clause" ,
289- None ,
290- "consider removing this trait bound" ,
291- ) ;
292- }
279+ let traits = rollup_traits( cx, bound_predicate. bounds, "these bounds contain repeated elements" ) ;
280+ for ( trait_ref, span) in traits {
281+ let key = ( path. res, trait_ref) ;
282+ if where_predicates. contains( & key) {
283+ span_lint_and_help(
284+ cx,
285+ TRAIT_DUPLICATION_IN_BOUNDS ,
286+ span,
287+ "this trait bound is already specified in the where clause" ,
288+ None ,
289+ "consider removing this trait bound" ,
290+ ) ;
293291 }
294292 }
295293 }
@@ -300,23 +298,6 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
300298#[ derive( PartialEq , Eq , Hash , Debug ) ]
301299struct ComparableTraitRef ( Res , Vec < Res > ) ;
302300
303- fn check_bounds_or_where_duplication ( cx : & LateContext < ' _ > , gen : & ' _ Generics < ' _ > ) {
304- if gen. span . from_expansion ( ) {
305- return ;
306- }
307-
308- for predicate in gen. predicates {
309- if let WherePredicate :: BoundPredicate ( ref bound_predicate) = predicate {
310- let msg = if predicate. in_where_clause ( ) {
311- "these where clauses contain repeated elements"
312- } else {
313- "these bounds contain repeated elements"
314- } ;
315- rollup_traits ( cx, bound_predicate. bounds , msg) ;
316- }
317- }
318- }
319-
320301fn get_trait_info_from_bound < ' a > ( bound : & ' a GenericBound < ' _ > ) -> Option < ( Res , & ' a [ PathSegment < ' a > ] , Span ) > {
321302 if let GenericBound :: Trait ( t, tbm) = bound {
322303 let trait_path = t. trait_ref . path ;
@@ -358,7 +339,7 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
358339 )
359340}
360341
361- fn rollup_traits ( cx : & LateContext < ' _ > , bounds : & [ GenericBound < ' _ > ] , msg : & str ) {
342+ fn rollup_traits ( cx : & LateContext < ' _ > , bounds : & [ GenericBound < ' _ > ] , msg : & str ) -> FxHashMap < ComparableTraitRef , Span > {
362343 let mut map = FxHashMap :: default ( ) ;
363344 let mut repeated_res = false ;
364345
@@ -400,4 +381,6 @@ fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
400381 ) ;
401382 }
402383 }
384+
385+ map
403386}
0 commit comments