Skip to content

Commit fb00313

Browse files
committed
Address review comments
1 parent 9503c56 commit fb00313

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/librustc_privacy/lib.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ mod diagnostics;
5151
/// in `impl Trait`, see individual commits in `DefIdVisitorSkeleton::visit_ty`.
5252
trait 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

328337
impl<'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

338347
trait 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

Comments
 (0)