Skip to content

Commit 5d84a47

Browse files
committed
fix(doc): respect public-dependency when documenting deps
1 parent ee72901 commit 5d84a47

2 files changed

Lines changed: 42 additions & 39 deletions

File tree

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,16 @@ fn compute_deps_doc(
637637
// built. If we're documenting *all* libraries, then we also depend on
638638
// the documentation of the library being built.
639639
let mut ret = Vec::new();
640+
let is_root = state.ws.is_member(&unit.pkg);
641+
642+
// Check if public-dependency feature is enabled
643+
let public_deps_enabled = state.gctx.cli_unstable().public_dependency
644+
|| unit
645+
.pkg
646+
.manifest()
647+
.unstable_features()
648+
.is_enabled(Feature::public_dependency());
649+
640650
for (id, deps) in state.deps(unit, unit_for) {
641651
let Some(dep_lib) = calc_artifact_deps(unit, unit_for, id, &deps, state, &mut ret)? else {
642652
continue;
@@ -657,7 +667,20 @@ fn compute_deps_doc(
657667
IS_NO_ARTIFACT_DEP,
658668
)?;
659669
ret.push(lib_unit_dep);
660-
if dep_lib.documented() && state.intent.wants_deps_docs() {
670+
671+
// Decide whether to document this dependency.
672+
// When public-dependency is enabled, only document:
673+
// - Direct dependencies of workspace members
674+
// - Public dependencies (recursively)
675+
// This dramatically speeds up documentation builds by excluding indirect
676+
// private dependencies that cannot be used by readers of the docs.
677+
let should_doc_dep = if public_deps_enabled && !is_root {
678+
state.resolve().is_public_dep(unit.pkg.package_id(), id)
679+
} else {
680+
true
681+
};
682+
683+
if dep_lib.documented() && state.intent.wants_deps_docs() && should_doc_dep {
661684
// Document this lib as well.
662685
let doc_unit_dep = new_unit_dep(
663686
state,

tests/testsuite/doc.rs

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4032,14 +4032,11 @@ fn mergeable_info_dep_collision() {
40324032

40334033
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
40344034
fn doc_with_public_dependency_transitive() {
4035-
// Tests recursive public dependency documentation with 2 layers.
4035+
// Tests recursive public dependency documentation with 2 layers
40364036
// foo -> bar (direct) -> baz (public) -> qux (public)
4037-
//
4038-
// Before the fix: all transitive deps are documented regardless of
4039-
// public/private markers, so foo, bar, baz, and qux all get docs.
4040-
// After the fix: only direct deps and their public deps recursively
4041-
// are documented, so the same set applies here since the whole chain
4042-
// is public.
4037+
// foo and bar should be documented (direct deps)
4038+
// baz should be documented (public dep of direct dep bar)
4039+
// qux should be documented (public dep of public dep baz)
40434040

40444041
Package::new("qux", "0.0.1")
40454042
.file("src/lib.rs", "pub fn qux() {}")
@@ -4100,8 +4097,6 @@ fn doc_with_public_dependency_transitive() {
41004097
)
41014098
.run();
41024099

4103-
// All four are documented: the whole chain is public so behavior is
4104-
// the same before and after the fix.
41054100
assert!(p.root().join("target/doc/foo/index.html").is_file());
41064101
assert!(p.root().join("target/doc/bar/index.html").is_file());
41074102
assert!(p.root().join("target/doc/baz/index.html").is_file());
@@ -4110,12 +4105,9 @@ fn doc_with_public_dependency_transitive() {
41104105

41114106
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
41124107
fn doc_direct_deps_always_documented() {
4113-
// Direct dependencies should always be documented regardless of the
4114-
// public flag on them.
4115-
// foo -> bar (public = true), baz (public = false)
4116-
//
4117-
// Both bar and baz are direct deps of foo, so both get documented
4118-
// both before and after the fix.
4108+
// Direct dependencies should always be documented regardless of public flag
4109+
// foo -> bar (public=true), baz (public=false)
4110+
// Both bar and baz should be documented since they are direct deps
41194111

41204112
Package::new("bar", "0.0.1")
41214113
.file("src/lib.rs", "pub fn bar() {}")
@@ -4166,20 +4158,16 @@ fn doc_direct_deps_always_documented() {
41664158
)
41674159
.run();
41684160

4169-
// Both direct deps are documented regardless of their public flag.
4161+
// Both direct deps should be documented
41704162
assert!(p.root().join("target/doc/foo/index.html").is_file());
41714163
assert!(p.root().join("target/doc/bar/index.html").is_file());
41724164
assert!(p.root().join("target/doc/baz/index.html").is_file());
41734165
}
41744166

41754167
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
41764168
fn doc_with_private_dependency() {
4177-
// foo -> bar (direct) -> baz (private dep of bar)
4178-
//
4179-
// Before the fix: baz is documented because cargo docs all transitive
4180-
// deps unconditionally, even when -Zpublic-dependency is active.
4181-
// After the fix: baz is NOT documented because it is a private
4182-
// transitive dep that callers of foo cannot use.
4169+
// foo -> bar (any) -> baz (private)
4170+
// Only foo and bar documented, not baz (transitive private dep)
41834171

41844172
Package::new("baz", "0.0.1")
41854173
.file("src/lib.rs", "pub fn baz() {}")
@@ -4196,7 +4184,7 @@ fn doc_with_private_dependency() {
41964184
"Cargo.toml",
41974185
r#"
41984186
cargo-features = ["public-dependency"]
4199-
4187+
42004188
[package]
42014189
name = "foo"
42024190
version = "0.0.1"
@@ -4218,7 +4206,6 @@ fn doc_with_private_dependency() {
42184206
[DOWNLOADING] crates ...
42194207
[DOWNLOADED] baz v0.0.1 (registry `dummy-registry`)
42204208
[DOWNLOADED] bar v0.0.1 (registry `dummy-registry`)
4221-
[DOCUMENTING] baz v0.0.1
42224209
[CHECKING] baz v0.0.1
42234210
[DOCUMENTING] bar v0.0.1
42244211
[CHECKING] bar v0.0.1
@@ -4233,19 +4220,12 @@ fn doc_with_private_dependency() {
42334220

42344221
assert!(p.root().join("target/doc/foo/index.html").is_file());
42354222
assert!(p.root().join("target/doc/bar/index.html").is_file());
4236-
// Before the fix baz is documented even though it is a private dep.
4237-
assert!(p.root().join("target/doc/baz/index.html").is_file());
4223+
assert!(!p.root().join("target/doc/baz/index.html").is_file());
42384224
}
42394225

42404226
#[cargo_test(nightly, reason = "public-dependency feature is unstable")]
42414227
fn doc_mixed_public_private_deps() {
4242-
// foo -> pub_dep (public), priv_dep (private), priv_dep_with_dep (default)
4243-
// priv_dep_with_dep -> transitive
4244-
//
4245-
// Before the fix: transitive is documented because cargo docs every
4246-
// reachable dep regardless of public/private markers.
4247-
// After the fix: transitive is NOT documented because it is only
4248-
// reachable through a private dependency chain.
4228+
// Tests mixed public and private dependencies
42494229

42504230
Package::new("pub_dep", "0.0.1")
42514231
.file("src/lib.rs", "pub fn pub_dep() {}")
@@ -4269,7 +4249,7 @@ fn doc_mixed_public_private_deps() {
42694249
"Cargo.toml",
42704250
r#"
42714251
cargo-features = ["public-dependency"]
4272-
4252+
42734253
[package]
42744254
name = "foo"
42754255
version = "0.0.1"
@@ -4288,7 +4268,7 @@ fn doc_mixed_public_private_deps() {
42884268
.masquerade_as_nightly_cargo(&["public-dependency"])
42894269
.run();
42904270

4291-
// All direct deps are documented.
4271+
// Direct deps documented, transitive private deps not documented
42924272
assert!(p.root().join("target/doc/foo/index.html").is_file());
42934273
assert!(p.root().join("target/doc/pub_dep/index.html").is_file());
42944274
assert!(p.root().join("target/doc/priv_dep/index.html").is_file());
@@ -4297,7 +4277,7 @@ fn doc_mixed_public_private_deps() {
42974277
.join("target/doc/priv_dep_with_dep/index.html")
42984278
.is_file()
42994279
);
4300-
// Before the fix transitive is also documented even though it is an
4301-
// indirect private dep.
4302-
assert!(p.root().join("target/doc/transitive/index.html").is_file());
4280+
4281+
// transitive should NOT be documented
4282+
assert!(!p.root().join("target/doc/transitive/index.html").is_file());
43034283
}

0 commit comments

Comments
 (0)