Skip to content

Commit 6e8f9dd

Browse files
committed
fix: Implement missing logics in exported_private_dependencies lint
1 parent ad27045 commit 6e8f9dd

File tree

4 files changed

+138
-27
lines changed

4 files changed

+138
-27
lines changed

compiler/rustc_privacy/src/lib.rs

+57
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
13511351
required_effective_vis: Option<EffectiveVisibility>,
13521352
in_assoc_ty: bool,
13531353
in_primary_interface: bool,
1354+
check_private_dep_leaks_only: bool,
13541355
}
13551356

13561357
impl SearchInterfaceForPrivateItemsVisitor<'_> {
@@ -1411,6 +1412,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
14111412
);
14121413
}
14131414

1415+
if self.check_private_dep_leaks_only {
1416+
return false;
1417+
}
1418+
14141419
let Some(local_def_id) = def_id.as_local() else {
14151420
return false;
14161421
};
@@ -1530,6 +1535,23 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
15301535
required_effective_vis,
15311536
in_assoc_ty: false,
15321537
in_primary_interface: true,
1538+
check_private_dep_leaks_only: false,
1539+
}
1540+
}
1541+
1542+
fn check_private_dep_leaks_only(
1543+
&self,
1544+
def_id: LocalDefId,
1545+
required_visibility: ty::Visibility,
1546+
) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
1547+
SearchInterfaceForPrivateItemsVisitor {
1548+
tcx: self.tcx,
1549+
item_def_id: def_id,
1550+
required_visibility,
1551+
required_effective_vis: None,
1552+
in_assoc_ty: false,
1553+
in_primary_interface: true,
1554+
check_private_dep_leaks_only: true,
15331555
}
15341556
}
15351557

@@ -1732,6 +1754,14 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
17321754
.generics()
17331755
.predicates();
17341756
}
1757+
1758+
// normally, a public item can implement a private trait, but this should be linted for leakages of
1759+
// private dependencies.
1760+
if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id.def_id) {
1761+
self.check_private_dep_leaks_only(item.owner_id.def_id, impl_vis)
1762+
.visit_trait(trait_ref.instantiate_identity());
1763+
}
1764+
17351765
for impl_item_ref in impl_.items {
17361766
let impl_item_vis = if impl_.of_trait.is_none() {
17371767
min(
@@ -1759,6 +1789,33 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
17591789
}
17601790
}
17611791
}
1792+
DefKind::Use => {
1793+
let item = tcx.hir_item(id);
1794+
if let hir::ItemKind::Use(path, use_kind) = item.kind
1795+
// List imports are desugared as single ones so skip `ListStem`s
1796+
&& use_kind != rustc_hir::UseKind::ListStem
1797+
{
1798+
if let Some(def_id) = path.res.iter().filter_map(Res::opt_def_id).last() {
1799+
// normally, public items in a private modules can be re-exported but this should be linted for
1800+
// leakages of a private dependencies
1801+
self.check_private_dep_leaks_only(item.owner_id.def_id, item_visibility)
1802+
.check_def_id(
1803+
def_id,
1804+
item.kind.descr(),
1805+
&LazyDefPathStr { def_id, tcx },
1806+
);
1807+
}
1808+
}
1809+
}
1810+
DefKind::ExternCrate => {
1811+
let item = tcx.hir_item(id);
1812+
if let Some(cnum) = tcx.extern_mod_stmt_cnum(item.owner_id.def_id) {
1813+
let def_id = cnum.as_def_id();
1814+
// `pub extern some_dep` should be linted if and only if `some_dep` is a private dependency
1815+
self.check_private_dep_leaks_only(item.owner_id.def_id, item_visibility)
1816+
.visit_def_id(def_id, item.kind.descr(), &LazyDefPathStr { def_id, tcx });
1817+
}
1818+
}
17621819
_ => {}
17631820
}
17641821
}

library/std/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ hashbrown = { version = "0.15", default-features = false, features = [
2525
] }
2626
std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = [
2727
'rustc-dep-of-std',
28-
] }
28+
], public = true }
2929

3030
# Dependencies of the `backtrace` crate
3131
rustc-demangle = { version = "0.1.24", features = ['rustc-dep-of-std'] }

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

+11-11
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
// dependency or a private one.
88

99
#![deny(exported_private_dependencies)]
10+
#![allow(hidden_glob_reexports)]
1011

1112
// This crate is a private dependency
12-
// FIXME: This should trigger.
1313
pub extern crate priv_dep;
14+
//~^ ERROR extern crate `priv_dep` from private dependency 'priv_dep' in public interface
1415
// This crate is a public dependency
1516
extern crate pub_dep;
1617
// This crate is a private dependency
@@ -77,31 +78,30 @@ pub type Alias = OtherType;
7778

7879
pub struct PublicWithPrivateImpl;
7980

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

8484
pub trait PubTraitOnPrivate {}
8585

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

9089
pub struct AllowedPrivType {
9190
#[allow(exported_private_dependencies)]
9291
pub allowed: OtherType,
9392
}
9493

95-
// FIXME: This should trigger.
9694
pub use priv_dep::m;
97-
// FIXME: This should trigger.
95+
//~^ ERROR `use` import `m` from private dependency 'priv_dep' in public interface
9896
pub use pm::fn_like;
99-
// FIXME: This should trigger.
97+
//~^ ERROR `use` import `fn_like` from private dependency 'pm' in public interface
10098
pub use pm::PmDerive;
101-
// FIXME: This should trigger.
99+
//~^ ERROR `use` import `PmDerive` from private dependency 'pm' in public interface
102100
pub use pm::pm_attr;
103-
104-
// FIXME: This should trigger.
101+
//~^ ERROR `use` import `pm_attr` from private dependency 'pm' in public interface
105102
pub use priv_dep::E::V1;
103+
//~^ ERROR `use` import `V1` from private dependency 'priv_dep' in public interface
104+
pub use priv_dep::*;
105+
//~^ ERROR `use` import `priv_dep` from private dependency 'priv_dep' in public interface
106106

107107
fn main() {}
+69-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: type `OtherType` from private dependency 'priv_dep' in public interface
2-
--> $DIR/pub-priv1.rs:29:5
1+
error: extern crate `priv_dep` from private dependency 'priv_dep' in public interface
2+
--> $DIR/pub-priv1.rs:13:1
33
|
4-
LL | pub field: OtherType,
5-
| ^^^^^^^^^^^^^^^^^^^^
4+
LL | pub extern crate priv_dep;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: the lint level is defined here
88
--> $DIR/pub-priv1.rs:9:9
@@ -11,64 +11,118 @@ LL | #![deny(exported_private_dependencies)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: type `OtherType` from private dependency 'priv_dep' in public interface
14-
--> $DIR/pub-priv1.rs:36:5
14+
--> $DIR/pub-priv1.rs:30:5
15+
|
16+
LL | pub field: OtherType,
17+
| ^^^^^^^^^^^^^^^^^^^^
18+
19+
error: type `OtherType` from private dependency 'priv_dep' in public interface
20+
--> $DIR/pub-priv1.rs:37:5
1521
|
1622
LL | pub fn pub_fn_param(param: OtherType) {}
1723
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1824

1925
error: type `OtherType` from private dependency 'priv_dep' in public interface
20-
--> $DIR/pub-priv1.rs:39:5
26+
--> $DIR/pub-priv1.rs:40:5
2127
|
2228
LL | pub fn pub_fn_return() -> OtherType { OtherType }
2329
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2430

2531
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
26-
--> $DIR/pub-priv1.rs:46:5
32+
--> $DIR/pub-priv1.rs:47:5
2733
|
2834
LL | type Foo: OtherTrait;
2935
| ^^^^^^^^^^^^^^^^^^^^
3036

3137
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
32-
--> $DIR/pub-priv1.rs:50:1
38+
--> $DIR/pub-priv1.rs:51:1
3339
|
3440
LL | pub trait WithSuperTrait: OtherTrait {}
3541
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3642

3743
error: type `OtherType` from private dependency 'priv_dep' in public interface
38-
--> $DIR/pub-priv1.rs:59:5
44+
--> $DIR/pub-priv1.rs:60:5
3945
|
4046
LL | type X = OtherType;
4147
| ^^^^^^
4248

4349
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
44-
--> $DIR/pub-priv1.rs:63:1
50+
--> $DIR/pub-priv1.rs:64:1
4551
|
4652
LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() }
4753
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4854

4955
error: type `OtherType` from private dependency 'priv_dep' in public interface
50-
--> $DIR/pub-priv1.rs:66:1
56+
--> $DIR/pub-priv1.rs:67:1
5157
|
5258
LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() }
5359
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5460

5561
error: type `OtherType` from private dependency 'priv_dep' in public interface
56-
--> $DIR/pub-priv1.rs:69:1
62+
--> $DIR/pub-priv1.rs:70:1
5763
|
5864
LL | pub static STATIC: OtherType = OtherType;
5965
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6066

6167
error: type `OtherType` from private dependency 'priv_dep' in public interface
62-
--> $DIR/pub-priv1.rs:72:1
68+
--> $DIR/pub-priv1.rs:73:1
6369
|
6470
LL | pub const CONST: OtherType = OtherType;
6571
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
6672

6773
error: type `OtherType` from private dependency 'priv_dep' in public interface
68-
--> $DIR/pub-priv1.rs:75:1
74+
--> $DIR/pub-priv1.rs:76:1
6975
|
7076
LL | pub type Alias = OtherType;
7177
| ^^^^^^^^^^^^^^
7278

73-
error: aborting due to 11 previous errors
79+
error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
80+
--> $DIR/pub-priv1.rs:81:1
81+
|
82+
LL | impl OtherTrait for PublicWithPrivateImpl {}
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84+
85+
error: type `OtherType` from private dependency 'priv_dep' in public interface
86+
--> $DIR/pub-priv1.rs:86:1
87+
|
88+
LL | impl PubTraitOnPrivate for OtherType {}
89+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
91+
error: `use` import `m` from private dependency 'priv_dep' in public interface
92+
--> $DIR/pub-priv1.rs:94:9
93+
|
94+
LL | pub use priv_dep::m;
95+
| ^^^^^^^^^^^
96+
97+
error: `use` import `fn_like` from private dependency 'pm' in public interface
98+
--> $DIR/pub-priv1.rs:96:9
99+
|
100+
LL | pub use pm::fn_like;
101+
| ^^^^^^^^^^^
102+
103+
error: `use` import `PmDerive` from private dependency 'pm' in public interface
104+
--> $DIR/pub-priv1.rs:98:9
105+
|
106+
LL | pub use pm::PmDerive;
107+
| ^^^^^^^^^^^^
108+
109+
error: `use` import `pm_attr` from private dependency 'pm' in public interface
110+
--> $DIR/pub-priv1.rs:100:9
111+
|
112+
LL | pub use pm::pm_attr;
113+
| ^^^^^^^^^^^
114+
115+
error: `use` import `V1` from private dependency 'priv_dep' in public interface
116+
--> $DIR/pub-priv1.rs:102:9
117+
|
118+
LL | pub use priv_dep::E::V1;
119+
| ^^^^^^^^^^^^^^^
120+
121+
error: `use` import `priv_dep` from private dependency 'priv_dep' in public interface
122+
--> $DIR/pub-priv1.rs:104:9
123+
|
124+
LL | pub use priv_dep::*;
125+
| ^^^^^^^^
126+
127+
error: aborting due to 20 previous errors
74128

0 commit comments

Comments
 (0)