From ac87f85a9bfe1816fa5d4e805d8182a12d61d047 Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Fri, 8 May 2026 04:16:25 -0400 Subject: [PATCH 1/3] test: snapshot public-dependency fingerprint bug --- tests/testsuite/pub_priv.rs | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/testsuite/pub_priv.rs b/tests/testsuite/pub_priv.rs index 28418b221a9..998915eda83 100644 --- a/tests/testsuite/pub_priv.rs +++ b/tests/testsuite/pub_priv.rs @@ -686,6 +686,69 @@ src/lib.rs:6:13: [WARNING] type `FromPriv` from private dependency 'priv_dep' in .run(); } +// Regression test for https://github.com/rust-lang/cargo/issues/16962. +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn z_public_dependency_invalidates_fingerprint() { + Package::new("dep", "0.1.0") + .file("src/lib.rs", "pub struct FromDep;") + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + + [dependencies] + dep = "0.1.0" + "#, + ) + .file( + "src/lib.rs", + " + extern crate dep; + pub fn use_dep(_: dep::FromDep) {} + ", + ) + .build(); + + p.cargo("check -Zpublic-dependency --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr_data(str![[r#" +... +src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in public interface +... +"#]]) + .run(); + + p.cargo("check --message-format=short") + .with_stderr_data(str![[r#" +src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in public interface +[WARNING] `foo` (lib) generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + + p.cargo("clean").run(); + + p.cargo("check --message-format=short") + .with_stderr_data(str![[r#" +... +"#]]) + .run(); + + p.cargo("check -Zpublic-dependency --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + #[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] fn manifest_location() { Package::new("dep", "0.1.0") From e3898ec4018d69815f46849ee004497e35ef2f5d Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Sat, 9 May 2026 11:30:23 -0400 Subject: [PATCH 2/3] refactor: extract public-dependency check --- src/cargo/core/compiler/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 5529652b6cc..172954a1089 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1887,6 +1887,15 @@ pub fn lib_search_paths( Ok(lib_search_paths) } +fn is_public_dependency_enabled(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> bool { + unit.pkg + .manifest() + .unstable_features() + .require(Feature::public_dependency()) + .is_ok() + || build_runner.bcx.gctx.cli_unstable().public_dependency +} + /// Generates a list of `--extern` arguments. pub fn extern_args( build_runner: &BuildRunner<'_, '_>, @@ -1897,6 +1906,7 @@ pub fn extern_args( let deps = build_runner.unit_deps(unit); let no_embed_metadata = build_runner.bcx.gctx.cli_unstable().no_embed_metadata; + let public_dependency_enabled = is_public_dependency_enabled(build_runner, unit); // Closure to add one dependency to `result`. let mut link_to = |dep: &UnitDep, @@ -1906,14 +1916,7 @@ pub fn extern_args( -> CargoResult<()> { let mut value = OsString::new(); let mut opts = Vec::new(); - let is_public_dependency_enabled = unit - .pkg - .manifest() - .unstable_features() - .require(Feature::public_dependency()) - .is_ok() - || build_runner.bcx.gctx.cli_unstable().public_dependency; - if !dep.public && unit.target.is_lib() && is_public_dependency_enabled { + if !dep.public && unit.target.is_lib() && public_dependency_enabled { opts.push("priv"); *unstable_opts = true; } From 01a7bd605faf2f2f7e3a979a4f3d4c14e855aa88 Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Sat, 9 May 2026 11:31:58 -0400 Subject: [PATCH 3/3] fix(fingerprint): rebuild when -Zpublic-dependency changes --- src/cargo/core/compiler/fingerprint/mod.rs | 7 +++++++ tests/testsuite/pub_priv.rs | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 2b803c45e48..fa7c1ad9846 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -88,6 +88,7 @@ //! `is_std` | | ✓ | ✓ //! `[lints]` table[^6] | ✓ | | //! `[lints.rust.unexpected_cfgs.check-cfg]` | ✓ | | +//! `--extern priv:` | ✓ | | //! //! [^1]: Bin dependencies are not included. //! @@ -1651,6 +1652,12 @@ fn calculate_normal( if let Some(allow_features) = &build_runner.bcx.gctx.cli_unstable().allow_features { allow_features.hash(&mut config); } + // -Zpublic-dependency changes how library units pass dependency privacy + // to rustc via `--extern`. + (unit.target.is_lib() + && build_runner.unit_deps(unit).iter().any(|dep| !dep.public) + && super::is_public_dependency_enabled(build_runner, unit)) + .hash(&mut config); // -Zno-embed-metadata changes how all units are compiled, and it also changes how we tell // rustc to link to deps using `--extern`. If it changes, we should rebuild everything. build_runner diff --git a/tests/testsuite/pub_priv.rs b/tests/testsuite/pub_priv.rs index 998915eda83..9c28d12c4d5 100644 --- a/tests/testsuite/pub_priv.rs +++ b/tests/testsuite/pub_priv.rs @@ -725,8 +725,7 @@ src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in publi p.cargo("check --message-format=short") .with_stderr_data(str![[r#" -src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in public interface -[WARNING] `foo` (lib) generated 1 warning +[CHECKING] foo v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]]) @@ -743,6 +742,9 @@ src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in publi p.cargo("check -Zpublic-dependency --message-format=short") .masquerade_as_nightly_cargo(&["public-dependency"]) .with_stderr_data(str![[r#" +[CHECKING] foo v0.0.1 ([ROOT]/foo) +src/lib.rs:3:13: [WARNING] type `FromDep` from private dependency 'dep' in public interface +[WARNING] `foo` (lib) generated 1 warning [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]])