From b9788fef298815c2b8366a42ef0c8113170d11ed Mon Sep 17 00:00:00 2001
From: John Kelly <johnharrykelly@gmail.com>
Date: Sun, 30 Apr 2023 14:34:46 +0100
Subject: [PATCH] Working

---
 clippy_lints/src/trait_bounds.rs            | 43 ++++++++++++---------
 tests/ui/trait_duplication_in_bounds.stderr |  5 +--
 2 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs
index 2c1c63e808b..8de0f92109b 100644
--- a/clippy_lints/src/trait_bounds.rs
+++ b/clippy_lints/src/trait_bounds.rs
@@ -187,37 +187,42 @@ 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 {
-                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(),
-                    Applicability::MaybeIncorrect,
-                );
+            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",
+                "try",
+                fixed_trait_snippet,
+                Applicability::MaybeIncorrect,
+            );
+        }
     }
 }
 
diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr
index a6508eb86f3..539b6114ca3 100644
--- a/tests/ui/trait_duplication_in_bounds.stderr
+++ b/tests/ui/trait_duplication_in_bounds.stderr
@@ -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