@@ -13,7 +13,7 @@ use rustc_hir::{
1313} ;
1414use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1515use rustc_middle:: hir:: map:: Map ;
16- use rustc_middle:: ty:: { AssocKind , Ty } ;
16+ use rustc_middle:: ty:: AssocKind ;
1717use rustc_semver:: RustcVersion ;
1818use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
1919use rustc_span:: Span ;
@@ -75,8 +75,8 @@ impl UseSelf {
7575enum StackItem {
7676 Check {
7777 impl_id : LocalDefId ,
78+ in_body : u32 ,
7879 types_to_skip : FxHashSet < HirId > ,
79- types_to_lint : Vec < HirId > ,
8080 } ,
8181 NoCheck ,
8282}
@@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
108108 then {
109109 StackItem :: Check {
110110 impl_id: item. def_id,
111- types_to_lint : Vec :: new ( ) ,
111+ in_body : 0 ,
112112 types_to_skip: std:: iter:: once( self_ty. hir_id) . collect( ) ,
113113 }
114114 } else {
@@ -182,51 +182,39 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
182182 }
183183 }
184184
185- fn check_body ( & mut self , cx : & LateContext < ' tcx > , body : & ' tcx hir:: Body < ' _ > ) {
185+ fn check_body ( & mut self , _ : & LateContext < ' _ > , _ : & hir:: Body < ' _ > ) {
186186 // `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
187187 // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
188188 // However the `node_type()` method can *only* be called in bodies.
189- //
190- // This method implementation determines which types should get linted in a `Body` and
191- // which shouldn't, with a visitor. We could directly lint in the visitor, but then we
192- // could only allow this lint on item scope. And we would have to check if those types are
193- // already dealt with in `check_ty` anyway.
194- if let Some ( StackItem :: Check {
195- impl_id,
196- types_to_lint,
197- types_to_skip,
198- ..
199- } ) = self . stack . last_mut ( )
200- {
201- let self_ty = cx. tcx . type_of ( * impl_id) ;
189+ if let Some ( & mut StackItem :: Check { ref mut in_body, .. } ) = self . stack . last_mut ( ) {
190+ * in_body = in_body. saturating_add ( 1 ) ;
191+ }
192+ }
202193
203- let mut visitor = LintTyCollector {
204- cx,
205- self_ty,
206- types_to_lint : vec ! [ ] ,
207- types_to_skip : vec ! [ ] ,
208- } ;
209- visitor. visit_expr ( & body. value ) ;
210- types_to_lint. extend ( visitor. types_to_lint ) ;
211- types_to_skip. extend ( visitor. types_to_skip ) ;
194+ fn check_body_post ( & mut self , _: & LateContext < ' _ > , _: & hir:: Body < ' _ > ) {
195+ if let Some ( & mut StackItem :: Check { ref mut in_body, .. } ) = self . stack . last_mut ( ) {
196+ * in_body = in_body. saturating_sub ( 1 ) ;
212197 }
213198 }
214199
215200 fn check_ty ( & mut self , cx : & LateContext < ' _ > , hir_ty : & hir:: Ty < ' _ > ) {
216201 if_chain ! {
217202 if !in_macro( hir_ty. span) ;
218203 if meets_msrv( self . msrv. as_ref( ) , & msrvs:: TYPE_ALIAS_ENUM_VARIANTS ) ;
219- if let Some ( StackItem :: Check {
204+ if let Some ( & StackItem :: Check {
220205 impl_id,
221- types_to_lint ,
222- types_to_skip,
206+ in_body ,
207+ ref types_to_skip,
223208 } ) = self . stack. last( ) ;
209+ if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = hir_ty. kind;
210+ if !matches!( path. res, Res :: SelfTy ( ..) | Res :: Def ( DefKind :: TyParam , _) ) ;
224211 if !types_to_skip. contains( & hir_ty. hir_id) ;
225- if types_to_lint. contains( & hir_ty. hir_id)
226- || {
227- let self_ty = cx. tcx. type_of( * impl_id) ;
228- should_lint_ty( hir_ty, hir_ty_to_ty( cx. tcx, hir_ty) , self_ty)
229- } ;
212+ let ty = if in_body > 0 {
213+ cx. typeck_results( ) . node_type( hir_ty. hir_id)
214+ } else {
215+ hir_ty_to_ty( cx. tcx, hir_ty)
216+ } ;
217+ if same_type_and_consts( ty, cx. tcx. type_of( impl_id) ) ;
230218 let hir = cx. tcx. hir( ) ;
231219 let id = hir. get_parent_node( hir_ty. hir_id) ;
232220 if !hir. opt_span( id) . map_or( false , in_macro) ;
@@ -289,35 +277,6 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
289277 }
290278}
291279
292- struct LintTyCollector < ' a , ' tcx > {
293- cx : & ' a LateContext < ' tcx > ,
294- self_ty : Ty < ' tcx > ,
295- types_to_lint : Vec < HirId > ,
296- types_to_skip : Vec < HirId > ,
297- }
298-
299- impl < ' a , ' tcx > Visitor < ' tcx > for LintTyCollector < ' a , ' tcx > {
300- type Map = Map < ' tcx > ;
301-
302- fn visit_ty ( & mut self , hir_ty : & ' tcx hir:: Ty < ' _ > ) {
303- if_chain ! {
304- if let Some ( ty) = self . cx. typeck_results( ) . node_type_opt( hir_ty. hir_id) ;
305- if should_lint_ty( hir_ty, ty, self . self_ty) ;
306- then {
307- self . types_to_lint. push( hir_ty. hir_id) ;
308- } else {
309- self . types_to_skip. push( hir_ty. hir_id) ;
310- }
311- }
312-
313- walk_ty ( self , hir_ty) ;
314- }
315-
316- fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
317- NestedVisitorMap :: None
318- }
319- }
320-
321280fn span_lint ( cx : & LateContext < ' _ > , span : Span ) {
322281 span_lint_and_sugg (
323282 cx,
@@ -346,15 +305,3 @@ fn is_item_interesting(item: &Item<'_>) -> bool {
346305 Impl { .. } | Static ( ..) | Const ( ..) | Fn ( ..) | Enum ( ..) | Struct ( ..) | Union ( ..) | Trait ( ..)
347306 )
348307}
349-
350- fn should_lint_ty ( hir_ty : & hir:: Ty < ' _ > , ty : Ty < ' _ > , self_ty : Ty < ' _ > ) -> bool {
351- if_chain ! {
352- if same_type_and_consts( ty, self_ty) ;
353- if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = hir_ty. kind;
354- then {
355- !matches!( path. res, Res :: SelfTy ( ..) | Res :: Def ( DefKind :: TyParam , _) )
356- } else {
357- false
358- }
359- }
360- }
0 commit comments