@@ -2,7 +2,7 @@ use clippy_config::Conf;
22use clippy_utils:: diagnostics:: span_lint_and_sugg;
33use clippy_utils:: is_from_proc_macro;
44use clippy_utils:: msrvs:: { self , Msrv } ;
5- use clippy_utils:: ty:: same_type_and_consts;
5+ use clippy_utils:: ty:: { same_type_and_consts, ty_from_hir_ty } ;
66use rustc_data_structures:: fx:: FxHashSet ;
77use rustc_errors:: Applicability ;
88use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
@@ -12,7 +12,6 @@ use rustc_hir::{
1212 self as hir, AmbigArg , Expr , ExprKind , FnRetTy , FnSig , GenericArgsParentheses , GenericParam , GenericParamKind ,
1313 HirId , Impl , ImplItemKind , Item , ItemKind , Pat , PatExpr , PatExprKind , PatKind , Path , QPath , Ty , TyKind ,
1414} ;
15- use rustc_hir_analysis:: lower_ty;
1615use rustc_lint:: { LateContext , LateLintPass } ;
1716use rustc_middle:: ty:: Ty as MiddleTy ;
1817use rustc_session:: impl_lint_pass;
@@ -73,7 +72,6 @@ impl UseSelf {
7372enum StackItem {
7473 Check {
7574 impl_id : LocalDefId ,
76- in_body : u32 ,
7775 types_to_skip : FxHashSet < HirId > ,
7876 } ,
7977 NoCheck ,
@@ -96,8 +94,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
9694 . as_ref ( )
9795 . is_none_or ( |params| params. parenthesized == GenericArgsParentheses :: No )
9896 && !item. span . from_expansion ( )
97+ // expensive, should be last check
9998 && !is_from_proc_macro ( cx, item)
100- // expensive, should be last check
10199 {
102100 // Self cannot be used inside const generic parameters
103101 let types_to_skip = generics
@@ -117,7 +115,6 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
117115 . collect ( ) ;
118116 StackItem :: Check {
119117 impl_id : item. owner_id . def_id ,
120- in_body : 0 ,
121118 types_to_skip,
122119 }
123120 } else {
@@ -131,6 +128,11 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
131128 }
132129
133130 fn check_impl_item ( & mut self , cx : & LateContext < ' _ > , impl_item : & hir:: ImplItem < ' _ > ) {
131+ // Checking items of `impl Self` blocks in which macro expands into.
132+ if impl_item. span . from_expansion ( ) {
133+ self . stack . push ( StackItem :: NoCheck ) ;
134+ return ;
135+ }
134136 // We want to skip types in trait `impl`s that aren't declared as `Self` in the trait
135137 // declaration. The collection of those types is all this method implementation does.
136138 if let ImplItemKind :: Fn ( FnSig { decl, .. } , ..) = impl_item. kind
@@ -186,18 +188,11 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
186188 }
187189 }
188190
189- fn check_body ( & mut self , _: & LateContext < ' _ > , _: & hir:: Body < ' _ > ) {
190- // `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
191- // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
192- // However the `node_type()` method can *only* be called in bodies.
193- if let Some ( & mut StackItem :: Check { ref mut in_body, .. } ) = self . stack . last_mut ( ) {
194- * in_body = in_body. saturating_add ( 1 ) ;
195- }
196- }
197-
198- fn check_body_post ( & mut self , _: & LateContext < ' _ > , _: & hir:: Body < ' _ > ) {
199- if let Some ( & mut StackItem :: Check { ref mut in_body, .. } ) = self . stack . last_mut ( ) {
200- * in_body = in_body. saturating_sub ( 1 ) ;
191+ fn check_impl_item_post ( & mut self , _: & LateContext < ' _ > , impl_item : & hir:: ImplItem < ' _ > ) {
192+ if impl_item. span . from_expansion ( )
193+ && let Some ( StackItem :: NoCheck ) = self . stack . last ( )
194+ {
195+ self . stack . pop ( ) ;
201196 }
202197 }
203198
@@ -206,7 +201,6 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
206201 && self . msrv . meets ( msrvs:: TYPE_ALIAS_ENUM_VARIANTS )
207202 && let Some ( & StackItem :: Check {
208203 impl_id,
209- in_body,
210204 ref types_to_skip,
211205 } ) = self . stack . last ( )
212206 && let TyKind :: Path ( QPath :: Resolved ( _, path) ) = hir_ty. kind
@@ -215,12 +209,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
215209 Res :: SelfTyParam { .. } | Res :: SelfTyAlias { .. } | Res :: Def ( DefKind :: TyParam , _)
216210 )
217211 && !types_to_skip. contains ( & hir_ty. hir_id )
218- && let ty = if in_body > 0 {
219- cx. typeck_results ( ) . node_type ( hir_ty. hir_id )
220- } else {
221- // We don't care about ignoring infer vars here
222- lower_ty ( cx. tcx , hir_ty. as_unambig_ty ( ) )
223- }
212+ && let ty = ty_from_hir_ty ( cx, hir_ty. as_unambig_ty ( ) )
224213 && let impl_ty = cx. tcx . type_of ( impl_id) . instantiate_identity ( )
225214 && same_type_and_consts ( ty, impl_ty)
226215 // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that
0 commit comments