Rollup merge of #138317 - petrochenkov:libsearch3, r=compiler-errors

privacy: Visit types and traits in impls in type privacy lints

With one exception to avoid false positives.

Fixes the same issue as https://github.com/rust-lang/rust/pull/134176.
This commit is contained in:
Matthias Krüger 2025-03-25 18:09:04 +01:00 committed by GitHub
commit 81e227583a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 14 deletions

View file

@ -72,7 +72,9 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
pub trait DefIdVisitor<'tcx> {
type Result: VisitorResult = ();
const SHALLOW: bool = false;
const SKIP_ASSOC_TYS: bool = false;
fn skip_assoc_tys(&self) -> bool {
false
}
fn tcx(&self) -> TyCtxt<'tcx>;
fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
@ -213,7 +215,7 @@ where
}
}
ty::Alias(kind @ (ty::Inherent | ty::Weak | ty::Projection), data) => {
if V::SKIP_ASSOC_TYS {
if self.def_id_visitor.skip_assoc_tys() {
// Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias`
// as visible/reachable even if `Type` is private.
@ -324,7 +326,9 @@ impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
for FindMin<'a, 'tcx, VL, SHALLOW>
{
const SHALLOW: bool = SHALLOW;
const SKIP_ASSOC_TYS: bool = true;
fn skip_assoc_tys(&self) -> bool {
true
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
@ -342,7 +346,7 @@ trait VisibilityLike: Sized {
def_id: LocalDefId,
) -> Self;
// Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
// Returns an over-approximation (`skip_assoc_tys()` = true) of visibility due to
// associated types for which we can't determine visibility precisely.
fn of_impl<const SHALLOW: bool>(
def_id: LocalDefId,
@ -1352,6 +1356,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
required_effective_vis: Option<EffectiveVisibility>,
in_assoc_ty: bool,
in_primary_interface: bool,
skip_assoc_tys: bool,
}
impl SearchInterfaceForPrivateItemsVisitor<'_> {
@ -1398,6 +1403,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
self
}
fn trait_ref(&mut self) -> &mut Self {
self.in_primary_interface = true;
if let Some(trait_ref) = self.tcx.impl_trait_ref(self.item_def_id) {
let _ = self.visit_trait(trait_ref.instantiate_identity());
}
self
}
fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool {
if self.leaks_private_dep(def_id) {
self.tcx.emit_node_span_lint(
@ -1495,6 +1508,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
type Result = ControlFlow<()>;
fn skip_assoc_tys(&self) -> bool {
self.skip_assoc_tys
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
@ -1531,6 +1547,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
required_effective_vis,
in_assoc_ty: false,
in_primary_interface: true,
skip_assoc_tys: false,
}
}
@ -1726,13 +1743,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
self.effective_visibilities,
);
// check that private components do not appear in the generics or predicates of inherent impls
// this check is intentionally NOT performed for impls of traits, per #90586
let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev));
// Generics and predicates of trait impls are intentionally not checked
// for private components (#90586).
if impl_.of_trait.is_none() {
self.check(item.owner_id.def_id, impl_vis, Some(impl_ev))
.generics()
.predicates();
check.generics().predicates();
}
// Skip checking private components in associated types, due to lack of full
// normalization they produce very ridiculous false positives.
// FIXME: Remove this when full normalization is implemented.
check.skip_assoc_tys = true;
check.ty().trait_ref();
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
min(

View file

@ -77,15 +77,14 @@ pub type Alias = OtherType;
pub struct PublicWithPrivateImpl;
// FIXME: This should trigger.
// See https://github.com/rust-lang/rust/issues/71043
impl OtherTrait for PublicWithPrivateImpl {}
//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
pub trait PubTraitOnPrivate {}
// FIXME: This should trigger.
// See https://github.com/rust-lang/rust/issues/71043
impl PubTraitOnPrivate for OtherType {}
//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface
//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface
pub struct AllowedPrivType {
#[allow(exported_private_dependencies)]

View file

@ -70,5 +70,25 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface
LL | pub type Alias = OtherType;
| ^^^^^^^^^^^^^^
error: aborting due to 11 previous errors
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:80:1
|
LL | impl OtherTrait for PublicWithPrivateImpl {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: type `OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:85:1
|
LL | impl PubTraitOnPrivate for OtherType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: type `OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:85:1
|
LL | impl PubTraitOnPrivate for OtherType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 14 previous errors