@@ -75,14 +75,16 @@ pub trait DefIdVisitor<'tcx> {
75
75
}
76
76
77
77
fn tcx ( & self ) -> TyCtxt < ' tcx > ;
78
+ /// NOTE: Def-id visiting should be idempotent, because `DefIdVisitorSkeleton` will avoid
79
+ /// visiting duplicate def-ids. All the current visitors follow this rule.
78
80
fn visit_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display )
79
81
-> Self :: Result ;
80
82
81
83
/// Not overridden, but used to actually visit types and traits.
82
84
fn skeleton ( & mut self ) -> DefIdVisitorSkeleton < ' _ , ' tcx , Self > {
83
85
DefIdVisitorSkeleton {
84
86
def_id_visitor : self ,
85
- visited_opaque_tys : Default :: default ( ) ,
87
+ visited_tys : Default :: default ( ) ,
86
88
dummy : Default :: default ( ) ,
87
89
}
88
90
}
@@ -102,7 +104,7 @@ pub trait DefIdVisitor<'tcx> {
102
104
103
105
pub struct DefIdVisitorSkeleton < ' v , ' tcx , V : ?Sized > {
104
106
def_id_visitor : & ' v mut V ,
105
- visited_opaque_tys : FxHashSet < DefId > ,
107
+ visited_tys : FxHashSet < Ty < ' tcx > > ,
106
108
dummy : PhantomData < TyCtxt < ' tcx > > ,
107
109
}
108
110
@@ -190,6 +192,9 @@ where
190
192
| ty:: Closure ( def_id, ..)
191
193
| ty:: CoroutineClosure ( def_id, ..)
192
194
| ty:: Coroutine ( def_id, ..) => {
195
+ if !self . visited_tys . insert ( ty) {
196
+ return V :: Result :: output ( ) ;
197
+ }
193
198
try_visit ! ( self . def_id_visitor. visit_def_id( def_id, "type" , & ty) ) ;
194
199
if V :: SHALLOW {
195
200
return V :: Result :: output ( ) ;
@@ -212,6 +217,9 @@ where
212
217
}
213
218
}
214
219
ty:: Alias ( kind @ ( ty:: Inherent | ty:: Free | ty:: Projection ) , data) => {
220
+ if !self . visited_tys . insert ( ty) {
221
+ return V :: Result :: output ( ) ;
222
+ }
215
223
if self . def_id_visitor . skip_assoc_tys ( ) {
216
224
// Visitors searching for minimal visibility/reachability want to
217
225
// conservatively approximate associated types like `Type::Alias`
@@ -243,6 +251,9 @@ where
243
251
} ;
244
252
}
245
253
ty:: Dynamic ( predicates, ..) => {
254
+ if !self . visited_tys . insert ( ty) {
255
+ return V :: Result :: output ( ) ;
256
+ }
246
257
// All traits in the list are considered the "primary" part of the type
247
258
// and are visited by shallow visitors.
248
259
for predicate in predicates {
@@ -258,39 +269,45 @@ where
258
269
}
259
270
}
260
271
ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) => {
261
- // Skip repeated `Opaque`s to avoid infinite recursion.
262
- if self . visited_opaque_tys . insert ( def_id) {
263
- // The intent is to treat `impl Trait1 + Trait2` identically to
264
- // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
265
- // (it either has no visibility, or its visibility is insignificant, like
266
- // visibilities of type aliases) and recurse into bounds instead to go
267
- // through the trait list (default type visitor doesn't visit those traits).
268
- // All traits in the list are considered the "primary" part of the type
269
- // and are visited by shallow visitors.
270
- try_visit ! ( self . visit_clauses( tcx. explicit_item_bounds( def_id) . skip_binder( ) ) ) ;
272
+ if !self . visited_tys . insert ( ty) {
273
+ return V :: Result :: output ( ) ;
271
274
}
275
+ // The intent is to treat `impl Trait1 + Trait2` identically to
276
+ // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
277
+ // (it either has no visibility, or its visibility is insignificant, like
278
+ // visibilities of type aliases) and recurse into bounds instead to go
279
+ // through the trait list (default type visitor doesn't visit those traits).
280
+ // All traits in the list are considered the "primary" part of the type
281
+ // and are visited by shallow visitors.
282
+ try_visit ! ( self . visit_clauses( tcx. explicit_item_bounds( def_id) . skip_binder( ) ) ) ;
272
283
}
273
- // These types don't have their own def-ids (but may have subcomponents
274
- // with def-ids that should be visited recursively).
284
+ // These types have neither their own def-ids nor subcomponents.
275
285
ty:: Bool
276
286
| ty:: Char
277
287
| ty:: Int ( ..)
278
288
| ty:: Uint ( ..)
279
289
| ty:: Float ( ..)
280
290
| ty:: Str
281
291
| ty:: Never
282
- | ty:: Array ( ..)
292
+ | ty:: Bound ( ..)
293
+ | ty:: Param ( ..) => return V :: Result :: output ( ) ,
294
+
295
+ // These types don't have their own def-ids (but may have subcomponents
296
+ // with def-ids that should be visited recursively).
297
+ ty:: Array ( ..)
283
298
| ty:: Slice ( ..)
284
299
| ty:: Tuple ( ..)
285
300
| ty:: RawPtr ( ..)
286
301
| ty:: Ref ( ..)
287
302
| ty:: Pat ( ..)
288
303
| ty:: FnPtr ( ..)
289
304
| ty:: UnsafeBinder ( _)
290
- | ty:: Param ( ..)
291
- | ty:: Bound ( ..)
292
305
| ty:: Error ( _)
293
- | ty:: CoroutineWitness ( ..) => { }
306
+ | ty:: CoroutineWitness ( ..) => {
307
+ if !self . visited_tys . insert ( ty) {
308
+ return V :: Result :: output ( ) ;
309
+ }
310
+ }
294
311
ty:: Placeholder ( ..) | ty:: Infer ( ..) => {
295
312
bug ! ( "unexpected type: {:?}" , ty)
296
313
}
@@ -923,7 +940,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
923
940
924
941
// Checks that a field in a struct constructor (expression or pattern) is accessible.
925
942
fn check_field (
926
- & mut self ,
943
+ & self ,
927
944
hir_id : hir:: HirId , // ID of the field use
928
945
use_ctxt : Span , // syntax context of the field name at the use site
929
946
def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
@@ -941,7 +958,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
941
958
942
959
// Checks that a field in a struct constructor (expression or pattern) is accessible.
943
960
fn emit_unreachable_field_error (
944
- & mut self ,
961
+ & self ,
945
962
fields : Vec < ( Symbol , Span , bool /* field is present */ ) > ,
946
963
def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
947
964
update_syntax : Option < Span > ,
@@ -1004,7 +1021,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
1004
1021
}
1005
1022
1006
1023
fn check_expanded_fields (
1007
- & mut self ,
1024
+ & self ,
1008
1025
adt : ty:: AdtDef < ' tcx > ,
1009
1026
variant : & ' tcx ty:: VariantDef ,
1010
1027
fields : & [ hir:: ExprField < ' tcx > ] ,
@@ -1142,7 +1159,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
1142
1159
result. is_break ( )
1143
1160
}
1144
1161
1145
- fn check_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1162
+ fn check_def_id ( & self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1146
1163
let is_error = !self . item_is_accessible ( def_id) ;
1147
1164
if is_error {
1148
1165
self . tcx . dcx ( ) . emit_err ( ItemIsPrivate { span : self . span , kind, descr : descr. into ( ) } ) ;
@@ -1401,7 +1418,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
1401
1418
self
1402
1419
}
1403
1420
1404
- fn check_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1421
+ fn check_def_id ( & self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1405
1422
if self . leaks_private_dep ( def_id) {
1406
1423
self . tcx . emit_node_span_lint (
1407
1424
lint:: builtin:: EXPORTED_PRIVATE_DEPENDENCIES ,
0 commit comments