diff options
| author | ThibsG <Thibs@debian.com> | 2020-07-03 11:48:28 +0200 |
|---|---|---|
| committer | ThibsG <Thibs@debian.com> | 2020-07-03 17:29:54 +0200 |
| commit | 2d5930a3da7048d784489f28b44a769880b6ceff (patch) | |
| tree | 0f0e5ccb35231dc0d387227bf155d74bca74c88e | |
| parent | d5a8f03a350e8a392f0aa1c05707b503f549e90b (diff) | |
| download | rust-2d5930a3da7048d784489f28b44a769880b6ceff.tar.gz rust-2d5930a3da7048d784489f28b44a769880b6ceff.zip | |
Don't lint for predicates generated in macros
| -rw-r--r-- | clippy_lints/src/trait_bounds.rs | 15 | ||||
| -rw-r--r-- | tests/ui/type_repetition_in_bounds.rs | 37 |
2 files changed, 38 insertions, 14 deletions
diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 650edbb4b11..0ef70311fb1 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -1,4 +1,5 @@ use crate::utils::{in_macro, snippet, snippet_with_applicability, span_lint_and_help, SpanlessHash}; +use if_chain::if_chain; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; use rustc_hir::{GenericBound, Generics, WherePredicate}; @@ -11,6 +12,8 @@ declare_clippy_lint! { /// **Why is this bad?** Repeating the type for every bound makes the code /// less readable than combining the bounds /// + /// **Known problems:** None. + /// /// **Example:** /// ```rust /// pub fn foo<T>(t: T) where T: Copy, T: Clone {} @@ -53,12 +56,14 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { let mut map = FxHashMap::default(); let mut applicability = Applicability::MaybeIncorrect; for bound in gen.where_clause.predicates { - if let WherePredicate::BoundPredicate(ref p) = bound { - if p.bounds.len() as u64 > self.max_trait_bounds { - return; - } + if_chain! { + if let WherePredicate::BoundPredicate(ref p) = bound; + if p.bounds.len() as u64 <= self.max_trait_bounds; + if !in_macro(p.span); let h = hash(&p.bounded_ty); - if let Some(ref v) = map.insert(h, p.bounds.iter().collect::<Vec<_>>()) { + if let Some(ref v) = map.insert(h, p.bounds.iter().collect::<Vec<_>>()); + + then { let mut hint_string = format!( "consider combining the bounds: `{}:", snippet(cx, p.bounded_ty.span, "_") diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 9f1700567d1..766190f2099 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -37,17 +37,36 @@ where } // Generic distinction (see #4323) -pub struct Foo<A>(A); -pub struct Bar<A, B> { - a: Foo<A>, - b: Foo<B>, +mod issue4323 { + pub struct Foo<A>(A); + pub struct Bar<A, B> { + a: Foo<A>, + b: Foo<B>, + } + + impl<A, B> Unpin for Bar<A, B> + where + Foo<A>: Unpin, + Foo<B>: Unpin, + { + } } -impl<A, B> Unpin for Bar<A, B> -where - Foo<A>: Unpin, - Foo<B>: Unpin, -{ +// Extern macros shouldn't lint (see #4326) +extern crate serde; +mod issue4326 { + use serde::{Deserialize, Serialize}; + + trait Foo {} + impl Foo for String {} + + #[derive(Debug, Serialize, Deserialize)] + struct Bar<S> + where + S: Foo, + { + foo: S, + } } fn main() {} |
