@@ -103,7 +103,6 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
103
103
fn check_generics ( & mut self , cx : & LateContext < ' tcx > , gen : & ' tcx Generics < ' _ > ) {
104
104
self . check_type_repetition ( cx, gen) ;
105
105
check_trait_bound_duplication ( cx, gen) ;
106
- check_bounds_or_where_duplication ( cx, gen) ;
107
106
}
108
107
109
108
fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
@@ -254,9 +253,9 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
254
253
if let WherePredicate :: BoundPredicate ( bound_predicate) = pred;
255
254
if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = bound_predicate. bounded_ty. kind;
256
255
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 ) ) )
260
259
}
261
260
}
262
261
None
@@ -277,19 +276,18 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
277
276
if !bound_predicate. span. from_expansion( ) ;
278
277
if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = bound_predicate. bounded_ty. kind;
279
278
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
+ ) ;
293
291
}
294
292
}
295
293
}
@@ -300,23 +298,6 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
300
298
#[ derive( PartialEq , Eq , Hash , Debug ) ]
301
299
struct ComparableTraitRef ( Res , Vec < Res > ) ;
302
300
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
-
320
301
fn get_trait_info_from_bound < ' a > ( bound : & ' a GenericBound < ' _ > ) -> Option < ( Res , & ' a [ PathSegment < ' a > ] , Span ) > {
321
302
if let GenericBound :: Trait ( t, tbm) = bound {
322
303
let trait_path = t. trait_ref . path ;
@@ -358,7 +339,7 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
358
339
)
359
340
}
360
341
361
- fn rollup_traits ( cx : & LateContext < ' _ > , bounds : & [ GenericBound < ' _ > ] , msg : & str ) {
342
+ fn rollup_traits ( cx : & LateContext < ' _ > , bounds : & [ GenericBound < ' _ > ] , msg : & str ) -> FxHashMap < ComparableTraitRef , Span > {
362
343
let mut map = FxHashMap :: default ( ) ;
363
344
let mut repeated_res = false ;
364
345
@@ -400,4 +381,6 @@ fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
400
381
) ;
401
382
}
402
383
}
384
+
385
+ map
403
386
}
0 commit comments