Skip to content

Commit 7c20eb2

Browse files
committed
fix(doc): Respect public-dependency when documenting deps
1 parent 41f0a4d commit 7c20eb2

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ struct State<'a, 'gctx> {
6767
/// dependency from a to b was added purely because it was a dev-dependency.
6868
/// This is used during `connect_run_custom_build_deps`.
6969
dev_dependency_edges: HashSet<(Unit, Unit)>,
70+
71+
/// Package IDs of the root units (i.e. the packages the user asked to
72+
/// compile). Used when deciding whether to document a dependency: roots
73+
/// always get all their direct deps documented, while non-roots only
74+
/// get public deps documented when `-Zpublic-dependency` is active.
75+
root_pkg_ids: HashSet<PackageId>,
7076
}
7177

7278
/// A boolean-like to indicate if a `Unit` is an artifact or not.
@@ -126,6 +132,7 @@ pub fn build_unit_dependencies<'a, 'gctx>(
126132
interner,
127133
scrape_units,
128134
dev_dependency_edges: HashSet::new(),
135+
root_pkg_ids: roots.iter().map(|u| u.pkg.package_id()).collect(),
129136
};
130137

131138
let std_unit_deps = calc_deps_of_std(&mut state, std_roots)?;
@@ -637,6 +644,19 @@ fn compute_deps_doc(
637644
// built. If we're documenting *all* libraries, then we also depend on
638645
// the documentation of the library being built.
639646
let mut ret = Vec::new();
647+
648+
let public_deps_enabled = state.gctx.cli_unstable().public_dependency
649+
|| unit
650+
.pkg
651+
.manifest()
652+
.unstable_features()
653+
.is_enabled(Feature::public_dependency());
654+
655+
// Whether this package is a root of the compilation (i.e. selected by
656+
// the user). Roots always have all their direct deps documented,
657+
// regardless of public/private status.
658+
let is_root = state.root_pkg_ids.contains(&unit.pkg.package_id());
659+
640660
for (id, deps) in state.deps(unit, unit_for) {
641661
let Some(dep_lib) = calc_artifact_deps(unit, unit_for, id, &deps, state, &mut ret)? else {
642662
continue;
@@ -657,7 +677,17 @@ fn compute_deps_doc(
657677
IS_NO_ARTIFACT_DEP,
658678
)?;
659679
ret.push(lib_unit_dep);
660-
if dep_lib.documented() && state.intent.wants_deps_docs() {
680+
681+
// Decide whether to document this dependency. When
682+
// public-dependency is enabled, only document direct deps of root
683+
// packages and public deps (recursively).
684+
let should_doc_dep = if is_root || !public_deps_enabled {
685+
true
686+
} else {
687+
state.resolve().is_public_dep(unit.pkg.package_id(), id)
688+
};
689+
690+
if dep_lib.documented() && state.intent.wants_deps_docs() && should_doc_dep {
661691
// Document this lib as well.
662692
let doc_unit_dep = new_unit_dep(
663693
state,

tests/testsuite/doc.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4180,6 +4180,7 @@ fn doc_direct_deps_always_documented() {
41804180
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
41814181
fn doc_with_transitive_private_dependency() {
41824182
// foo -> bar (direct dep) -> baz (private dep of bar, transitive to foo)
4183+
// baz should NOT be documented because it is a private transitive dep.
41834184

41844185
Package::new("baz", "0.0.1")
41854186
.file("src/lib.rs", "pub fn baz() {}")
@@ -4218,7 +4219,6 @@ fn doc_with_transitive_private_dependency() {
42184219
[DOWNLOADING] crates ...
42194220
[DOWNLOADED] baz v0.0.1 (registry `dummy-registry`)
42204221
[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
4221-
[DOCUMENTING] baz v0.0.1
42224222
[CHECKING] baz v0.0.1
42234223
[DOCUMENTING] bar v0.0.1
42244224
[CHECKING] bar v0.0.1
@@ -4233,7 +4233,7 @@ fn doc_with_transitive_private_dependency() {
42334233

42344234
assert!(p.root().join("target/doc/foo/index.html").is_file());
42354235
assert!(p.root().join("target/doc/bar/index.html").is_file());
4236-
assert!(p.root().join("target/doc/baz/index.html").is_file());
4236+
assert!(!p.root().join("target/doc/baz/index.html").is_file());
42374237
}
42384238

42394239
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
@@ -4290,17 +4290,19 @@ fn doc_mixed_public_private_deps() {
42904290
.join("target/doc/priv_dep_with_dep/index.html")
42914291
.is_file()
42924292
);
4293-
assert!(p.root().join("target/doc/transitive/index.html").is_file());
4293+
assert!(!p.root().join("target/doc/transitive/index.html").is_file());
42944294
}
42954295

42964296
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
42974297
fn doc_workspace_member_private_dep() {
42984298
// selected and skipped are both workspace members.
42994299
// selected has a private dep on skipped.
43004300
// skipped has a dep on transitive (a registry crate).
4301-
// Running `cargo doc -p selected` currently documents all of them,
4302-
// including transitive, because the public-dependency filter treats
4303-
// workspace members the same as roots.
4301+
//
4302+
// Running `cargo doc -p selected`, selected is the root so all its
4303+
// direct deps (skipped) are documented. But skipped is not a root,
4304+
// so the public-dependency filter applies: transitive is not marked
4305+
// public by skipped, so it should not be documented.
43044306

43054307
Package::new("transitive", "0.0.1")
43064308
.file("src/lib.rs", "pub fn transitive() {}")
@@ -4350,6 +4352,7 @@ fn doc_workspace_member_private_dep() {
43504352

43514353
assert!(p.root().join("target/doc/selected/index.html").is_file());
43524354
assert!(p.root().join("target/doc/skipped/index.html").is_file());
4353-
// transitive is documented under the current behavior
4354-
assert!(p.root().join("target/doc/transitive/index.html").is_file());
4355+
// transitive is not documented: skipped is not a root, so the
4356+
// public-dependency filter kicks in and transitive is not public
4357+
assert!(!p.root().join("target/doc/transitive/index.html").is_file());
43554358
}

0 commit comments

Comments
 (0)