@@ -13,7 +13,7 @@ use rustc_hir::{
13
13
} ;
14
14
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
15
15
use rustc_middle:: hir:: map:: Map ;
16
- use rustc_middle:: ty:: { AssocKind , Ty } ;
16
+ use rustc_middle:: ty:: AssocKind ;
17
17
use rustc_semver:: RustcVersion ;
18
18
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
19
19
use rustc_span:: Span ;
@@ -75,8 +75,8 @@ impl UseSelf {
75
75
enum StackItem {
76
76
Check {
77
77
impl_id : LocalDefId ,
78
+ in_body : u32 ,
78
79
types_to_skip : FxHashSet < HirId > ,
79
- types_to_lint : Vec < HirId > ,
80
80
} ,
81
81
NoCheck ,
82
82
}
@@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
108
108
then {
109
109
StackItem :: Check {
110
110
impl_id: item. def_id,
111
- types_to_lint : Vec :: new ( ) ,
111
+ in_body : 0 ,
112
112
types_to_skip: std:: iter:: once( self_ty. hir_id) . collect( ) ,
113
113
}
114
114
} else {
@@ -182,51 +182,39 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
182
182
}
183
183
}
184
184
185
- fn check_body ( & mut self , cx : & LateContext < ' tcx > , body : & ' tcx hir:: Body < ' _ > ) {
185
+ fn check_body ( & mut self , _ : & LateContext < ' _ > , _ : & hir:: Body < ' _ > ) {
186
186
// `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
187
187
// we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
188
188
// 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
+ }
202
193
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 ) ;
212
197
}
213
198
}
214
199
215
200
fn check_ty ( & mut self , cx : & LateContext < ' _ > , hir_ty : & hir:: Ty < ' _ > ) {
216
201
if_chain ! {
217
202
if !in_macro( hir_ty. span) ;
218
203
if meets_msrv( self . msrv. as_ref( ) , & msrvs:: TYPE_ALIAS_ENUM_VARIANTS ) ;
219
- if let Some ( StackItem :: Check {
204
+ if let Some ( & StackItem :: Check {
220
205
impl_id,
221
- types_to_lint ,
222
- types_to_skip,
206
+ in_body ,
207
+ ref types_to_skip,
223
208
} ) = 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 , _) ) ;
224
211
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) ) ;
230
218
let hir = cx. tcx. hir( ) ;
231
219
let id = hir. get_parent_node( hir_ty. hir_id) ;
232
220
if !hir. opt_span( id) . map_or( false , in_macro) ;
@@ -289,35 +277,6 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
289
277
}
290
278
}
291
279
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
-
321
280
fn span_lint ( cx : & LateContext < ' _ > , span : Span ) {
322
281
span_lint_and_sugg (
323
282
cx,
@@ -346,15 +305,3 @@ fn is_item_interesting(item: &Item<'_>) -> bool {
346
305
Impl { .. } | Static ( ..) | Const ( ..) | Fn ( ..) | Enum ( ..) | Struct ( ..) | Union ( ..) | Trait ( ..)
347
306
)
348
307
}
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