@@ -53,35 +53,43 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
53
53
let tcx = cx. tcx ;
54
54
// `Deref` is being implemented for `t`
55
55
if let hir:: ItemKind :: Impl ( impl_) = item. kind
56
+ // the trait is a `Deref` implementation
56
57
&& 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 ( )
63
64
// `<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" )
65
66
&& let ty:: Dynamic ( data, _, ty:: Dyn ) = target. kind ( )
66
67
&& let Some ( target_principal) = data. principal ( )
67
68
// `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 ( ) )
74
71
{
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_
77
76
. items
78
77
. iter ( )
79
78
. find_map ( |i| ( i. ident . name == sym:: Target ) . then_some ( i. span ) )
80
79
. map ( |label| SupertraitAsDerefTargetLabel { label } ) ;
80
+ let span = tcx. def_span ( item. owner_id . def_id ) ;
81
81
cx. emit_spanned_lint (
82
82
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
+ } ,
85
93
) ;
86
94
}
87
95
}
0 commit comments