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,38 +187,43 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
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);
}
let mut seen_def_ids = FxHashSet::default();
let traits = bounds
.iter()
.filter_map(|b| snippet_opt(cx, b.span))
.collect::<Vec<_>>();
let traits = traits.join(" + ");
let mut fixed_traits = Vec::new();
for bound in bounds.iter() {
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(
cx,
TRAIT_DUPLICATION_IN_BOUNDS,
bounds_span,
"this trait bound is already specified in trait declaration",
"consider removing this trait bound",
traits.clone(),
"try",
fixed_trait_snippet,
Applicability::MaybeIncorrect,
);
}
}
}
}
impl TraitBounds {

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`
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)) {
| ^^^^ help: consider removing this trait bound
|
| ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`
error: aborting due to 9 previous errors