Skip to content

Commit 0cf2864

Browse files
author
Allen Hsu
committed
Lint trait duplication in one pass.
1 parent 3ddc04f commit 0cf2864

File tree

2 files changed

+22
-39
lines changed

2 files changed

+22
-39
lines changed

clippy_lints/src/trait_bounds.rs

+18-35
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
103103
fn check_generics(&mut self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
104104
self.check_type_repetition(cx, gen);
105105
check_trait_bound_duplication(cx, gen);
106-
check_bounds_or_where_duplication(cx, gen);
107106
}
108107

109108
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<'_>) {
254253
if let WherePredicate::BoundPredicate(bound_predicate) = pred;
255254
if let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind;
256255
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)))
260259
}
261260
}
262261
None
@@ -277,19 +276,18 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
277276
if !bound_predicate.span.from_expansion();
278277
if let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind;
279278
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+
);
293291
}
294292
}
295293
}
@@ -300,23 +298,6 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
300298
#[derive(PartialEq, Eq, Hash, Debug)]
301299
struct ComparableTraitRef(Res, Vec<Res>);
302300

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-
320301
fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> {
321302
if let GenericBound::Trait(t, tbm) = bound {
322303
let trait_path = t.trait_ref.path;
@@ -358,7 +339,7 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
358339
)
359340
}
360341

361-
fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
342+
fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) -> FxHashMap<ComparableTraitRef, Span> {
362343
let mut map = FxHashMap::default();
363344
let mut repeated_res = false;
364345

@@ -400,4 +381,6 @@ fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) {
400381
);
401382
}
402383
}
384+
385+
map
403386
}

tests/ui/trait_duplication_in_bounds_unfixable.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: this trait bound is already specified in the where clause
2-
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:15
2+
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23
33
|
44
LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
5-
| ^^^^^
5+
| ^^^^^^^
66
|
77
note: the lint level is defined here
88
--> $DIR/trait_duplication_in_bounds_unfixable.rs:1:9
@@ -12,10 +12,10 @@ LL | #![deny(clippy::trait_duplication_in_bounds)]
1212
= help: consider removing this trait bound
1313

1414
error: this trait bound is already specified in the where clause
15-
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23
15+
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:15
1616
|
1717
LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
18-
| ^^^^^^^
18+
| ^^^^^
1919
|
2020
= help: consider removing this trait bound
2121

0 commit comments

Comments
 (0)