@@ -187,37 +187,42 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
187
187
return ;
188
188
}
189
189
190
- let mut bounds_span = Span :: default ( ) ;
190
+ let mut bounds_span = bounds [ 0 ] . span ;
191
191
192
- for bound in bounds. iter ( ) {
192
+ for bound in bounds. iter ( ) . skip ( 1 ) {
193
193
bounds_span = bounds_span. to ( bound. span ) ;
194
194
}
195
195
196
196
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 ( ) ;
203
198
204
199
for bound in bounds. iter ( ) {
205
200
let Some ( def_id) = bound. trait_ref . trait_def_id ( ) else { continue ; } ;
206
201
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) ;
219
206
}
220
207
}
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
+ }
221
226
}
222
227
}
223
228
0 commit comments