Auto merge of #14221 - epage:implicit, r=weihanglo

fix: Ensure dep/feature activates the dependency on 2024

### What does this PR try to resolve?

Fixes #14016

### How should we test and review this PR?

This doesn't revert the last commit of #14018 so that it works properly
on Editions 2021 and 2024.

### Additional information
This commit is contained in:
bors 2024-07-10 18:23:50 +00:00
commit fd2b60ea01
2 changed files with 104 additions and 1 deletions

View File

@ -291,7 +291,7 @@ fn resolve_toml(
dev_dependencies2: None,
build_dependencies: None,
build_dependencies2: None,
features: original_toml.features.clone(),
features: None,
target: None,
replace: original_toml.replace.clone(),
patch: original_toml.patch.clone(),
@ -322,6 +322,8 @@ fn resolve_toml(
});
resolved_toml.package = Some(resolved_package);
resolved_toml.features = resolve_features(original_toml.features.as_ref(), edition)?;
resolved_toml.lib = targets::resolve_lib(
original_toml.lib.as_ref(),
package_root,
@ -686,6 +688,40 @@ fn default_readme_from_package_root(package_root: &Path) -> Option<String> {
None
}
#[tracing::instrument(skip_all)]
fn resolve_features(
original_features: Option<&BTreeMap<manifest::FeatureName, Vec<String>>>,
edition: Edition,
) -> CargoResult<Option<BTreeMap<manifest::FeatureName, Vec<String>>>> {
let Some(mut resolved_features) = original_features.cloned() else {
return Ok(None);
};
if Edition::Edition2024 <= edition {
for activations in resolved_features.values_mut() {
let mut deps = Vec::new();
for feature_value in activations.iter() {
let feature_value = FeatureValue::new(InternedString::new(feature_value));
let FeatureValue::DepFeature {
dep_name,
dep_feature: _,
weak: false,
} = feature_value
else {
continue;
};
let dep = FeatureValue::Dep { dep_name }.to_string();
if !activations.contains(&dep) {
deps.push(dep);
}
}
activations.extend(deps);
}
}
Ok(Some(resolved_features))
}
#[tracing::instrument(skip_all)]
fn resolve_dependencies<'a>(
gctx: &GlobalContext,

View File

@ -1847,6 +1847,73 @@ fn features_option_given_twice() {
p.cargo("check --features a --features b").run();
}
#[cargo_test(nightly, reason = "edition2024 is not stable")]
fn strong_dep_feature_edition2024() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["edition2024"]
[package]
name = "foo"
version = "0.1.0"
edition = "2024"
[features]
optional_dep = ["optional_dep/foo"]
[dependencies]
optional_dep = { path = "optional_dep", optional = true }
"#,
)
.file(
"src/main.rs",
r#"
fn main() {}
"#,
)
.file(
"optional_dep/Cargo.toml",
r#"
[package]
name = "optional_dep"
[features]
foo = []
"#,
)
.file(
"optional_dep/src/lib.rs",
r#"
"#,
)
.build();
p.cargo("metadata")
.masquerade_as_nightly_cargo(&["edition2024"])
.with_stdout_data(
str![[r#"
{
"metadata": null,
"packages": [
{
"features": {
"optional_dep": [
"optional_dep/foo",
"dep:optional_dep"
]
},
"name": "foo",
"...": "{...}"
}
],
"...": "{...}"
}
"#]]
.json(),
)
.run();
}
#[cargo_test]
fn multi_multi_features() {
let p = project()