mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
feat: add the package
feature unification option
This commit is contained in:
parent
73b5b33e1d
commit
70f16f448b
@ -162,6 +162,7 @@ pub fn resolve_ws_with_opts<'gctx>(
|
||||
FeatureUnification::Workspace => {
|
||||
vec![ops::Packages::All(Vec::new()).to_package_id_specs(ws)?]
|
||||
}
|
||||
FeatureUnification::Package => specs.iter().map(|spec| vec![spec.clone()]).collect(),
|
||||
};
|
||||
let specs: Vec<_> = individual_specs
|
||||
.iter()
|
||||
@ -269,7 +270,28 @@ pub fn resolve_ws_with_opts<'gctx>(
|
||||
for specs in individual_specs {
|
||||
let feature_opts = FeatureOpts::new(ws, has_dev_units, force_all_targets)?;
|
||||
|
||||
// We want to narrow the features to the current specs so that stuff like `cargo check -p a
|
||||
// -p b -F a/a,b/b` works and the resolver does not contain that `a` does not have feature
|
||||
// `b` and vice-versa. However, resolver v1 needs to see even features of unselected
|
||||
// packages turned on if it was because of working directory being inside the unselected
|
||||
// package, because they might turn on a feature of a selected package.
|
||||
let narrowed_features = match feature_unification {
|
||||
FeatureUnification::Package => {
|
||||
let mut narrowed_features = cli_features.clone();
|
||||
let enabled_features = members_with_features
|
||||
.iter()
|
||||
.filter_map(|(package, cli_features)| {
|
||||
specs
|
||||
.iter()
|
||||
.any(|spec| spec.matches(package.package_id()))
|
||||
.then_some(cli_features.features.iter())
|
||||
})
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect();
|
||||
narrowed_features.features = Rc::new(enabled_features);
|
||||
Cow::Owned(narrowed_features)
|
||||
}
|
||||
FeatureUnification::Selected | FeatureUnification::Workspace => {
|
||||
Cow::Borrowed(cli_features)
|
||||
}
|
||||
|
@ -2864,6 +2864,7 @@ pub enum IncompatibleRustVersions {
|
||||
#[derive(Copy, Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum FeatureUnification {
|
||||
Package,
|
||||
Selected,
|
||||
Workspace,
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ fn package_feature_unification() {
|
||||
".cargo/config.toml",
|
||||
r#"
|
||||
[resolver]
|
||||
feature-unification = "selected"
|
||||
feature-unification = "package"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
@ -245,14 +245,21 @@ fn package_feature_unification() {
|
||||
p.cargo("check -p a -p b")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_contains("[ERROR] features were unified")
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
)
|
||||
.run();
|
||||
p.cargo("check")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_contains("[ERROR] features were unified")
|
||||
.with_stderr_data(str![[r#"
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
// Sanity check that compilation without package feature unification does not work
|
||||
p.cargo("check -p a -p b")
|
||||
@ -271,7 +278,7 @@ fn package_feature_unification_default_features() {
|
||||
".cargo/config.toml",
|
||||
r#"
|
||||
[resolver]
|
||||
feature-unification = "selected"
|
||||
feature-unification = "package"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
@ -366,17 +373,9 @@ fn package_feature_unification_default_features() {
|
||||
p.cargo("check")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -407,7 +406,7 @@ fn package_feature_unification_cli_features() {
|
||||
".cargo/config.toml",
|
||||
r#"
|
||||
[resolver]
|
||||
feature-unification = "selected"
|
||||
feature-unification = "package"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
@ -481,30 +480,17 @@ fn package_feature_unification_cli_features() {
|
||||
p.cargo("check -p a -p b -F a,b")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] 1 package to latest compatible version
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] outside v0.1.0 (registry `dummy-registry`)
|
||||
[CHECKING] outside v0.1.0
|
||||
[ERROR] features were unified
|
||||
--> [ROOT]/home/.cargo/registry/src/-[HASH]/outside-0.1.0/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `outside` (lib) due to 1 previous error
|
||||
[WARNING] build failed, waiting for other jobs to finish...
|
||||
[CHECKING] b v0.1.0 ([ROOT]/foo/b)
|
||||
[CHECKING] a v0.1.0 ([ROOT]/foo/a)
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -513,26 +499,9 @@ fn package_feature_unification_cli_features() {
|
||||
p.cargo("check --workspace --exclude common -F a,b")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[CHECKING] outside v0.1.0
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] features were unified
|
||||
--> [ROOT]/home/.cargo/registry/src/-[HASH]/outside-0.1.0/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `outside` (lib) due to 1 previous error
|
||||
[WARNING] build failed, waiting for other jobs to finish...
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -542,26 +511,9 @@ fn package_feature_unification_cli_features() {
|
||||
p.cargo("check -p a -p b -F a/a,b/b")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[CHECKING] outside v0.1.0
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] features were unified
|
||||
--> [ROOT]/home/.cargo/registry/src/-[HASH]/outside-0.1.0/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[WARNING] build failed, waiting for other jobs to finish...
|
||||
[ERROR] could not compile `outside` (lib) due to 1 previous error
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -618,7 +570,7 @@ fn package_feature_unification_weak_dependencies() {
|
||||
".cargo/config.toml",
|
||||
r#"
|
||||
[resolver]
|
||||
feature-unification = "selected"
|
||||
feature-unification = "package"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
@ -690,17 +642,12 @@ fn package_feature_unification_weak_dependencies() {
|
||||
p.cargo("check -p a -p b")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[CHECKING] a v0.1.0 ([ROOT]/foo/a)
|
||||
[CHECKING] b v0.1.0 ([ROOT]/foo/b)
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -709,16 +656,9 @@ fn package_feature_unification_weak_dependencies() {
|
||||
p.cargo("check")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(101)
|
||||
.with_stderr_data(str![[r#"
|
||||
[CHECKING] common v0.1.0 ([ROOT]/foo/common)
|
||||
[ERROR] features were unified
|
||||
--> common/src/lib.rs:3:17
|
||||
|
|
||||
3 | compile_error!("features were unified");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[ERROR] could not compile `common` (lib) due to 1 previous error
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
@ -873,27 +813,27 @@ common v0.1.0 ([ROOT]/foo/common)
|
||||
p.cargo("tree -e features")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "selected") // To be changed to package later
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_stdout_data(str![[r#"
|
||||
common v0.1.0 ([ROOT]/foo/common)
|
||||
a v0.1.0 ([ROOT]/foo/a)
|
||||
├── common feature "a"
|
||||
│ └── common v0.1.0 ([ROOT]/foo/common)
|
||||
├── common feature "default" (command-line)
|
||||
├── common feature "default"
|
||||
│ └── common v0.1.0 ([ROOT]/foo/common)
|
||||
├── outside feature "a"
|
||||
│ └── outside v0.1.0
|
||||
└── outside feature "default"
|
||||
└── outside v0.1.0
|
||||
|
||||
b v0.1.0 ([ROOT]/foo/b)
|
||||
├── common feature "b"
|
||||
│ └── common v0.1.0 ([ROOT]/foo/common)
|
||||
├── common feature "default" (command-line) (*)
|
||||
├── common feature "default"
|
||||
│ └── common v0.1.0 ([ROOT]/foo/common)
|
||||
├── outside feature "b"
|
||||
│ └── outside v0.1.0
|
||||
└── outside feature "default" (*)
|
||||
|
||||
common v0.1.0 ([ROOT]/foo/common)
|
||||
└── outside feature "default"
|
||||
└── outside v0.1.0
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
@ -973,7 +913,7 @@ fn cargo_install_ignores_config() {
|
||||
.arg(p.root())
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "selected")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_stderr_data(str![[r#"
|
||||
[INSTALLING] a v0.1.0 ([ROOT]/foo)
|
||||
[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
|
||||
@ -1029,7 +969,7 @@ edition = "2021"
|
||||
.build();
|
||||
|
||||
p.cargo("fix --edition --allow-no-vcs")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "selected")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_stderr_data(str![[r#"
|
||||
@ -1111,10 +1051,10 @@ fn edition_v2_resolver_report() {
|
||||
.build();
|
||||
|
||||
p.cargo("fix --edition --allow-no-vcs --workspace")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "selected")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
.with_status(0)
|
||||
.with_status(101)
|
||||
.with_stderr_data(
|
||||
str![[r#"
|
||||
[MIGRATING] Cargo.toml from 2018 edition to 2021
|
||||
@ -1125,26 +1065,7 @@ fn edition_v2_resolver_report() {
|
||||
[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
|
||||
[DOWNLOADED] opt_dep v1.0.0 (registry `dummy-registry`)
|
||||
[MIGRATING] bar/Cargo.toml from 2018 edition to 2021
|
||||
[NOTE] Switching to Edition 2021 will enable the use of the version 2 feature resolver in Cargo.
|
||||
This may cause some dependencies to be built with fewer features enabled than previously.
|
||||
More information about the resolver changes may be found at https://doc.rust-lang.org/nightly/edition-guide/rust-2021/default-cargo-resolver.html
|
||||
When building the following dependencies, the given features will no longer be used:
|
||||
|
||||
common v1.0.0 removed features: dev-feat, f1, opt_dep
|
||||
common v1.0.0 (as host dependency) removed features: dev-feat, f1
|
||||
|
||||
The following differences only apply when building with dev-dependencies:
|
||||
|
||||
common v1.0.0 removed features: f1, opt_dep
|
||||
|
||||
[CHECKING] opt_dep v1.0.0
|
||||
[CHECKING] bar v1.0.0
|
||||
[CHECKING] bar v0.1.0 ([ROOT]/foo/bar)
|
||||
[MIGRATING] bar/src/lib.rs from 2018 edition to 2021
|
||||
[CHECKING] common v1.0.0
|
||||
[CHECKING] foo v0.1.0 ([ROOT]/foo)
|
||||
[MIGRATING] src/lib.rs from 2018 edition to 2021
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
[ERROR] cannot fix edition when using `feature-unification = "package"`.
|
||||
|
||||
"#]]
|
||||
.unordered(),
|
||||
@ -1213,7 +1134,7 @@ fn feature_unification_of_cli_features_within_workspace() {
|
||||
p.cargo("check -p parent -F grandchild/a")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
// .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_status(101)
|
||||
.with_stderr_data(str![[r#"
|
||||
[ERROR] the package 'parent' does not contain this feature: grandchild/a
|
||||
@ -1246,7 +1167,7 @@ fn feature_unification_of_cli_features_within_workspace() {
|
||||
p.cargo("check -p child -F grandchild/a")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
// .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_stderr_data(str![[r#"
|
||||
[CHECKING] grandchild v0.1.0 ([ROOT]/foo/grandchild)
|
||||
[CHECKING] child v0.1.0 ([ROOT]/foo/child)
|
||||
@ -1278,7 +1199,7 @@ fn feature_unification_of_cli_features_within_workspace() {
|
||||
p.cargo("check -F grandchild/a")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
// .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_stderr_data(str![[r#"
|
||||
[CHECKING] parent v0.1.0 ([ROOT]/foo/parent)
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
@ -1309,7 +1230,7 @@ fn feature_unification_of_cli_features_within_workspace() {
|
||||
p.cargo("check -F grandchild/a --workspace --exclude grandchild")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
// .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_stderr_data(str![[r#"
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
@ -1339,7 +1260,7 @@ fn feature_unification_of_cli_features_within_workspace() {
|
||||
p.cargo("check -F grandchild/a --workspace --exclude grandchild --exclude child")
|
||||
.arg("-Zfeature-unification")
|
||||
.masquerade_as_nightly_cargo(&["feature-unification"])
|
||||
// .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.env("CARGO_RESOLVER_FEATURE_UNIFICATION", "package")
|
||||
.with_status(101)
|
||||
.with_stderr_data(str![[r#"
|
||||
[ERROR] the package 'parent' does not contain this feature: grandchild/a
|
||||
|
Loading…
x
Reference in New Issue
Block a user