Skip to content

Commit 2d5930a

Browse files
committed
Don't lint for predicates generated in macros
1 parent d5a8f03 commit 2d5930a

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

clippy_lints/src/trait_bounds.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::utils::{in_macro, snippet, snippet_with_applicability, span_lint_and_help, SpanlessHash};
2+
use if_chain::if_chain;
23
use rustc_data_structures::fx::FxHashMap;
34
use rustc_errors::Applicability;
45
use 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, "_")

tests/ui/type_repetition_in_bounds.rs

+28-9
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,36 @@ where
3737
}
3838

3939
// Generic distinction (see #4323)
40-
pub struct Foo<A>(A);
41-
pub struct Bar<A, B> {
42-
a: Foo<A>,
43-
b: Foo<B>,
40+
mod issue4323 {
41+
pub struct Foo<A>(A);
42+
pub struct Bar<A, B> {
43+
a: Foo<A>,
44+
b: Foo<B>,
45+
}
46+
47+
impl<A, B> Unpin for Bar<A, B>
48+
where
49+
Foo<A>: Unpin,
50+
Foo<B>: Unpin,
51+
{
52+
}
4453
}
4554

46-
impl<A, B> Unpin for Bar<A, B>
47-
where
48-
Foo<A>: Unpin,
49-
Foo<B>: Unpin,
50-
{
55+
// Extern macros shouldn't lint (see #4326)
56+
extern crate serde;
57+
mod issue4326 {
58+
use serde::{Deserialize, Serialize};
59+
60+
trait Foo {}
61+
impl Foo for String {}
62+
63+
#[derive(Debug, Serialize, Deserialize)]
64+
struct Bar<S>
65+
where
66+
S: Foo,
67+
{
68+
foo: S,
69+
}
5170
}
5271

5372
fn main() {}

0 commit comments

Comments
 (0)