@@ -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
@@ -180,6 +182,9 @@ where
180182 }
181183
182184 fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> Self :: Result {
185+ if !self . visited_tys . insert ( ty) {
186+ return V :: Result :: output ( ) ;
187+ }
183188 let tcx = self . def_id_visitor . tcx ( ) ;
184189 // GenericArgs are not visited here because they are visited below
185190 // in `super_visit_with`.
@@ -258,17 +263,14 @@ where
258263 }
259264 }
260265 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( ) ) ) ;
271- }
266+ // The intent is to treat `impl Trait1 + Trait2` identically to
267+ // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
268+ // (it either has no visibility, or its visibility is insignificant, like
269+ // visibilities of type aliases) and recurse into bounds instead to go
270+ // through the trait list (default type visitor doesn't visit those traits).
271+ // All traits in the list are considered the "primary" part of the type
272+ // and are visited by shallow visitors.
273+ try_visit ! ( self . visit_clauses( tcx. explicit_item_bounds( def_id) . skip_binder( ) ) ) ;
272274 }
273275 // These types don't have their own def-ids (but may have subcomponents
274276 // with def-ids that should be visited recursively).
@@ -923,7 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
923925
924926 // Checks that a field in a struct constructor (expression or pattern) is accessible.
925927 fn check_field (
926- & mut self ,
928+ & self ,
927929 hir_id : hir:: HirId , // ID of the field use
928930 use_ctxt : Span , // syntax context of the field name at the use site
929931 def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
@@ -941,7 +943,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
941943
942944 // Checks that a field in a struct constructor (expression or pattern) is accessible.
943945 fn emit_unreachable_field_error (
944- & mut self ,
946+ & self ,
945947 fields : Vec < ( Symbol , Span , bool /* field is present */ ) > ,
946948 def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
947949 update_syntax : Option < Span > ,
@@ -1004,7 +1006,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
10041006 }
10051007
10061008 fn check_expanded_fields (
1007- & mut self ,
1009+ & self ,
10081010 adt : ty:: AdtDef < ' tcx > ,
10091011 variant : & ' tcx ty:: VariantDef ,
10101012 fields : & [ hir:: ExprField < ' tcx > ] ,
@@ -1142,7 +1144,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
11421144 result. is_break ( )
11431145 }
11441146
1145- fn check_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1147+ fn check_def_id ( & self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
11461148 let is_error = !self . item_is_accessible ( def_id) ;
11471149 if is_error {
11481150 self . tcx . dcx ( ) . emit_err ( ItemIsPrivate { span : self . span , kind, descr : descr. into ( ) } ) ;
@@ -1401,7 +1403,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14011403 self
14021404 }
14031405
1404- fn check_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
1406+ fn check_def_id ( & self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool {
14051407 if self . leaks_private_dep ( def_id) {
14061408 self . tcx . emit_node_span_lint (
14071409 lint:: builtin:: EXPORTED_PRIVATE_DEPENDENCIES ,
0 commit comments