11use crate :: utils:: { in_macro, snippet, snippet_with_applicability, span_lint_and_help, SpanlessHash } ;
2+ use if_chain:: if_chain;
23use rustc_data_structures:: fx:: FxHashMap ;
34use rustc_errors:: Applicability ;
45use rustc_hir:: { GenericBound , Generics , WherePredicate } ;
@@ -11,6 +12,8 @@ declare_clippy_lint! {
1112 /// **Why is this bad?** Repeating the type for every bound makes the code
1213 /// less readable than combining the bounds
1314 ///
15+ /// **Known problems:** None.
16+ ///
1417 /// **Example:**
1518 /// ```rust
1619 /// pub fn foo<T>(t: T) where T: Copy, T: Clone {}
@@ -53,12 +56,14 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
5356 let mut map = FxHashMap :: default ( ) ;
5457 let mut applicability = Applicability :: MaybeIncorrect ;
5558 for bound in gen. where_clause . predicates {
56- if let WherePredicate :: BoundPredicate ( ref p ) = bound {
57- if p . bounds . len ( ) as u64 > self . max_trait_bounds {
58- return ;
59- }
59+ if_chain ! {
60+ if let WherePredicate :: BoundPredicate ( ref p ) = bound ;
61+ if p . bounds . len ( ) as u64 <= self . max_trait_bounds ;
62+ if !in_macro ( p . span ) ;
6063 let h = hash( & p. bounded_ty) ;
61- if let Some ( ref v) = map. insert ( h, p. bounds . iter ( ) . collect :: < Vec < _ > > ( ) ) {
64+ if let Some ( ref v) = map. insert( h, p. bounds. iter( ) . collect:: <Vec <_>>( ) ) ;
65+
66+ then {
6267 let mut hint_string = format!(
6368 "consider combining the bounds: `{}:" ,
6469 snippet( cx, p. bounded_ty. span, "_" )
0 commit comments