@@ -51,6 +51,7 @@ mod diagnostics;
51
51
/// in `impl Trait`, see individual commits in `DefIdVisitorSkeleton::visit_ty`.
52
52
trait DefIdVisitor < ' a , ' tcx : ' a > {
53
53
fn tcx ( & self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
54
+ fn recurse ( & self ) -> bool { true }
54
55
fn recurse_into_assoc_tys ( & self ) -> bool { true }
55
56
fn visit_def_id ( & mut self , def_id : DefId , kind : & str , descr : & dyn fmt:: Display ) -> bool ;
56
57
@@ -86,7 +87,8 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
86
87
{
87
88
fn visit_trait ( & mut self , trait_ref : TraitRef < ' tcx > ) -> bool {
88
89
let TraitRef { def_id, substs } = trait_ref;
89
- self . def_id_visitor . visit_def_id ( def_id, "trait" , & trait_ref) || substs. visit_with ( self )
90
+ self . def_id_visitor . visit_def_id ( def_id, "trait" , & trait_ref) ||
91
+ self . def_id_visitor . recurse ( ) && substs. visit_with ( self )
90
92
}
91
93
92
94
fn visit_predicates ( & mut self , predicates : Lrc < ty:: GenericPredicates < ' tcx > > ) -> bool {
@@ -167,7 +169,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
167
169
// free type aliases, but this isn't done yet.
168
170
return false ;
169
171
}
170
- // This will also visit substs, so we don't need to recurse.
172
+ // This will also visit substs if necessary , so we don't need to recurse.
171
173
return self . visit_trait ( proj. trait_ref ( tcx) ) ;
172
174
}
173
175
ty:: Dynamic ( predicates, ..) => {
@@ -206,7 +208,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
206
208
bug ! ( "unexpected type: {:?}" , ty) ,
207
209
}
208
210
209
- ty. super_visit_with ( self )
211
+ self . def_id_visitor . recurse ( ) && ty. super_visit_with ( self )
210
212
}
211
213
}
212
214
@@ -325,6 +327,7 @@ struct FindMin<'a, 'tcx, VL: VisibilityLike> {
325
327
326
328
impl < ' a , ' tcx , VL : VisibilityLike > DefIdVisitor < ' a , ' tcx > for FindMin < ' a , ' tcx , VL > {
327
329
fn tcx ( & self ) -> TyCtxt < ' a , ' tcx , ' tcx > { self . tcx }
330
+ fn recurse ( & self ) -> bool { VL :: RECURSE }
328
331
fn recurse_into_assoc_tys ( & self ) -> bool { false }
329
332
fn visit_def_id ( & mut self , def_id : DefId , _kind : & str , _descr : & dyn fmt:: Display ) -> bool {
330
333
self . min = VL :: new_min ( self , def_id) ;
@@ -334,6 +337,7 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'a, 'tcx> for FindMin<'a, 'tcx,
334
337
335
338
trait VisibilityLike : Sized {
336
339
const MAX : Self ;
340
+ const RECURSE : bool = true ;
337
341
fn new_min < ' a , ' tcx > ( find : & FindMin < ' a , ' tcx , Self > , def_id : DefId ) -> Self ;
338
342
339
343
// Returns an over-approximation (`recurse_into_assoc_tys` = false) of visibility due to
@@ -357,6 +361,12 @@ impl VisibilityLike for ty::Visibility {
357
361
}
358
362
impl VisibilityLike for Option < AccessLevel > {
359
363
const MAX : Self = Some ( AccessLevel :: Public ) ;
364
+ // Type inference is very smart sometimes.
365
+ // It can make an impl reachable even some components of its type or trait are unreachable.
366
+ // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
367
+ // 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 ;
360
370
fn new_min < ' a , ' tcx > ( find : & FindMin < ' a , ' tcx , Self > , def_id : DefId ) -> Self {
361
371
cmp:: min ( if let Some ( node_id) = find. tcx . hir ( ) . as_local_node_id ( def_id) {
362
372
find. access_levels . map . get ( & node_id) . cloned ( )
0 commit comments