Skip to content

Commit 5e917a6

Browse files
committed
increase the accuracy of effective visibilities calculation
1 parent 3572d74 commit 5e917a6

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

Diff for: compiler/rustc_privacy/src/lib.rs

+21-25
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ impl VisibilityLike for ty::Visibility {
409409
}
410410
}
411411

412-
impl VisibilityLike for Option<EffectiveVisibility> {
413-
const MAX: Self = Some(EffectiveVisibility::from_vis(ty::Visibility::Public));
412+
impl VisibilityLike for EffectiveVisibility {
413+
const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public);
414414
// Type inference is very smart sometimes.
415415
// It can make an impl reachable even some components of its type or trait are unreachable.
416416
// E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -422,13 +422,14 @@ impl VisibilityLike for Option<EffectiveVisibility> {
422422
// (which require reaching the `DefId`s in them).
423423
const SHALLOW: bool = true;
424424
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
425-
if let Some(min) = find.min {
426-
return find
427-
.effective_visibilities
428-
.effective_vis(def_id)
429-
.map(|eff_vis| min.min(*eff_vis, find.tcx));
430-
}
431-
None
425+
let effective_vis =
426+
find.effective_visibilities.effective_vis(def_id).cloned().unwrap_or_else(|| {
427+
let private_vis =
428+
ty::Visibility::Restricted(find.tcx.parent_module_from_def_id(def_id));
429+
EffectiveVisibility::from_vis(private_vis)
430+
});
431+
432+
effective_vis.min(find.min, find.tcx)
432433
}
433434
}
434435

@@ -766,28 +767,23 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
766767
}
767768
}
768769
hir::ItemKind::Impl(ref impl_) => {
769-
if let Some(item_ev) = Option::<EffectiveVisibility>::of_impl(
770+
let item_ev = EffectiveVisibility::of_impl(
770771
item.owner_id.def_id,
771772
self.tcx,
772773
&self.effective_visibilities,
773-
) {
774-
self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
774+
);
775+
self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
775776

776-
self.reach(item.owner_id.def_id, item_ev)
777-
.generics()
778-
.predicates()
779-
.ty()
780-
.trait_ref();
777+
self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
781778

782-
for impl_item_ref in impl_.items {
783-
let def_id = impl_item_ref.id.owner_id.def_id;
784-
let nominal_vis =
785-
impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
786-
self.update_eff_vis(def_id, item_ev, nominal_vis, Level::Direct);
779+
for impl_item_ref in impl_.items {
780+
let def_id = impl_item_ref.id.owner_id.def_id;
781+
let nominal_vis =
782+
impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
783+
self.update_eff_vis(def_id, item_ev, nominal_vis, Level::Direct);
787784

788-
if let Some(impl_item_ev) = self.get(def_id) {
789-
self.reach(def_id, impl_item_ev).generics().predicates().ty();
790-
}
785+
if let Some(impl_item_ev) = self.get(def_id) {
786+
self.reach(def_id, impl_item_ev).generics().predicates().ty();
791787
}
792788
}
793789
}

Diff for: compiler/rustc_resolve/src/effective_visibilities.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
8181
def_effective_visibilities: Default::default(),
8282
import_effective_visibilities: Default::default(),
8383
current_private_vis: Visibility::Restricted(CRATE_DEF_ID),
84-
changed: false,
84+
changed: true,
8585
};
8686

8787
visitor.def_effective_visibilities.update_root();

Diff for: tests/ui/privacy/effective_visibilities_full_priv.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(rustc_attrs)]
2+
#![allow(private_in_public)]
3+
4+
struct SemiPriv;
5+
6+
mod m {
7+
#[rustc_effective_visibility]
8+
struct Priv;
9+
//~^ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
10+
//~| ERROR not in the table
11+
12+
#[rustc_effective_visibility]
13+
pub fn foo() {} //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
14+
15+
#[rustc_effective_visibility]
16+
impl crate::SemiPriv { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
17+
pub fn f(_: Priv) {}
18+
}
19+
}
20+
21+
fn main() {}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
2+
--> $DIR/effective_visibilities_full_priv.rs:8:5
3+
|
4+
LL | struct Priv;
5+
| ^^^^^^^^^^^
6+
7+
error: not in the table
8+
--> $DIR/effective_visibilities_full_priv.rs:8:5
9+
|
10+
LL | struct Priv;
11+
| ^^^^^^^^^^^
12+
13+
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
14+
--> $DIR/effective_visibilities_full_priv.rs:13:5
15+
|
16+
LL | pub fn foo() {}
17+
| ^^^^^^^^^^^^
18+
19+
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
20+
--> $DIR/effective_visibilities_full_priv.rs:16:5
21+
|
22+
LL | impl crate::SemiPriv {
23+
| ^^^^^^^^^^^^^^^^^^^^
24+
25+
error: aborting due to 4 previous errors
26+

0 commit comments

Comments
 (0)