diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 8aed78f315a..31aa29f573b 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1506,15 +1506,14 @@ pub fn extern_args( |dep: &UnitDep, extern_crate_name: InternedString, noprelude: bool| -> CargoResult<()> { let mut value = OsString::new(); let mut opts = Vec::new(); - if unit + let is_public_dependency_enabled = unit .pkg .manifest() .unstable_features() .require(Feature::public_dependency()) .is_ok() - && !dep.public - && unit.target.is_lib() - { + || build_runner.bcx.gctx.cli_unstable().public_dependency; + if !dep.public && unit.target.is_lib() && is_public_dependency_enabled { opts.push("priv"); *unstable_opts = true; } diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index c1d6493ed0a..0f8ca4f2ceb 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -765,6 +765,7 @@ unstable_cli_options!( panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"), precise_pre_release: bool = ("Enable pre-release versions to be selected with `update --precise`"), profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"), + public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"), publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"), rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"), rustdoc_scrape_examples: bool = ("Allows Rustdoc to scrape code examples from reverse-dependencies"), @@ -1141,6 +1142,7 @@ impl CliUnstable { "mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?, "no-index-update" => self.no_index_update = parse_empty(k, v)?, "panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?, + "public-dependency" => self.public_dependency = parse_empty(k, v)?, "profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?, "precise-pre-release" => self.precise_pre_release = parse_empty(k, v)?, "trim-paths" => self.trim_paths = parse_empty(k, v)?, diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 243b37e52e6..3fe8239e48b 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -911,6 +911,7 @@ fn run_verify( .unstable_features() .require(Feature::public_dependency()) .is_ok() + || ws.gctx().cli_unstable().public_dependency { // FIXME: Turn this on at some point in the future //Some(vec!["-D exported_private_dependencies".to_string()]) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 0bead106403..059127de9f3 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -727,6 +727,27 @@ pub fn to_real_manifest( v.unused_keys(), manifest_ctx.warnings, ); + let mut resolved = resolved; + if let manifest::TomlDependency::Detailed(ref mut d) = resolved { + if d.public.is_some() { + if matches!(dep.kind(), DepKind::Normal) { + if !manifest_ctx + .features + .require(Feature::public_dependency()) + .is_ok() + && !manifest_ctx.gctx.cli_unstable().public_dependency + { + d.public = None; + manifest_ctx.warnings.push(format!( + "Ignoring `public` on dependency {name}. Pass `-Zpublic-dependency` to enable support for it", name = &dep.name_in_toml() + )) + } + } else { + d.public = None; + } + } + } + manifest_ctx.deps.push(dep); deps.insert( n.clone(), @@ -1992,15 +2013,23 @@ fn detailed_dep_to_dependency( } if let Some(p) = orig.public { - manifest_ctx - .features - .require(Feature::public_dependency())?; + let public_feature = manifest_ctx.features.require(Feature::public_dependency()); + let with_z_public = manifest_ctx.gctx.cli_unstable().public_dependency; + let with_public_feature = public_feature.is_ok(); + if !with_public_feature && (!with_z_public && !manifest_ctx.gctx.nightly_features_allowed) { + public_feature?; + } if dep.kind() != DepKind::Normal { - bail!("'public' specifier can only be used on regular dependencies, not {:?} dependencies", dep.kind()); + match (with_public_feature, with_z_public) { + (true, _) => bail!("'public' specifier can only be used on regular dependencies, not {:?} dependencies", dep.kind()), + (_, true) => bail!("'public' specifier can only be used on regular dependencies, not {:?} dependencies", dep.kind()), + // If public feature isn't enabled in nightly, we instead warn that. + (false, false) => manifest_ctx.warnings.push(format!("'public' specifier can only be used on regular dependencies, not {:?} dependencies", dep.kind())), + } + } else { + dep.set_public(p); } - - dep.set_public(p); } if let (Some(artifact), is_lib, target) = ( diff --git a/tests/build-std/main.rs b/tests/build-std/main.rs index 39c23196266..84915790851 100644 --- a/tests/build-std/main.rs +++ b/tests/build-std/main.rs @@ -33,7 +33,7 @@ fn enable_build_std(e: &mut Execs, arg: Option<&str>) { Some(s) => format!("-Zbuild-std={}", s), None => "-Zbuild-std".to_string(), }; - e.arg(arg); + e.arg(arg).arg("-Zpublic-dependency"); e.masquerade_as_nightly_cargo(&["build-std"]); } diff --git a/tests/testsuite/cargo/z_help/stdout.term.svg b/tests/testsuite/cargo/z_help/stdout.term.svg index ced211b9259..5848c09f543 100644 --- a/tests/testsuite/cargo/z_help/stdout.term.svg +++ b/tests/testsuite/cargo/z_help/stdout.term.svg @@ -1,4 +1,4 @@ - +