Skip to content

Commit 8a2bc71

Browse files
committed
feat: Add "-Zpublic-denpendency" for public-dependency feature.
1 parent c061bfb commit 8a2bc71

File tree

30 files changed

+199
-213
lines changed

30 files changed

+199
-213
lines changed

src/cargo/core/compiler/mod.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ use crate::core::compiler::future_incompat::FutureIncompatReport;
8989
pub use crate::core::compiler::unit::{Unit, UnitInterner};
9090
use crate::core::manifest::TargetSourcePath;
9191
use crate::core::profiles::{PanicStrategy, Profile, StripInner};
92-
use crate::core::{Feature, PackageId, Target, Verbosity};
92+
use crate::core::{PackageId, Target, Verbosity};
9393
use crate::util::errors::{CargoResult, VerboseError};
9494
use crate::util::interning::InternedString;
9595
use crate::util::machine_message::{self, Message};
@@ -1437,15 +1437,7 @@ pub fn extern_args(
14371437
|dep: &UnitDep, extern_crate_name: InternedString, noprelude: bool| -> CargoResult<()> {
14381438
let mut value = OsString::new();
14391439
let mut opts = Vec::new();
1440-
if unit
1441-
.pkg
1442-
.manifest()
1443-
.unstable_features()
1444-
.require(Feature::public_dependency())
1445-
.is_ok()
1446-
&& !dep.public
1447-
&& unit.target.is_lib()
1448-
{
1440+
if !dep.public && unit.target.is_lib() {
14491441
opts.push("priv");
14501442
*unstable_opts = true;
14511443
}

src/cargo/core/features.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,6 @@ features! {
458458
/// Declarative build scripts.
459459
(unstable, metabuild, "", "reference/unstable.html#metabuild"),
460460

461-
/// Specifying the 'public' attribute on dependencies.
462-
(unstable, public_dependency, "", "reference/unstable.html#public-dependency"),
463-
464461
/// Allow to specify profiles other than 'dev', 'release', 'test', etc.
465462
(stable, named_profiles, "1.57", "reference/profiles.html#custom-profiles"),
466463

@@ -764,6 +761,7 @@ unstable_cli_options!(
764761
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
765762
precise_pre_release: bool = ("Enable pre-release versions to be selected with `update --precise`"),
766763
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
764+
public_dependency: bool = ("Enable public-dependency to allow marking dependencies as public/private"),
767765
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
768766
rustdoc_map: bool = ("Allow passing external documentation mappings to rustdoc"),
769767
rustdoc_scrape_examples: bool = ("Allows Rustdoc to scrape code examples from reverse-dependencies"),
@@ -1140,6 +1138,7 @@ impl CliUnstable {
11401138
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
11411139
"no-index-update" => self.no_index_update = parse_empty(k, v)?,
11421140
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
1141+
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
11431142
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
11441143
"precise-pre-release" => self.precise_pre_release = parse_empty(k, v)?,
11451144
"trim-paths" => self.trim_paths = parse_empty(k, v)?,

src/cargo/core/workspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,6 @@ impl<'cfg> Workspace<'cfg> {
449449
// NOTE: Since we use ConfigRelativePath, this root isn't used as
450450
// any relative paths are resolved before they'd be joined with root.
451451
Path::new("unused-relative-path"),
452-
self.unstable_features(),
453452
/* kind */ None,
454453
)
455454
})

src/cargo/ops/cargo_package.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor}
1010
use crate::core::manifest::Target;
1111
use crate::core::resolver::CliFeatures;
1212
use crate::core::{registry::PackageRegistry, resolver::HasDevUnits};
13-
use crate::core::{Feature, Shell, Verbosity, Workspace};
1413
use crate::core::{Package, PackageId, PackageSet, Resolve, SourceId};
14+
use crate::core::{Shell, Verbosity, Workspace};
1515
use crate::sources::PathSource;
1616
use crate::util::cache_lock::CacheLockMode;
1717
use crate::util::config::JobsConfig;
@@ -910,20 +910,7 @@ fn run_verify(
910910
let new_pkg = src.root_package()?;
911911
let pkg_fingerprint = hash_all(&dst)?;
912912
let ws = Workspace::ephemeral(new_pkg, config, None, true)?;
913-
914-
let rustc_args = if pkg
915-
.manifest()
916-
.unstable_features()
917-
.require(Feature::public_dependency())
918-
.is_ok()
919-
{
920-
// FIXME: Turn this on at some point in the future
921-
//Some(vec!["-D exported_private_dependencies".to_string()])
922-
Some(vec![])
923-
} else {
924-
None
925-
};
926-
913+
let rustc_args = Some(vec![]);
927914
let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
928915
ops::compile_with_exec(
929916
&ws,

src/cargo/util/toml/mod.rs

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::AlreadyPrintedError;
99
use anyhow::{anyhow, bail, Context as _};
1010
use cargo_platform::Platform;
1111
use cargo_util::paths;
12-
use cargo_util_schemas::manifest;
13-
use cargo_util_schemas::manifest::RustVersion;
12+
use cargo_util_schemas::manifest::{self, InheritableDependency};
13+
use cargo_util_schemas::manifest::{RustVersion, TomlDependency};
1414
use itertools::Itertools;
1515
use lazycell::LazyCell;
1616
use pathdiff::diff_paths;
@@ -105,61 +105,62 @@ fn read_manifest_from_str(
105105

106106
let mut unused = BTreeSet::new();
107107
let deserializer = toml::de::Deserializer::new(contents);
108-
let manifest: manifest::TomlManifest = match serde_ignored::deserialize(deserializer, |path| {
109-
let mut key = String::new();
110-
stringify(&mut key, &path);
111-
unused.insert(key);
112-
}) {
113-
Ok(manifest) => manifest,
114-
Err(e) => {
115-
let Some(span) = e.span() else {
116-
return Err(e.into());
117-
};
108+
let mut manifest: manifest::TomlManifest =
109+
match serde_ignored::deserialize(deserializer, |path| {
110+
let mut key = String::new();
111+
stringify(&mut key, &path);
112+
unused.insert(key);
113+
}) {
114+
Ok(manifest) => manifest,
115+
Err(e) => {
116+
let Some(span) = e.span() else {
117+
return Err(e.into());
118+
};
118119

119-
let (line_num, column) = translate_position(&contents, span.start);
120-
let source_start = contents[0..span.start]
121-
.rfind('\n')
122-
.map(|s| s + 1)
123-
.unwrap_or(0);
124-
let source_end = contents[span.end - 1..]
125-
.find('\n')
126-
.map(|s| s + span.end)
127-
.unwrap_or(contents.len());
128-
let source = &contents[source_start..source_end];
129-
// Make sure we don't try to highlight past the end of the line,
130-
// but also make sure we are highlighting at least one character
131-
let highlight_end = (column + contents[span].chars().count())
132-
.min(source.len())
133-
.max(column + 1);
134-
// Get the path to the manifest, relative to the cwd
135-
let manifest_path = diff_paths(manifest_file, config.cwd())
136-
.unwrap_or_else(|| manifest_file.to_path_buf())
137-
.display()
138-
.to_string();
139-
let snippet = Snippet {
140-
title: Some(Annotation {
141-
id: None,
142-
label: Some(e.message()),
143-
annotation_type: AnnotationType::Error,
144-
}),
145-
footer: vec![],
146-
slices: vec![Slice {
147-
source: &source,
148-
line_start: line_num + 1,
149-
origin: Some(manifest_path.as_str()),
150-
annotations: vec![SourceAnnotation {
151-
range: (column, highlight_end),
152-
label: "",
120+
let (line_num, column) = translate_position(&contents, span.start);
121+
let source_start = contents[0..span.start]
122+
.rfind('\n')
123+
.map(|s| s + 1)
124+
.unwrap_or(0);
125+
let source_end = contents[span.end - 1..]
126+
.find('\n')
127+
.map(|s| s + span.end)
128+
.unwrap_or(contents.len());
129+
let source = &contents[source_start..source_end];
130+
// Make sure we don't try to highlight past the end of the line,
131+
// but also make sure we are highlighting at least one character
132+
let highlight_end = (column + contents[span].chars().count())
133+
.min(source.len())
134+
.max(column + 1);
135+
// Get the path to the manifest, relative to the cwd
136+
let manifest_path = diff_paths(manifest_file, config.cwd())
137+
.unwrap_or_else(|| manifest_file.to_path_buf())
138+
.display()
139+
.to_string();
140+
let snippet = Snippet {
141+
title: Some(Annotation {
142+
id: None,
143+
label: Some(e.message()),
153144
annotation_type: AnnotationType::Error,
145+
}),
146+
footer: vec![],
147+
slices: vec![Slice {
148+
source: &source,
149+
line_start: line_num + 1,
150+
origin: Some(manifest_path.as_str()),
151+
annotations: vec![SourceAnnotation {
152+
range: (column, highlight_end),
153+
label: "",
154+
annotation_type: AnnotationType::Error,
155+
}],
156+
fold: false,
154157
}],
155-
fold: false,
156-
}],
157-
};
158-
let renderer = Renderer::styled();
159-
writeln!(config.shell().err(), "{}", renderer.render(snippet))?;
160-
return Err(AlreadyPrintedError::new(e.into()).into());
161-
}
162-
};
158+
};
159+
let renderer = Renderer::styled();
160+
writeln!(config.shell().err(), "{}", renderer.render(snippet))?;
161+
return Err(AlreadyPrintedError::new(e.into()).into());
162+
}
163+
};
163164
let add_unused = |warnings: &mut Warnings| {
164165
for key in unused {
165166
warnings.add_warning(format!("unused manifest key: {}", key));
@@ -183,10 +184,33 @@ fn read_manifest_from_str(
183184
}
184185
}
185186
}
187+
188+
let mut public_deps_without_z = BTreeSet::new();
189+
if let Some(deps) = &mut manifest.dependencies {
190+
for (name, dep) in deps {
191+
if let InheritableDependency::Value(toml_dep) = dep {
192+
if toml_dep.is_public() && !config.cli_unstable().public_dependency {
193+
if let TomlDependency::Detailed(d) = toml_dep {
194+
d.public = Some(false)
195+
}
196+
public_deps_without_z.insert(name.clone());
197+
}
198+
}
199+
}
200+
}
201+
let public_warn = |warnings: &mut Warnings| {
202+
for name in public_deps_without_z {
203+
warnings.add_warning(format!(
204+
"{name} is public, pass `-Zpublic-dependency` to enable support for it",
205+
))
206+
}
207+
};
208+
186209
return if manifest.project.is_some() || manifest.package.is_some() {
187210
let (mut manifest, paths) =
188211
to_real_manifest(manifest, embedded, source_id, package_root, config)?;
189212
add_unused(manifest.warnings_mut());
213+
public_warn(manifest.warnings_mut());
190214
if manifest.targets().iter().all(|t| t.is_custom_build()) {
191215
bail!(
192216
"no targets specified in the manifest\n\
@@ -198,6 +222,7 @@ fn read_manifest_from_str(
198222
} else {
199223
let (mut m, paths) = to_virtual_manifest(manifest, source_id, package_root, config)?;
200224
add_unused(m.warnings_mut());
225+
public_warn(m.warnings_mut());
201226
Ok((EitherManifest::Virtual(m), paths))
202227
};
203228

@@ -678,7 +703,6 @@ pub fn to_real_manifest(
678703
nested_paths: &mut nested_paths,
679704
config,
680705
warnings: &mut warnings,
681-
features: &features,
682706
platform: None,
683707
root: package_root,
684708
};
@@ -1153,7 +1177,6 @@ fn to_virtual_manifest(
11531177
config,
11541178
warnings: &mut warnings,
11551179
platform: None,
1156-
features: &features,
11571180
root,
11581181
};
11591182
(replace(&me, &mut cx)?, patch(&me, &mut cx)?)
@@ -1302,7 +1325,6 @@ struct Context<'a, 'b> {
13021325
warnings: &'a mut Vec<String>,
13031326
platform: Option<Platform>,
13041327
root: &'a Path,
1305-
features: &'a Features,
13061328
}
13071329

13081330
fn verify_lints(lints: Option<manifest::TomlLints>) -> CargoResult<Option<manifest::TomlLints>> {
@@ -1709,7 +1731,6 @@ pub(crate) fn to_dependency<P: ResolveToPath + Clone>(
17091731
warnings: &mut Vec<String>,
17101732
platform: Option<Platform>,
17111733
root: &Path,
1712-
features: &Features,
17131734
kind: Option<DepKind>,
17141735
) -> CargoResult<Dependency> {
17151736
dep_to_dependency(
@@ -1723,7 +1744,6 @@ pub(crate) fn to_dependency<P: ResolveToPath + Clone>(
17231744
warnings,
17241745
platform,
17251746
root,
1726-
features,
17271747
},
17281748
kind,
17291749
)
@@ -1944,8 +1964,6 @@ fn detailed_dep_to_dependency<P: ResolveToPath + Clone>(
19441964
}
19451965

19461966
if let Some(p) = orig.public {
1947-
cx.features.require(Feature::public_dependency())?;
1948-
19491967
if dep.kind() != DepKind::Normal {
19501968
bail!("'public' specifier can only be used on regular dependencies, not {:?} dependencies", dep.kind());
19511969
}

src/doc/src/reference/unstable.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,9 @@ The 'public-dependency' feature allows marking dependencies as 'public'
296296
or 'private'. When this feature is enabled, additional information is passed to rustc to allow
297297
the 'exported_private_dependencies' lint to function properly.
298298

299-
This requires the appropriate key to be set in `cargo-features`:
299+
Pass `-Zpublic-dependency` to cargo to enable support for it.
300300

301301
```toml
302-
cargo-features = ["public-dependency"]
303-
304302
[dependencies]
305303
my_dep = { version = "1.2.3", public = true }
306304
private_dep = "2.0.0" # Will be 'private' by default

tests/testsuite/artifact_dep.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,10 @@ fn with_assumed_host_target_and_optional_build_dep() {
25732573
.run();
25742574
}
25752575

2576+
// Since public-dependency had switched to non-blocking feature gate, (See https://github.com/rust-lang/cargo/issues/13308)
2577+
// this test case will warn "trait `c::Trait` from private dependency 'c' in public interface".
2578+
// The weird sutuation is that the warning "warning: `a` (lib) generated 1 warning (1 duplicate)" will appear randomly.
2579+
// Add #[allow(exported_private_dependencies)] to suppress it.
25762580
#[cargo_test]
25772581
fn decouple_same_target_transitive_dep_from_artifact_dep() {
25782582
// See https://github.com/rust-lang/cargo/issues/11463
@@ -2636,7 +2640,7 @@ fn decouple_same_target_transitive_dep_from_artifact_dep() {
26362640
"a/src/lib.rs",
26372641
r#"
26382642
use b::Trait as _;
2639-
2643+
#[allow(exported_private_dependencies)]
26402644
pub fn use_b_trait(x: &impl c::Trait) {
26412645
x.b();
26422646
}

tests/testsuite/build.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,8 @@ fn cargo_default_env_metadata_env_var() {
14391439
-C extra-filename=[..] \
14401440
--out-dir [..] \
14411441
-L dependency=[CWD]/target/debug/deps \
1442-
--extern bar=[CWD]/target/debug/deps/{prefix}bar{suffix}`
1442+
--extern 'priv:bar=[CWD]/target/debug/deps/{prefix}bar{suffix}' \
1443+
-Z unstable-options`
14431444
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
14441445
prefix = env::consts::DLL_PREFIX,
14451446
suffix = env::consts::DLL_SUFFIX,
@@ -1467,7 +1468,8 @@ fn cargo_default_env_metadata_env_var() {
14671468
-C extra-filename=[..] \
14681469
--out-dir [..] \
14691470
-L dependency=[CWD]/target/debug/deps \
1470-
--extern bar=[CWD]/target/debug/deps/{prefix}bar-[..]{suffix}`
1471+
--extern 'priv:bar=[CWD]/target/debug/deps/{prefix}bar-[..]{suffix}' \
1472+
-Z unstable-options`
14711473
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
14721474
",
14731475
prefix = env::consts::DLL_PREFIX,
@@ -2445,8 +2447,9 @@ fn verbose_release_build_deps() {
24452447
-C metadata=[..] \
24462448
--out-dir [..] \
24472449
-L dependency=[CWD]/target/release/deps \
2448-
--extern foo=[CWD]/target/release/deps/{prefix}foo{suffix} \
2449-
--extern foo=[CWD]/target/release/deps/libfoo.rlib`
2450+
--extern 'priv:foo=[CWD]/target/release/deps/{prefix}foo{suffix}' \
2451+
--extern 'priv:foo=[CWD]/target/release/deps/libfoo.rlib' \
2452+
-Z unstable-options`
24502453
[FINISHED] release [optimized] target(s) in [..]
24512454
",
24522455
prefix = env::consts::DLL_PREFIX,

tests/testsuite/build_script.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3018,7 +3018,7 @@ fn diamond_passes_args_only_once() {
30183018
[COMPILING] a v0.5.0 ([..]
30193019
[RUNNING] `rustc [..]`
30203020
[COMPILING] foo v0.5.0 ([..]
3021-
[RUNNING] `[..]rmeta -L native=test`
3021+
[RUNNING] `[..] --extern 'priv:a=[..]rmeta' --extern 'priv:b=[..]rmeta' -Z unstable-options -L native=test`
30223022
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
30233023
",
30243024
)

tests/testsuite/cargo/z_help/stdout.log

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Available unstable (nightly-only) flags:
2525
-Z panic-abort-tests Enable support to run tests with -Cpanic=abort
2626
-Z precise-pre-release Enable pre-release versions to be selected with `update --precise`
2727
-Z profile-rustflags Enable the `rustflags` option in profiles in .cargo/config.toml file
28+
-Z public-dependency Enable public-dependency to allow marking dependencies as public/private
2829
-Z publish-timeout Enable the `publish.timeout` key in .cargo/config.toml file
2930
-Z rustdoc-map Allow passing external documentation mappings to rustdoc
3031
-Z rustdoc-scrape-examples Allows Rustdoc to scrape code examples from reverse-dependencies
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
cargo-features = ["public-dependency"]
21
[package]
32
name = "bar"
43
version = "0.0.0"

0 commit comments

Comments
 (0)