Skip to content

Commit fc76f1b

Browse files
committed
privacy: Visit types and traits in impls in type privacy lints
1 parent 2b285cd commit fc76f1b

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

compiler/rustc_privacy/src/lib.rs

+31-9
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
7171
pub trait DefIdVisitor<'tcx> {
7272
type Result: VisitorResult = ();
7373
const SHALLOW: bool = false;
74-
const SKIP_ASSOC_TYS: bool = false;
74+
fn skip_assoc_tys(&self) -> bool {
75+
false
76+
}
7577

7678
fn tcx(&self) -> TyCtxt<'tcx>;
7779
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
@@ -212,7 +214,7 @@ where
212214
}
213215
}
214216
ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => {
215-
if V::SKIP_ASSOC_TYS {
217+
if self.def_id_visitor.skip_assoc_tys() {
216218
// Visitors searching for minimal visibility/reachability want to
217219
// conservatively approximate associated types like `Type::Alias`
218220
// as visible/reachable even if `Type` is private.
@@ -323,7 +325,9 @@ impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
323325
for FindMin<'a, 'tcx, VL, SHALLOW>
324326
{
325327
const SHALLOW: bool = SHALLOW;
326-
const SKIP_ASSOC_TYS: bool = true;
328+
fn skip_assoc_tys(&self) -> bool {
329+
true
330+
}
327331
fn tcx(&self) -> TyCtxt<'tcx> {
328332
self.tcx
329333
}
@@ -341,7 +345,7 @@ trait VisibilityLike: Sized {
341345
def_id: LocalDefId,
342346
) -> Self;
343347

344-
// Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
348+
// Returns an over-approximation (`skip_assoc_tys()` = true) of visibility due to
345349
// associated types for which we can't determine visibility precisely.
346350
fn of_impl<const SHALLOW: bool>(
347351
def_id: LocalDefId,
@@ -1350,6 +1354,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
13501354
required_effective_vis: Option<EffectiveVisibility>,
13511355
in_assoc_ty: bool,
13521356
in_primary_interface: bool,
1357+
skip_assoc_tys: bool,
13531358
}
13541359

13551360
impl SearchInterfaceForPrivateItemsVisitor<'_> {
@@ -1396,6 +1401,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
13961401
self
13971402
}
13981403

1404+
fn trait_ref(&mut self) -> &mut Self {
1405+
self.in_primary_interface = true;
1406+
if let Some(trait_ref) = self.tcx.impl_trait_ref(self.item_def_id) {
1407+
self.visit_trait(trait_ref.instantiate_identity());
1408+
}
1409+
self
1410+
}
1411+
13991412
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
14001413
if self.leaks_private_dep(def_id) {
14011414
self.tcx.emit_node_span_lint(
@@ -1493,6 +1506,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14931506

14941507
impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
14951508
type Result = ControlFlow<()>;
1509+
fn skip_assoc_tys(&self) -> bool {
1510+
self.skip_assoc_tys
1511+
}
14961512
fn tcx(&self) -> TyCtxt<'tcx> {
14971513
self.tcx
14981514
}
@@ -1529,6 +1545,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
15291545
required_effective_vis,
15301546
in_assoc_ty: false,
15311547
in_primary_interface: true,
1548+
skip_assoc_tys: false,
15321549
}
15331550
}
15341551

@@ -1724,13 +1741,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
17241741
self.effective_visibilities,
17251742
);
17261743

1727-
// check that private components do not appear in the generics or predicates of inherent impls
1728-
// this check is intentionally NOT performed for impls of traits, per #90586
1744+
let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev));
1745+
// Generics and predicates of trait impls are intentionally not checked
1746+
// for private components (#90586).
17291747
if impl_.of_trait.is_none() {
1730-
self.check(item.owner_id.def_id, impl_vis, Some(impl_ev))
1731-
.generics()
1732-
.predicates();
1748+
check.generics().predicates();
17331749
}
1750+
// Skip checking private components in associated types, due to lack of full
1751+
// normalization they produce very ridiculous false positives.
1752+
// FIXME: Remove this when full normalization is implemented.
1753+
check.skip_assoc_tys = true;
1754+
check.ty().trait_ref();
1755+
17341756
for impl_item_ref in impl_.items {
17351757
let impl_item_vis = if impl_.of_trait.is_none() {
17361758
min(

tests/ui/privacy/pub-priv-dep/pub-priv1.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,14 @@ pub type Alias = OtherType;
7777

7878
pub struct PublicWithPrivateImpl;
7979

80-
// FIXME: This should trigger.
81-
// See https://github.com/rust-lang/rust/issues/71043
8280
impl OtherTrait for PublicWithPrivateImpl {}
81+
//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
8382

8483
pub trait PubTraitOnPrivate {}
8584

86-
// FIXME: This should trigger.
87-
// See https://github.com/rust-lang/rust/issues/71043
8885
impl PubTraitOnPrivate for OtherType {}
86+
//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface
87+
//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
8988

9089
pub struct AllowedPrivType {
9190
#[allow(exported_private_dependencies)]

tests/ui/privacy/pub-priv-dep/pub-priv1.stderr

+21-1
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,25 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface
7070
LL | pub type Alias = OtherType;
7171
| ^^^^^^^^^^^^^^
7272

73-
error: aborting due to 11 previous errors
73+
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
74+
--> $DIR/pub-priv1.rs:80:1
75+
|
76+
LL | impl OtherTrait for PublicWithPrivateImpl {}
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
78+
79+
error: type `OtherType` from private dependency 'priv_dep' in public interface
80+
--> $DIR/pub-priv1.rs:85:1
81+
|
82+
LL | impl PubTraitOnPrivate for OtherType {}
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84+
85+
error: type `OtherType` from private dependency 'priv_dep' in public interface
86+
--> $DIR/pub-priv1.rs:85:1
87+
|
88+
LL | impl PubTraitOnPrivate for OtherType {}
89+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
|
91+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
92+
93+
error: aborting due to 14 previous errors
7494

0 commit comments

Comments
 (0)