Skip to content

Commit 95a24c6

Browse files
committed
privacy: Do not mark items reachable farther than their nominal visibility
This commit reverts a change made in #111425. It was believed that this change was necessary for implementing type privacy lints, but #111801 showed that it was not necessary. Quite opposite, the revert fixes some issues.
1 parent 17edd1a commit 95a24c6

File tree

6 files changed

+37
-34
lines changed

6 files changed

+37
-34
lines changed

compiler/rustc_lint/src/builtin.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,7 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS])
665665

666666
impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
667667
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
668-
if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id)
669-
&& cx.tcx.local_visibility(item.owner_id.def_id).is_public())
670-
{
668+
if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
671669
return;
672670
}
673671
let (def, ty) = match item.kind {
@@ -786,9 +784,7 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
786784

787785
impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
788786
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
789-
if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id)
790-
&& cx.tcx.local_visibility(item.owner_id.def_id).is_public())
791-
{
787+
if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
792788
return;
793789
}
794790

compiler/rustc_middle/src/middle/privacy.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use crate::ty::{TyCtxt, Visibility};
55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
7+
use rustc_hir::def::DefKind;
78
use rustc_macros::HashStable;
89
use rustc_query_system::ich::StableHashingContext;
910
use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
@@ -148,13 +149,12 @@ impl EffectiveVisibilities {
148149
};
149150
}
150151

151-
pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) {
152+
pub fn check_invariants(&self, tcx: TyCtxt<'_>) {
152153
if !cfg!(debug_assertions) {
153154
return;
154155
}
155156
for (&def_id, ev) in &self.map {
156157
// More direct visibility levels can never go farther than less direct ones,
157-
// neither of effective visibilities can go farther than nominal visibility,
158158
// and all effective visibilities are larger or equal than private visibility.
159159
let private_vis = Visibility::Restricted(tcx.parent_module_from_def_id(def_id));
160160
let span = tcx.def_span(def_id.to_def_id());
@@ -175,17 +175,20 @@ impl EffectiveVisibilities {
175175
ev.reachable_through_impl_trait
176176
);
177177
}
178-
let nominal_vis = tcx.visibility(def_id);
179-
// FIXME: `rustc_privacy` is not yet updated for the new logic and can set
180-
// effective visibilities that are larger than the nominal one.
181-
if !nominal_vis.is_at_least(ev.reachable_through_impl_trait, tcx) && early {
182-
span_bug!(
183-
span,
184-
"{:?}: reachable_through_impl_trait {:?} > nominal {:?}",
185-
def_id,
186-
ev.reachable_through_impl_trait,
187-
nominal_vis
188-
);
178+
// All effective visibilities except `reachable_through_impl_trait` are limited to
179+
// nominal visibility. For some items nominal visibility doesn't make sense so we
180+
// don't check this condition for them.
181+
if !matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
182+
let nominal_vis = tcx.visibility(def_id);
183+
if !nominal_vis.is_at_least(ev.reachable, tcx) {
184+
span_bug!(
185+
span,
186+
"{:?}: reachable {:?} > nominal {:?}",
187+
def_id,
188+
ev.reachable,
189+
nominal_vis
190+
);
191+
}
189192
}
190193
}
191194
}

compiler/rustc_privacy/src/lib.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,12 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
894894
_descr: &dyn fmt::Display,
895895
) -> ControlFlow<Self::BreakTy> {
896896
if let Some(def_id) = def_id.as_local() {
897-
self.ev.update_eff_vis(def_id, self.effective_vis, None, self.level);
897+
// All effective visibilities except `reachable_through_impl_trait` are limited to
898+
// nominal visibility. If any type or trait is leaked farther than that, it will
899+
// produce type privacy errors on any use, so we don't consider it leaked.
900+
let nominal_vis = (self.level != Level::ReachableThroughImplTrait)
901+
.then(|| self.ev.tcx.local_visibility(def_id));
902+
self.ev.update_eff_vis(def_id, self.effective_vis, nominal_vis, self.level);
898903
}
899904
ControlFlow::Continue(())
900905
}
@@ -1869,10 +1874,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
18691874
return false;
18701875
};
18711876

1872-
// FIXME: `Level::Reachable` should be taken instead of `Level::Reexported`
1873-
let reexported_at_vis = *effective_vis.at_level(Level::Reexported);
1877+
let reachable_at_vis = *effective_vis.at_level(Level::Reachable);
18741878

1875-
if !vis.is_at_least(reexported_at_vis, self.tcx) {
1879+
if !vis.is_at_least(reachable_at_vis, self.tcx) {
18761880
let lint = if self.in_primary_interface {
18771881
lint::builtin::PRIVATE_INTERFACES
18781882
} else {
@@ -1889,7 +1893,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
18891893
tcx: self.tcx,
18901894
})
18911895
.into(),
1892-
item_vis_descr: &vis_to_string(self.item_def_id, reexported_at_vis, self.tcx),
1896+
item_vis_descr: &vis_to_string(self.item_def_id, reachable_at_vis, self.tcx),
18931897
ty_span: vis_span,
18941898
ty_kind: kind,
18951899
ty_descr: descr.into(),
@@ -2278,7 +2282,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
22782282
changed: false,
22792283
};
22802284

2281-
visitor.effective_visibilities.check_invariants(tcx, true);
2285+
visitor.effective_visibilities.check_invariants(tcx);
22822286
if visitor.impl_trait_pass {
22832287
// Underlying types of `impl Trait`s are marked as reachable unconditionally,
22842288
// so this pass doesn't need to be a part of the fixed point iteration below.
@@ -2295,7 +2299,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
22952299
break;
22962300
}
22972301
}
2298-
visitor.effective_visibilities.check_invariants(tcx, false);
2302+
visitor.effective_visibilities.check_invariants(tcx);
22992303

23002304
let mut check_visitor =
23012305
TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };

library/core/src/iter/adapters/flatten.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ where
310310
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
311311
/// this type.
312312
#[derive(Clone, Debug)]
313-
#[unstable(feature = "trusted_len", issue = "37572")]
313+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
314314
struct FlattenCompat<I, U> {
315315
iter: Fuse<I>,
316316
frontiter: Option<U>,
@@ -464,7 +464,7 @@ where
464464
}
465465
}
466466

467-
#[unstable(feature = "trusted_len", issue = "37572")]
467+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
468468
impl<I, U> Iterator for FlattenCompat<I, U>
469469
where
470470
I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@@ -579,7 +579,7 @@ where
579579
}
580580
}
581581

582-
#[unstable(feature = "trusted_len", issue = "37572")]
582+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
583583
impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
584584
where
585585
I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@@ -649,23 +649,23 @@ where
649649
}
650650
}
651651

652-
#[unstable(feature = "trusted_len", issue = "37572")]
652+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
653653
unsafe impl<const N: usize, I, T> TrustedLen
654654
for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter>
655655
where
656656
I: TrustedLen<Item = [T; N]>,
657657
{
658658
}
659659

660-
#[unstable(feature = "trusted_len", issue = "37572")]
660+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
661661
unsafe impl<'a, const N: usize, I, T> TrustedLen
662662
for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter>
663663
where
664664
I: TrustedLen<Item = &'a [T; N]>,
665665
{
666666
}
667667

668-
#[unstable(feature = "trusted_len", issue = "37572")]
668+
#[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
669669
unsafe impl<'a, const N: usize, I, T> TrustedLen
670670
for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter>
671671
where

tests/ui/privacy/effective_visibilities_full_priv.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct SemiPriv;
66
mod m {
77
#[rustc_effective_visibility]
88
struct Priv;
9-
//~^ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
9+
//~^ ERROR not in the table
1010
//~| ERROR not in the table
1111

1212
#[rustc_effective_visibility]

tests/ui/privacy/effective_visibilities_full_priv.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
1+
error: not in the table
22
--> $DIR/effective_visibilities_full_priv.rs:8:5
33
|
44
LL | struct Priv;

0 commit comments

Comments
 (0)