@@ -61,7 +61,7 @@ fn emit_lint(
61
61
implied_bindings : & [ rustc_hir:: TypeBinding < ' _ > ] ,
62
62
bound : & ImplTraitBound < ' _ > ,
63
63
) {
64
- let implied_by = snippet ( cx, bound. impl_trait_bound_span , ".." ) ;
64
+ let implied_by = snippet ( cx, bound. span , ".." ) ;
65
65
66
66
span_lint_and_then (
67
67
cx,
@@ -101,7 +101,7 @@ fn emit_lint(
101
101
( [ .., arg] , [ .., binding] ) => arg. span ( ) . max ( binding. span ) . shrink_to_hi ( ) ,
102
102
( [ .., arg] , [ ] ) => arg. span ( ) . shrink_to_hi ( ) ,
103
103
( [ ] , [ .., binding] ) => binding. span . shrink_to_hi ( ) ,
104
- ( [ ] , [ ] ) => bound. impl_trait_bound_span . shrink_to_hi ( ) ,
104
+ ( [ ] , [ ] ) => bound. span . shrink_to_hi ( ) ,
105
105
} ;
106
106
107
107
let mut associated_tys_sugg = if needs_angle_brackets {
@@ -223,8 +223,9 @@ fn is_same_generics<'tcx>(
223
223
224
224
struct ImplTraitBound < ' tcx > {
225
225
/// The span of the bound in the `impl Trait` type
226
- impl_trait_bound_span : Span ,
227
- /// The predicates defined in the trait referenced by this bound
226
+ span : Span ,
227
+ /// The predicates defined in the trait referenced by this bound. This also contains the actual
228
+ /// supertrait bounds
228
229
predicates : & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] ,
229
230
/// The `DefId` of the trait being referenced by this bound
230
231
trait_def_id : DefId ,
@@ -257,7 +258,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
257
258
args : path. args . map_or ( [ ] . as_slice ( ) , |p| p. args ) ,
258
259
bindings : path. args . map_or ( [ ] . as_slice ( ) , |p| p. bindings ) ,
259
260
trait_def_id,
260
- impl_trait_bound_span : bound. span ( ) ,
261
+ span : bound. span ( ) ,
261
262
} )
262
263
} else {
263
264
None
@@ -266,6 +267,34 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
266
267
. collect ( )
267
268
}
268
269
270
+ /// Given a bound in an `impl Trait` type, looks for a trait in the set of supertraits (previously
271
+ /// collected in [`collect_supertrait_bounds`]) that matches (same trait and generic arguments).
272
+ fn find_bound_in_supertraits < ' a , ' tcx > (
273
+ cx : & LateContext < ' tcx > ,
274
+ trait_def_id : DefId ,
275
+ args : & ' tcx [ GenericArg < ' tcx > ] ,
276
+ bounds : & ' a [ ImplTraitBound < ' tcx > ] ,
277
+ ) -> Option < & ' a ImplTraitBound < ' tcx > > {
278
+ bounds. iter ( ) . find ( |bound| {
279
+ bound. predicates . iter ( ) . any ( |( clause, _) | {
280
+ if let ClauseKind :: Trait ( tr) = clause. kind ( ) . skip_binder ( )
281
+ && tr. def_id ( ) == trait_def_id
282
+ {
283
+ is_same_generics (
284
+ cx. tcx ,
285
+ tr. trait_ref . args ,
286
+ bound. args ,
287
+ args,
288
+ bound. trait_def_id ,
289
+ trait_def_id,
290
+ )
291
+ } else {
292
+ false
293
+ }
294
+ } )
295
+ } )
296
+ }
297
+
269
298
fn check ( cx : & LateContext < ' _ > , decl : & FnDecl < ' _ > ) {
270
299
if let FnRetTy :: Return ( ty) = decl. output
271
300
&& let TyKind :: OpaqueDef ( item_id, ..) = ty. kind
@@ -287,24 +316,7 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
287
316
&& let implied_args = path. args . map_or ( [ ] . as_slice ( ) , |a| a. args )
288
317
&& let implied_bindings = path. args . map_or ( [ ] . as_slice ( ) , |a| a. bindings )
289
318
&& let Some ( def_id) = poly_trait. trait_ref . path . res . opt_def_id ( )
290
- && let Some ( bound) = supertraits. iter ( ) . find ( |bound| {
291
- bound. predicates . iter ( ) . any ( |( clause, _) | {
292
- if let ClauseKind :: Trait ( tr) = clause. kind ( ) . skip_binder ( )
293
- && tr. def_id ( ) == def_id
294
- {
295
- is_same_generics (
296
- cx. tcx ,
297
- tr. trait_ref . args ,
298
- bound. args ,
299
- implied_args,
300
- bound. trait_def_id ,
301
- def_id,
302
- )
303
- } else {
304
- false
305
- }
306
- } )
307
- } )
319
+ && let Some ( bound) = find_bound_in_supertraits ( cx, def_id, implied_args, & supertraits)
308
320
{
309
321
emit_lint ( cx, poly_trait, opaque_ty, index, implied_bindings, bound) ;
310
322
}
0 commit comments