Skip to content

Commit f81f3dc

Browse files
committed
If the parent dependency is private, treat dependents as private
Currently, marking a dependency private does not automatically make all its child dependencies private. Resolve this by making its children private by default as well. This also resolves some FIXMEs for tests that are intended to fail but previously passed. [1]: rust-lang#135501 (comment)
1 parent 1363c61 commit f81f3dc

File tree

5 files changed

+52
-8
lines changed

5 files changed

+52
-8
lines changed

compiler/rustc_metadata/src/creader.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,10 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
163163
enum CrateOrigin<'a> {
164164
/// This crate was a dependency of another crate.
165165
Dependency {
166+
/// Where this dependency was included from.
166167
dep_root: &'a CratePaths,
168+
/// True if the parent is private, meaning the dependent should also be private.
169+
parent_private: bool,
167170
/// Dependency info about this crate.
168171
dep: &'a CrateDep,
169172
},
@@ -193,6 +196,17 @@ impl<'a> CrateOrigin<'a> {
193196
_ => None,
194197
}
195198
}
199+
200+
/// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the
201+
/// dependency is not private, `None` if it could not be determined.
202+
fn private_dep(&self) -> Option<bool> {
203+
match self {
204+
CrateOrigin::Dependency { parent_private, dep, .. } => {
205+
Some(dep.is_private || *parent_private)
206+
}
207+
_ => None,
208+
}
209+
}
196210
}
197211

198212
impl CStore {
@@ -497,7 +511,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
497511
&crate_paths
498512
};
499513

500-
let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
514+
let cnum_map =
515+
self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind, private_dep)?;
501516

502517
let raw_proc_macros = if crate_root.is_proc_macro_crate() {
503518
let temp_root;
@@ -638,7 +653,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
638653
let host_hash = dep.map(|d| d.host_hash).flatten();
639654
let extra_filename = dep.map(|d| &d.extra_filename[..]);
640655
let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
641-
let private_dep = dep.map(|d| d.is_private);
656+
let private_dep = origin.private_dep();
642657

643658
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
644659
(LoadResult::Previous(cnum), None)
@@ -735,6 +750,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
735750
metadata: &MetadataBlob,
736751
krate: CrateNum,
737752
dep_kind: CrateDepKind,
753+
parent_is_private: bool,
738754
) -> Result<CrateNumMap, CrateError> {
739755
debug!(
740756
"resolving deps of external crate `{}` with dep root `{}`",
@@ -753,18 +769,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
753769
crate_num_map.push(krate);
754770
for dep in deps {
755771
info!(
756-
"resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`",
772+
"resolving dep `{}`->`{}` hash: `{}` extra filename: `{}` private {}",
757773
crate_root.name(),
758774
dep.name,
759775
dep.hash,
760-
dep.extra_filename
776+
dep.extra_filename,
777+
dep.is_private,
761778
);
762779
let dep_kind = match dep_kind {
763780
CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
764781
_ => dep.kind,
765782
};
766783
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, CrateOrigin::Dependency {
767784
dep_root,
785+
parent_private: parent_is_private,
768786
dep: &dep,
769787
})?;
770788
crate_num_map.push(cnum);
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//@ aux-crate:priv:reexport=reexport.rs
22
//@ compile-flags: -Zunstable-options
3-
//@ check-pass
43

54
// Checks the behavior of a reexported item from a private dependency.
65

@@ -9,7 +8,7 @@
98

109
extern crate reexport;
1110

12-
// FIXME: This should trigger.
1311
pub fn leaks_priv() -> reexport::Shared {
12+
//~^ ERROR type `Shared` from private dependency 'shared' in public interface
1413
reexport::Shared
1514
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: type `Shared` from private dependency 'shared' in public interface
2+
--> $DIR/reexport_from_priv.rs:11:1
3+
|
4+
LL | pub fn leaks_priv() -> reexport::Shared {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/reexport_from_priv.rs:7:9
9+
|
10+
LL | #![deny(exported_private_dependencies)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//@ aux-crate:priv:shared=shared.rs
22
//@ aux-crate:priv:indirect1=indirect1.rs
33
//@ compile-flags: -Zunstable-options
4-
//@ check-pass
54

65
// A shared dependency, where it is only indirectly public.
76
//
@@ -23,7 +22,7 @@
2322
extern crate shared;
2423
extern crate indirect1;
2524

26-
// FIXME: This should trigger.
2725
pub fn leaks_priv() -> shared::Shared {
26+
//~^ ERROR type `Shared` from private dependency 'shared' in public interface
2827
shared::Shared
2928
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: type `Shared` from private dependency 'shared' in public interface
2+
--> $DIR/shared_indirect.rs:25:1
3+
|
4+
LL | pub fn leaks_priv() -> shared::Shared {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/shared_indirect.rs:20:9
9+
|
10+
LL | #![deny(exported_private_dependencies)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

0 commit comments

Comments
 (0)