@@ -51,8 +51,8 @@ mod diagnostics;
5151/// in `impl Trait`, see individual commits in `DefIdVisitorSkeleton::visit_ty`.
5252trait DefIdVisitor < ' a , ' tcx : ' a > {
5353 fn tcx ( & self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
54- fn recurse ( & self ) -> bool { true }
55- fn recurse_into_assoc_tys ( & self ) -> bool { true }
54+ fn shallow ( & self ) -> bool { false }
55+ fn skip_assoc_tys ( & self ) -> bool { false }
5656 fn visit_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool ;
5757
5858 /// Not overridden, but used to actually visit types and traits.
@@ -88,7 +88,7 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
8888 fn visit_trait ( & mut self , trait_ref : TraitRef < ' tcx > ) -> bool {
8989 let TraitRef { def_id, substs } = trait_ref;
9090 self . def_id_visitor . visit_def_id ( def_id, "trait" , & trait_ref) ||
91- self . def_id_visitor . recurse ( ) && substs. visit_with ( self )
91+ ( ! self . def_id_visitor . shallow ( ) && substs. visit_with ( self ) )
9292 }
9393
9494 fn visit_predicates ( & mut self , predicates : Lrc < ty:: GenericPredicates < ' tcx > > ) -> bool {
@@ -140,6 +140,9 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
140140 if self . def_id_visitor . visit_def_id ( def_id, "type" , ty) {
141141 return true ;
142142 }
143+ if self . def_id_visitor . shallow ( ) {
144+ return false ;
145+ }
143146 // Default type visitor doesn't visit signatures of fn types.
144147 // Something like `fn() -> Priv {my_func}` is considered a private type even if
145148 // `my_func` is public, so we need to visit signatures.
@@ -161,7 +164,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
161164 }
162165 }
163166 ty:: Projection ( proj) | ty:: UnnormalizedProjection ( proj) => {
164- if ! self . def_id_visitor . recurse_into_assoc_tys ( ) {
167+ if self . def_id_visitor . skip_assoc_tys ( ) {
165168 // Visitors searching for minimal visibility/reachability want to
166169 // conservatively approximate associated types like `<Type as Trait>::Alias`
167170 // as visible/reachable even if both `Type` and `Trait` are private.
@@ -173,6 +176,8 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
173176 return self . visit_trait ( proj. trait_ref ( tcx) ) ;
174177 }
175178 ty:: Dynamic ( predicates, ..) => {
179+ // All traits in the list are considered the "primary" part of the type
180+ // and are visited by shallow visitors.
176181 for predicate in * predicates. skip_binder ( ) {
177182 let trait_ref = match * predicate {
178183 ty:: ExistentialPredicate :: Trait ( trait_ref) => trait_ref,
@@ -189,9 +194,13 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
189194 ty:: Opaque ( def_id, ..) => {
190195 // Skip repeated `Opaque`s to avoid infinite recursion.
191196 if self . visited_opaque_tys . insert ( def_id) {
192- // Default type visitor doesn't visit traits in `impl Trait`.
193- // Something like `impl PrivTr` is considered a private type,
194- // so we need to visit the traits additionally.
197+ // The intent is to treat `impl Trait1 + Trait2` identically to
198+ // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
199+ // (it either has no visibility, or its visibility is insignificant, like
200+ // visibilities of type aliases) and recurse into predicates instead to go
201+ // through the trait list (default type visitor doesn't visit those traits).
202+ // All traits in the list are considered the "primary" part of the type
203+ // and are visited by shallow visitors.
195204 if self . visit_predicates ( tcx. predicates_of ( def_id) ) {
196205 return true ;
197206 }
@@ -208,7 +217,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
208217 bug ! ( "unexpected type: {:?}" , ty) ,
209218 }
210219
211- self . def_id_visitor . recurse ( ) && ty. super_visit_with ( self )
220+ ! self . def_id_visitor . shallow ( ) && ty. super_visit_with ( self )
212221 }
213222}
214223
@@ -327,8 +336,8 @@ struct FindMin<'a, 'tcx, VL: VisibilityLike> {
327336
328337impl < ' a , ' tcx , VL : VisibilityLike > DefIdVisitor < ' a , ' tcx > for FindMin < ' a , ' tcx , VL > {
329338 fn tcx ( & self ) -> TyCtxt < ' a , ' tcx , ' tcx > { self . tcx }
330- fn recurse ( & self ) -> bool { VL :: RECURSE }
331- fn recurse_into_assoc_tys ( & self ) -> bool { false }
339+ fn shallow ( & self ) -> bool { VL :: SHALLOW }
340+ fn skip_assoc_tys ( & self ) -> bool { true }
332341 fn visit_def_id ( & mut self , def_id : DefId , _kind : & str , _descr : & dyn fmt:: Display ) -> bool {
333342 self . min = VL :: new_min ( self , def_id) ;
334343 false
@@ -337,10 +346,10 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'a, 'tcx> for FindMin<'a, 'tcx,
337346
338347trait VisibilityLike : Sized {
339348 const MAX : Self ;
340- const RECURSE : bool = true ;
349+ const SHALLOW : bool = false ;
341350 fn new_min < ' a , ' tcx > ( find : & FindMin < ' a , ' tcx , Self > , def_id : DefId ) -> Self ;
342351
343- // Returns an over-approximation (`recurse_into_assoc_tys ` = false ) of visibility due to
352+ // Returns an over-approximation (`skip_assoc_tys ` = true ) of visibility due to
344353 // associated types for which we can't determine visibility precisely.
345354 fn of_impl < ' a , ' tcx > ( node_id : ast:: NodeId , tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
346355 access_levels : & ' a AccessLevels ) -> Self {
@@ -365,8 +374,12 @@ impl VisibilityLike for Option<AccessLevel> {
365374 // It can make an impl reachable even some components of its type or trait are unreachable.
366375 // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
367376 // can be usable from other crates (#57264). So we skip substs when calculating reachability
368- // and consider an impl reachable if its "primary" type and trait are reachable.
369- const RECURSE : bool = false ;
377+ // and consider an impl reachable if its "shallow" type and trait are reachable.
378+ //
379+ // The assumption we make here is that type-inference won't let you use an impl without knowing
380+ // both "shallow" version of its self type and "shallow" version of its trait if it exists
381+ // (which require reaching the `DefId`s in them).
382+ const SHALLOW : bool = true ;
370383 fn new_min < ' a , ' tcx > ( find : & FindMin < ' a , ' tcx , Self > , def_id : DefId ) -> Self {
371384 cmp:: min ( if let Some ( node_id) = find. tcx . hir ( ) . as_local_node_id ( def_id) {
372385 find. access_levels . map . get ( & node_id) . cloned ( )
0 commit comments