@@ -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
@@ -180,6 +182,9 @@ where
180
182
}
181
183
182
184
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> Self :: Result {
185
+ if !self . visited_tys . insert ( ty) {
186
+ return V :: Result :: output ( ) ;
187
+ }
183
188
let tcx = self . def_id_visitor . tcx ( ) ;
184
189
// GenericArgs are not visited here because they are visited below
185
190
// in `super_visit_with`.
@@ -258,17 +263,14 @@ where
258
263
}
259
264
}
260
265
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( ) ) ) ;
272
274
}
273
275
// These types don't have their own def-ids (but may have subcomponents
274
276
// with def-ids that should be visited recursively).
@@ -923,7 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
923
925
924
926
// Checks that a field in a struct constructor (expression or pattern) is accessible.
925
927
fn check_field (
926
- & mut self ,
928
+ & self ,
927
929
hir_id : hir:: HirId , // ID of the field use
928
930
use_ctxt : Span , // syntax context of the field name at the use site
929
931
def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
@@ -941,7 +943,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
941
943
942
944
// Checks that a field in a struct constructor (expression or pattern) is accessible.
943
945
fn emit_unreachable_field_error (
944
- & mut self ,
946
+ & self ,
945
947
fields : Vec < ( Symbol , Span , bool /* field is present */ ) > ,
946
948
def : ty:: AdtDef < ' tcx > , // definition of the struct or enum
947
949
update_syntax : Option < Span > ,
@@ -1004,7 +1006,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
1004
1006
}
1005
1007
1006
1008
fn check_expanded_fields (
1007
- & mut self ,
1009
+ & self ,
1008
1010
adt : ty:: AdtDef < ' tcx > ,
1009
1011
variant : & ' tcx ty:: VariantDef ,
1010
1012
fields : & [ hir:: ExprField < ' tcx > ] ,
@@ -1142,7 +1144,7 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
1142
1144
result. is_break ( )
1143
1145
}
1144
1146
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 {
1146
1148
let is_error = !self . item_is_accessible ( def_id) ;
1147
1149
if is_error {
1148
1150
self . tcx . dcx ( ) . emit_err ( ItemIsPrivate { span : self . span , kind, descr : descr. into ( ) } ) ;
@@ -1401,7 +1403,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
1401
1403
self
1402
1404
}
1403
1405
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 {
1405
1407
if self . leaks_private_dep ( def_id) {
1406
1408
self . tcx . emit_node_span_lint (
1407
1409
lint:: builtin:: EXPORTED_PRIVATE_DEPENDENCIES ,
0 commit comments