@@ -61,7 +61,7 @@ fn emit_lint(
6161 implied_bindings : & [ rustc_hir:: TypeBinding < ' _ > ] ,
6262 bound : & ImplTraitBound < ' _ > ,
6363) {
64- let implied_by = snippet ( cx, bound. impl_trait_bound_span , ".." ) ;
64+ let implied_by = snippet ( cx, bound. span , ".." ) ;
6565
6666 span_lint_and_then (
6767 cx,
@@ -101,7 +101,7 @@ fn emit_lint(
101101 ( [ .., arg] , [ .., binding] ) => arg. span ( ) . max ( binding. span ) . shrink_to_hi ( ) ,
102102 ( [ .., arg] , [ ] ) => arg. span ( ) . shrink_to_hi ( ) ,
103103 ( [ ] , [ .., binding] ) => binding. span . shrink_to_hi ( ) ,
104- ( [ ] , [ ] ) => bound. impl_trait_bound_span . shrink_to_hi ( ) ,
104+ ( [ ] , [ ] ) => bound. span . shrink_to_hi ( ) ,
105105 } ;
106106
107107 let mut associated_tys_sugg = if needs_angle_brackets {
@@ -223,8 +223,9 @@ fn is_same_generics<'tcx>(
223223
224224struct ImplTraitBound < ' tcx > {
225225 /// 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
228229 predicates : & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] ,
229230 /// The `DefId` of the trait being referenced by this bound
230231 trait_def_id : DefId ,
@@ -257,7 +258,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
257258 args : path. args . map_or ( [ ] . as_slice ( ) , |p| p. args ) ,
258259 bindings : path. args . map_or ( [ ] . as_slice ( ) , |p| p. bindings ) ,
259260 trait_def_id,
260- impl_trait_bound_span : bound. span ( ) ,
261+ span : bound. span ( ) ,
261262 } )
262263 } else {
263264 None
@@ -266,6 +267,34 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
266267 . collect ( )
267268}
268269
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+
269298fn check ( cx : & LateContext < ' _ > , decl : & FnDecl < ' _ > ) {
270299 if let FnRetTy :: Return ( ty) = decl. output
271300 && let TyKind :: OpaqueDef ( item_id, ..) = ty. kind
@@ -287,24 +316,7 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
287316 && let implied_args = path. args . map_or ( [ ] . as_slice ( ) , |a| a. args )
288317 && let implied_bindings = path. args . map_or ( [ ] . as_slice ( ) , |a| a. bindings )
289318 && 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)
308320 {
309321 emit_lint ( cx, poly_trait, opaque_ty, index, implied_bindings, bound) ;
310322 }
0 commit comments