@@ -53,35 +53,43 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
5353 let tcx = cx. tcx ;
5454 // `Deref` is being implemented for `t`
5555 if let hir:: ItemKind :: Impl ( impl_) = item. kind
56+ // the trait is a `Deref` implementation
5657 && let Some ( trait_) = & impl_. of_trait
57- && let t = tcx . type_of ( item . owner_id ) . instantiate_identity ( )
58- && let opt_did @ Some ( did) = trait_ . trait_def_id ( )
59- && opt_did == tcx . lang_items ( ) . deref_trait ( )
60- // `t` is `dyn t_principal`
61- && let ty:: Dynamic ( data, _, ty:: Dyn ) = t . kind ( )
62- && let Some ( t_principal ) = data. principal ( )
58+ && let Some ( did ) = trait_ . trait_def_id ( )
59+ && Some ( did) == tcx . lang_items ( ) . deref_trait ( )
60+ // the self type is `dyn t_principal`
61+ && let self_ty = tcx . type_of ( item . owner_id ) . instantiate_identity ( )
62+ && let ty:: Dynamic ( data, _, ty:: Dyn ) = self_ty . kind ( )
63+ && let Some ( self_principal ) = data. principal ( )
6364 // `<T as Deref>::Target` is `dyn target_principal`
64- && let Some ( target) = cx. get_associated_type ( t , did, "Target" )
65+ && let Some ( target) = cx. get_associated_type ( self_ty , did, "Target" )
6566 && let ty:: Dynamic ( data, _, ty:: Dyn ) = target. kind ( )
6667 && let Some ( target_principal) = data. principal ( )
6768 // `target_principal` is a supertrait of `t_principal`
68- && supertraits ( tcx, t_principal. with_self_ty ( tcx, tcx. types . trait_object_dummy_self ) )
69- . any ( |sup| {
70- tcx. erase_regions (
71- sup. map_bound ( |x| ty:: ExistentialTraitRef :: erase_self_ty ( tcx, x) ) ,
72- ) == tcx. erase_regions ( target_principal)
73- } )
69+ && let Some ( supertrait_principal) = supertraits ( tcx, self_principal. with_self_ty ( tcx, self_ty) )
70+ . find ( |supertrait| supertrait. def_id ( ) == target_principal. def_id ( ) )
7471 {
75- let t = tcx. erase_regions ( t) ;
76- let label = impl_
72+ // erase regions in self type for better diagnostic presentation
73+ let ( self_ty, target_principal, supertrait_principal) =
74+ tcx. erase_regions ( ( self_ty, target_principal, supertrait_principal) ) ;
75+ let label2 = impl_
7776 . items
7877 . iter ( )
7978 . find_map ( |i| ( i. ident . name == sym:: Target ) . then_some ( i. span ) )
8079 . map ( |label| SupertraitAsDerefTargetLabel { label } ) ;
80+ let span = tcx. def_span ( item. owner_id . def_id ) ;
8181 cx. emit_spanned_lint (
8282 DEREF_INTO_DYN_SUPERTRAIT ,
83- tcx. def_span ( item. owner_id . def_id ) ,
84- SupertraitAsDerefTarget { t, label } ,
83+ span,
84+ SupertraitAsDerefTarget {
85+ self_ty,
86+ supertrait_principal : supertrait_principal. map_bound ( |trait_ref| {
87+ ty:: ExistentialTraitRef :: erase_self_ty ( tcx, trait_ref)
88+ } ) ,
89+ target_principal,
90+ label : span,
91+ label2,
92+ } ,
8593 ) ;
8694 }
8795 }
0 commit comments