Auto merge of #10337 - WaffleLapkin:merge_futures_with_all_features, r=alexcrichton

Do not ignore `--features` when `--all-features` is present

This allows to specify dependency features when using `--all-features`, for example:
```shell
$ cargo run --example example --all-features --features="tracing/log"
```
You can test this in this repository: https://github.com/WaffleLapkin/cargo_all_some_features, it contains an example with ``required-features = [..., "tracing/log"]`` that is impossible to run with `--all-features` without this patch.

An attempt to fix #10333
This commit is contained in:
bors 2022-01-31 17:52:10 +00:00
commit ea259a07f5
7 changed files with 103 additions and 28 deletions

View file

@ -323,14 +323,14 @@ fn build_requirements<'a, 'b: 'a>(
return Err(e.into_activate_error(parent, s));
}
}
} else {
for fv in features.iter() {
if let Err(e) = reqs.require_value(fv) {
return Err(e.into_activate_error(parent, s));
}
}
handle_default(*uses_default_features, &mut reqs)?;
}
for fv in features.iter() {
if let Err(e) = reqs.require_value(fv) {
return Err(e.into_activate_error(parent, s));
}
}
handle_default(*uses_default_features, &mut reqs)?;
}
RequestedFeatures::DepFeatures {
features,

View file

@ -680,19 +680,18 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
) -> Vec<FeatureValue> {
let summary = self.resolve.summary(pkg_id);
let feature_map = summary.features();
if cli_features.all_features {
feature_map
.keys()
.map(|k| FeatureValue::Feature(*k))
.collect()
} else {
let mut result: Vec<FeatureValue> = cli_features.features.iter().cloned().collect();
let default = InternedString::new("default");
if cli_features.uses_default_features && feature_map.contains_key(&default) {
result.push(FeatureValue::Feature(default));
}
result
let mut result: Vec<FeatureValue> = cli_features.features.iter().cloned().collect();
let default = InternedString::new("default");
if cli_features.uses_default_features && feature_map.contains_key(&default) {
result.push(FeatureValue::Feature(default));
}
if cli_features.all_features {
result.extend(feature_map.keys().map(|k| FeatureValue::Feature(*k)))
}
result
}
/// Returns the dependencies for a package, filtering out inactive targets.

View file

@ -1117,7 +1117,7 @@ impl<'cfg> Workspace<'cfg> {
cli_features: &CliFeatures,
found_features: &mut BTreeSet<FeatureValue>,
) -> CliFeatures {
if cli_features.features.is_empty() || cli_features.all_features {
if cli_features.features.is_empty() {
return cli_features.clone();
}
@ -1185,7 +1185,7 @@ impl<'cfg> Workspace<'cfg> {
}
CliFeatures {
features: Rc::new(features),
all_features: false,
all_features: cli_features.all_features,
uses_default_features: cli_features.uses_default_features,
}
}

View file

@ -473,12 +473,12 @@ fn add_cli_features(
let mut to_add: HashSet<FeatureValue> = HashSet::new();
if cli_features.all_features {
to_add.extend(feature_map.keys().map(|feat| FeatureValue::Feature(*feat)));
} else {
if cli_features.uses_default_features {
to_add.insert(FeatureValue::Feature(InternedString::new("default")));
}
to_add.extend(cli_features.features.iter().cloned());
};
}
if cli_features.uses_default_features {
to_add.insert(FeatureValue::Feature(InternedString::new("default")));
}
to_add.extend(cli_features.features.iter().cloned());
// Add each feature as a node, and mark as "from command-line" in graph.cli_features.
for fv in to_add {

View file

@ -2398,3 +2398,77 @@ foo v0.1.0 [..]
)
.run();
}
#[cargo_test]
fn all_features_merges_with_features() {
Package::new("dep", "0.1.0")
.feature("feat1", &[])
.file(
"src/lib.rs",
r#"
#[cfg(feature="feat1")]
pub fn work() {
println!("it works");
}
"#,
)
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[features]
a = []
[dependencies]
dep = "0.1"
[[example]]
name = "ex"
required-features = ["a", "dep/feat1"]
"#,
)
.file(
"examples/ex.rs",
r#"
fn main() {
dep::work();
}
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("run --example ex --all-features --features dep/feat1")
.with_stderr(
"\
[UPDATING] [..]
[DOWNLOADING] crates ...
[DOWNLOADED] [..]
[COMPILING] dep v0.1.0
[COMPILING] foo v0.1.0 [..]
[FINISHED] [..]
[RUNNING] `target/debug/examples/ex[EXE]`
",
)
.with_stdout("it works")
.run();
switch_to_resolver_2(&p);
p.cargo("run --example ex --all-features --features dep/feat1")
.with_stderr(
"\
[FINISHED] [..]
[RUNNING] `target/debug/examples/ex[EXE]`
",
)
.with_stdout("it works")
.run();
}

View file

@ -849,7 +849,8 @@ foo v0.1.0 ([ROOT]/foo)
bar v1.0.0
bar feature \"default\"
foo v0.1.0 ([ROOT]/foo)
foo feature \"a\" (command-line)
foo feature \"a\" (command-line)
foo feature \"default\" (command-line)
",
)
.run();

View file

@ -275,6 +275,7 @@ foo v0.1.0 ([..]/foo)
opt2 v1.0.0
opt2 feature \"default\"
foo v0.1.0 ([..]/foo)
foo feature \"default\" (command-line)
foo feature \"f1\" (command-line)
foo feature \"f2\" (command-line)
foo feature \"f2\" (command-line)