Skip to content

Commit 67713f5

Browse files
committed
privacy: Fix regression in impl reachability
1 parent 68fe518 commit 67713f5

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

src/librustc_privacy/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ 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 }
5455
fn recurse_into_assoc_tys(&self) -> bool { true }
5556
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool;
5657

@@ -86,7 +87,8 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
8687
{
8788
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
8889
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)
9092
}
9193

9294
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>
167169
// free type aliases, but this isn't done yet.
168170
return false;
169171
}
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.
171173
return self.visit_trait(proj.trait_ref(tcx));
172174
}
173175
ty::Dynamic(predicates, ..) => {
@@ -206,7 +208,7 @@ impl<'a, 'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
206208
bug!("unexpected type: {:?}", ty),
207209
}
208210

209-
ty.super_visit_with(self)
211+
self.def_id_visitor.recurse() && ty.super_visit_with(self)
210212
}
211213
}
212214

@@ -325,6 +327,7 @@ struct FindMin<'a, 'tcx, VL: VisibilityLike> {
325327

326328
impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'a, 'tcx> for FindMin<'a, 'tcx, VL> {
327329
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
330+
fn recurse(&self) -> bool { VL::RECURSE }
328331
fn recurse_into_assoc_tys(&self) -> bool { false }
329332
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
330333
self.min = VL::new_min(self, def_id);
@@ -334,6 +337,7 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'a, 'tcx> for FindMin<'a, 'tcx,
334337

335338
trait VisibilityLike: Sized {
336339
const MAX: Self;
340+
const RECURSE: bool = true;
337341
fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self;
338342

339343
// Returns an over-approximation (`recurse_into_assoc_tys` = false) of visibility due to
@@ -357,6 +361,12 @@ impl VisibilityLike for ty::Visibility {
357361
}
358362
impl VisibilityLike for Option<AccessLevel> {
359363
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;
360370
fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self {
361371
cmp::min(if let Some(node_id) = find.tcx.hir().as_local_node_id(def_id) {
362372
find.access_levels.map.get(&node_id).cloned()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
mod inner {
2+
pub struct PubUnnameable;
3+
}
4+
5+
pub struct Pub<T>(T);
6+
7+
impl Pub<inner::PubUnnameable> {
8+
pub fn pub_method() {}
9+
}

src/test/ui/privacy/issue-57264.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// compile-pass
2+
// aux-build:issue-57264.rs
3+
4+
extern crate issue_57264;
5+
6+
fn main() {
7+
issue_57264::Pub::pub_method();
8+
}

0 commit comments

Comments
 (0)