This commit is contained in:
John Kelly 2023-04-30 14:34:46 +01:00
parent 8db21e9a9c
commit b9788fef29
2 changed files with 26 additions and 22 deletions

View file

@ -187,39 +187,44 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
return; return;
} }
let mut bounds_span = Span::default(); let mut bounds_span = bounds[0].span;
for bound in bounds.iter() { for bound in bounds.iter().skip(1) {
bounds_span = bounds_span.to(bound.span); bounds_span = bounds_span.to(bound.span);
} }
let mut seen_def_ids = FxHashSet::default(); let mut seen_def_ids = FxHashSet::default();
let mut fixed_traits = Vec::new();
let traits = bounds
.iter()
.filter_map(|b| snippet_opt(cx, b.span))
.collect::<Vec<_>>();
let traits = traits.join(" + ");
for bound in bounds.iter() { for bound in bounds.iter() {
let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; }; let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; };
let already_seen = !seen_def_ids.insert(def_id); let new_trait = seen_def_ids.insert(def_id);
if already_seen { if new_trait {
fixed_traits.push(bound);
}
}
let fixed_trait_snippet = fixed_traits
.iter()
.filter_map(|b| snippet_opt(cx, b.span))
.collect::<Vec<_>>()
.join(" + ");
if bounds.len() != fixed_traits.len() {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
TRAIT_DUPLICATION_IN_BOUNDS, TRAIT_DUPLICATION_IN_BOUNDS,
bounds_span, bounds_span,
"this trait bound is already specified in trait declaration", "this trait bound is already specified in trait declaration",
"consider removing this trait bound", "try",
traits.clone(), fixed_trait_snippet,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} }
} }
} }
}
impl TraitBounds { impl TraitBounds {
fn check_type_repetition<'tcx>(self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) { fn check_type_repetition<'tcx>(self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {

View file

@ -53,11 +53,10 @@ LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone`
error: this trait bound is already specified in trait declaration error: this trait bound is already specified in trait declaration
--> $DIR/trait_duplication_in_bounds.rs:118:46 --> $DIR/trait_duplication_in_bounds.rs:118:33
| |
LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) { LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
| ^^^^ help: consider removing this trait bound | ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`
|
error: aborting due to 9 previous errors error: aborting due to 9 previous errors