diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f617..c9b361a8a3504 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1351,6 +1351,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> { required_effective_vis: Option, in_assoc_ty: bool, in_primary_interface: bool, + check_private_dep_leaks_only: bool, } impl SearchInterfaceForPrivateItemsVisitor<'_> { @@ -1411,6 +1412,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { ); } + if self.check_private_dep_leaks_only { + return false; + } + let Some(local_def_id) = def_id.as_local() else { return false; }; @@ -1530,6 +1535,23 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { required_effective_vis, in_assoc_ty: false, in_primary_interface: true, + check_private_dep_leaks_only: false, + } + } + + fn check_private_dep_leaks_only( + &self, + def_id: LocalDefId, + required_visibility: ty::Visibility, + ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> { + SearchInterfaceForPrivateItemsVisitor { + tcx: self.tcx, + item_def_id: def_id, + required_visibility, + required_effective_vis: None, + in_assoc_ty: false, + in_primary_interface: true, + check_private_dep_leaks_only: true, } } @@ -1732,6 +1754,14 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { .generics() .predicates(); } + + // normally, a public item can implement a private trait, but this should be linted for leakages of + // private dependencies. + if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id.def_id) { + self.check_private_dep_leaks_only(item.owner_id.def_id, impl_vis) + .visit_trait(trait_ref.instantiate_identity()); + } + for impl_item_ref in impl_.items { let impl_item_vis = if impl_.of_trait.is_none() { min( diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index 112eaf528be27..06e4f12924485 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -7,6 +7,7 @@ // dependency or a private one. #![deny(exported_private_dependencies)] +#![allow(hidden_glob_reexports)] // This crate is a private dependency // FIXME: This should trigger. @@ -77,15 +78,13 @@ 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 pub struct AllowedPrivType { #[allow(exported_private_dependencies)] @@ -103,5 +102,7 @@ pub use pm::pm_attr; // FIXME: This should trigger. pub use priv_dep::E::V1; +// FIXME: This should trigger. +pub use priv_dep::*; fn main() {} diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr index 53d461a5774a0..87c845e52ef1c 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,5 +1,5 @@ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:29:5 + --> $DIR/pub-priv1.rs:30:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ @@ -11,64 +11,76 @@ LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:36:5 + --> $DIR/pub-priv1.rs:37:5 | LL | pub fn pub_fn_param(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:39:5 + --> $DIR/pub-priv1.rs:40:5 | LL | pub fn pub_fn_return() -> OtherType { OtherType } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:46:5 + --> $DIR/pub-priv1.rs:47:5 | LL | type Foo: OtherTrait; | ^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:50:1 + --> $DIR/pub-priv1.rs:51:1 | LL | pub trait WithSuperTrait: OtherTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:59:5 + --> $DIR/pub-priv1.rs:60:5 | LL | type X = OtherType; | ^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:63:1 + --> $DIR/pub-priv1.rs:64:1 | LL | pub fn in_bounds(x: T) { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:66:1 + --> $DIR/pub-priv1.rs:67:1 | LL | pub fn private_in_generic() -> std::num::Saturating { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:69:1 + --> $DIR/pub-priv1.rs:70:1 | LL | pub static STATIC: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:72:1 + --> $DIR/pub-priv1.rs:73:1 | LL | pub const CONST: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:75:1 + --> $DIR/pub-priv1.rs:76:1 | 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:81:1 + | +LL | impl OtherTrait for PublicWithPrivateImpl {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:86:1 + | +LL | impl PubTraitOnPrivate for OtherType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 13 previous errors