@@ -75,14 +75,16 @@ pub trait DefIdVisitor<'tcx> {
7575 }
7676
7777 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.
7880 fn visit_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display )
7981 -> Self :: Result ;
8082
8183 /// Not overridden, but used to actually visit types and traits.
8284 fn skeleton ( & mut self ) -> DefIdVisitorSkeleton < ' _ , ' tcx , Self > {
8385 DefIdVisitorSkeleton {
8486 def_id_visitor : self ,
85- visited_opaque_tys : Default :: default ( ) ,
87+ visited_tys : Default :: default ( ) ,
8688 dummy : Default :: default ( ) ,
8789 }
8890 }
@@ -102,7 +104,7 @@ pub trait DefIdVisitor<'tcx> {
102104
103105pub struct DefIdVisitorSkeleton < ' v , ' tcx , V : ?Sized > {
104106 def_id_visitor : & ' v mut V ,
105- visited_opaque_tys : FxHashSet < DefId > ,
107+ visited_tys : FxHashSet < Ty < ' tcx > > ,
106108 dummy : PhantomData < TyCtxt < ' tcx > > ,
107109}
108110
@@ -190,6 +192,9 @@ where
190192 | ty:: Closure ( def_id, ..)
191193 | ty:: CoroutineClosure ( def_id, ..)
192194 | ty:: Coroutine ( def_id, ..) => {
195+ if !self . visited_tys . insert ( ty) {
196+ return V :: Result :: output ( ) ;
197+ }
193198 try_visit ! ( self . def_id_visitor. visit_def_id( def_id, "type" , & ty) ) ;
194199 if V :: SHALLOW {
195200 return V :: Result :: output ( ) ;
@@ -212,6 +217,9 @@ where
212217 }
213218 }
214219 ty:: Alias ( kind @ ( ty:: Inherent | ty:: Free | ty:: Projection ) , data) => {
220+ if !self . visited_tys . insert ( ty) {
221+ return V :: Result :: output ( ) ;
222+ }
215223 if self . def_id_visitor . skip_assoc_tys ( ) {
216224 // Visitors searching for minimal visibility/reachability want to
217225 // conservatively approximate associated types like `Type::Alias`
@@ -243,6 +251,9 @@ where
243251 } ;
244252 }
245253 ty:: Dynamic ( predicates, ..) => {
254+ if !self . visited_tys . insert ( ty) {
255+ return V :: Result :: output ( ) ;
256+ }
246257 // All traits in the list are considered the "primary" part of the type
247258 // and are visited by shallow visitors.
248259 for predicate in predicates {
@@ -258,39 +269,45 @@ where
258269 }
259270 }
260271 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 ( ) ;
271274 }
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( ) ) ) ;
272283 }
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.
275285 ty:: Bool
276286 | ty:: Char
277287 | ty:: Int ( ..)
278288 | ty:: Uint ( ..)
279289 | ty:: Float ( ..)
280290 | ty:: Str
281291 | 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 ( ..)
283298 | ty:: Slice ( ..)
284299 | ty:: Tuple ( ..)
285300 | ty:: RawPtr ( ..)
286301 | ty:: Ref ( ..)
287302 | ty:: Pat ( ..)
288303 | ty:: FnPtr ( ..)
289304 | ty:: UnsafeBinder ( _)
290- | ty:: Param ( ..)
291- | ty:: Bound ( ..)
292305 | ty:: Error ( _)
293- | ty:: CoroutineWitness ( ..) => { }
306+ | ty:: CoroutineWitness ( ..) => {
307+ if !self . visited_tys . insert ( ty) {
308+ return V :: Result :: output ( ) ;
309+ }
310+ }
294311 ty:: Placeholder ( ..) | ty:: Infer ( ..) => {
295312 bug ! ( "unexpected type: {:?}" , ty)
296313 }
@@ -923,7 +940,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
923940
924941 // Checks that a field in a struct constructor (expression or pattern) is accessible.
925942 fn check_field (
926- & mut self ,
943+ & self ,
927944 hir_id : hir:: HirId , // ID of the field use
928945 use_ctxt : Span , // syntax context of the field name at the use site
929946 def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
@@ -941,7 +958,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
941958
942959 // Checks that a field in a struct constructor (expression or pattern) is accessible.
943960 fn emit_unreachable_field_error (
944- & mut self ,
961+ & self ,
945962 fields : Vec < ( Symbol , Span , bool /* field is present */ ) > ,
946963 def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
947964 update_syntax : Option < Span > ,
@@ -1004,7 +1021,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
10041021 }
10051022
10061023 fn check_expanded_fields (
1007- & mut self ,
1024+ & self ,
10081025 adt : ty:: AdtDef < ' tcx > ,
10091026 variant : & ' tcx ty:: VariantDef ,
10101027 fields : & [ hir:: ExprField < ' tcx > ] ,
@@ -1142,7 +1159,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
11421159 result. is_break ( )
11431160 }
11441161
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 {
11461163 let is_error = !self . item_is_accessible ( def_id) ;
11471164 if is_error {
11481165 self . tcx . dcx ( ) . emit_err ( ItemIsPrivate { span : self . span , kind, descr : descr. into ( ) } ) ;
@@ -1401,7 +1418,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14011418 self
14021419 }
14031420
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 {
14051422 if self . leaks_private_dep ( def_id) {
14061423 self . tcx . emit_node_span_lint (
14071424 lint:: builtin:: EXPORTED_PRIVATE_DEPENDENCIES ,
0 commit comments