@@ -62,26 +62,25 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
6262 let tcx = cx. tcx ;
6363 // `Deref` is being implemented for `t`
6464 if let hir:: ItemKind :: Impl ( impl_) = item. kind
65+ // the trait is a `Deref` implementation
6566 && let Some ( trait_) = & impl_. of_trait
66- && let t = tcx . type_of ( item . owner_id ) . instantiate_identity ( )
67- && let opt_did @ Some ( did) = trait_ . trait_def_id ( )
68- && opt_did == tcx . lang_items ( ) . deref_trait ( )
69- // `t` is `dyn t_principal`
70- && let ty:: Dynamic ( data, _, ty:: Dyn ) = t . kind ( )
71- && let Some ( t_principal ) = data. principal ( )
67+ && let Some ( did ) = trait_ . trait_def_id ( )
68+ && Some ( did) == tcx . lang_items ( ) . deref_trait ( )
69+ // the self type is `dyn t_principal`
70+ && let self_ty = tcx . type_of ( item . owner_id ) . instantiate_identity ( )
71+ && let ty:: Dynamic ( data, _, ty:: Dyn ) = self_ty . kind ( )
72+ && let Some ( self_principal ) = data. principal ( )
7273 // `<T as Deref>::Target` is `dyn target_principal`
73- && let Some ( target) = cx. get_associated_type ( t , did, "Target" )
74+ && let Some ( target) = cx. get_associated_type ( self_ty , did, "Target" )
7475 && let ty:: Dynamic ( data, _, ty:: Dyn ) = target. kind ( )
7576 && let Some ( target_principal) = data. principal ( )
7677 // `target_principal` is a supertrait of `t_principal`
77- && supertraits ( tcx, t_principal. with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) )
78- . any ( |sup| {
79- tcx. erase_regions (
80- sup. map_bound ( |x| ty:: ExistentialTraitRef :: erase_self_ty ( tcx, x) ) ,
81- ) == tcx. erase_regions ( target_principal)
82- } )
78+ && let Some ( supertrait_principal) = supertraits ( tcx, self_principal. with_self_ty ( tcx, self_ty) )
79+ . find ( |supertrait| supertrait. def_id ( ) == target_principal. def_id ( ) )
8380 {
84- let t = tcx. erase_regions ( t) ;
81+ // erase regions in self type for better diagnostic presentation
82+ let ( self_ty, target_principal, supertrait_principal) =
83+ tcx. erase_regions ( ( self_ty, target_principal, supertrait_principal) ) ;
8584 let label = impl_
8685 . items
8786 . iter ( )
@@ -90,7 +89,14 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
9089 cx. emit_spanned_lint (
9190 DEREF_INTO_DYN_SUPERTRAIT ,
9291 tcx. def_span ( item. owner_id . def_id ) ,
93- SupertraitAsDerefTarget { t, target_principal, label } ,
92+ SupertraitAsDerefTarget {
93+ self_ty,
94+ supertrait_principal : supertrait_principal. map_bound ( |trait_ref| {
95+ ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref)
96+ } ) ,
97+ target_principal,
98+ label,
99+ } ,
94100 ) ;
95101 }
96102 }
0 commit comments