Skip to content

Commit

Permalink
Don't lint for predicates generated in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibsG committed Jul 3, 2020
1 parent d5a8f03 commit 2d5930a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
15 changes: 10 additions & 5 deletions clippy_lints/src/trait_bounds.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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 {}
Expand Down Expand Up @@ -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, "_")
Expand Down
37 changes: 28 additions & 9 deletions tests/ui/type_repetition_in_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

0 comments on commit 2d5930a

Please sign in to comment.