@@ -187,37 +187,42 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
187187 return ;
188188 }
189189
190- let mut bounds_span = Span :: default ( ) ;
190+ let mut bounds_span = bounds [ 0 ] . span ;
191191
192- for bound in bounds. iter ( ) {
192+ for bound in bounds. iter ( ) . skip ( 1 ) {
193193 bounds_span = bounds_span. to ( bound. span ) ;
194194 }
195195
196196 let mut seen_def_ids = FxHashSet :: default ( ) ;
197-
198- let traits = bounds
199- . iter ( )
200- . filter_map ( |b| snippet_opt ( cx, b. span ) )
201- . collect :: < Vec < _ > > ( ) ;
202- let traits = traits. join ( " + " ) ;
197+ let mut fixed_traits = Vec :: new ( ) ;
203198
204199 for bound in bounds. iter ( ) {
205200 let Some ( def_id) = bound. trait_ref . trait_def_id ( ) else { continue ; } ;
206201
207- let already_seen = !seen_def_ids. insert ( def_id) ;
208-
209- if already_seen {
210- span_lint_and_sugg (
211- cx,
212- TRAIT_DUPLICATION_IN_BOUNDS ,
213- bounds_span,
214- "this trait bound is already specified in trait declaration" ,
215- "consider removing this trait bound" ,
216- traits. clone ( ) ,
217- Applicability :: MaybeIncorrect ,
218- ) ;
202+ let new_trait = seen_def_ids. insert ( def_id) ;
203+
204+ if new_trait {
205+ fixed_traits. push ( bound) ;
219206 }
220207 }
208+
209+ let fixed_trait_snippet = fixed_traits
210+ . iter ( )
211+ . filter_map ( |b| snippet_opt ( cx, b. span ) )
212+ . collect :: < Vec < _ > > ( )
213+ . join ( " + " ) ;
214+
215+ if bounds. len ( ) != fixed_traits. len ( ) {
216+ span_lint_and_sugg (
217+ cx,
218+ TRAIT_DUPLICATION_IN_BOUNDS ,
219+ bounds_span,
220+ "this trait bound is already specified in trait declaration" ,
221+ "try" ,
222+ fixed_trait_snippet,
223+ Applicability :: MaybeIncorrect ,
224+ ) ;
225+ }
221226 }
222227}
223228
0 commit comments