Skip to content

Commit

Permalink
Auto merge of #14018 - epage:dep_name, r=ehuss
Browse files Browse the repository at this point in the history
fix(fix): Address problems with implicit -> explicit feature migration

### What does this PR try to resolve?

Within the scope of `cargo fix` there  are two problems
- We wipe out existing feature activations if it has the same name as an optional dependency
- The `Cargo.toml` isn't parseable because the unused optional dependency won't "exist" if just `dep_name/feature_name` is used

Fixes #14010

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

As for the unused optional dependency not "existing" error,
- #14015 is for improving the message for weak dep features
- #14016 is for re-evaluating how we handle this for strong dep features

Depending on what solution we go with for #14016, we might want to revisit the second migration within this PR.  This is one reason I made the commit separate (in addition to just making it clearer whats happening as this gets into some finer details of features).

### Additional information
  • Loading branch information
bors committed Jun 17, 2024
2 parents f911dfd + 21c0928 commit 83a3964
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 61 deletions.
52 changes: 43 additions & 9 deletions src/cargo/ops/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
fixes += rename_dep_fields_2024(workspace, "dependencies");
}

fixes += add_feature_for_unused_deps(pkg, root);
fixes += add_feature_for_unused_deps(pkg, root, ws.gctx());
fixes += rename_table(root, "project", "package");
if let Some(target) = root.get_mut("lib").and_then(|t| t.as_table_like_mut()) {
fixes += rename_target_fields_2024(target);
Expand Down Expand Up @@ -435,7 +435,11 @@ fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) ->
1
}

fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableLike) -> usize {
fn add_feature_for_unused_deps(
pkg: &Package,
parent: &mut dyn toml_edit::TableLike,
gctx: &GlobalContext,
) -> usize {
let manifest = pkg.manifest();

let activated_opt_deps = manifest
Expand All @@ -456,18 +460,48 @@ fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableL
for dep in manifest.dependencies() {
let dep_name_in_toml = dep.name_in_toml();
if dep.is_optional() && !activated_opt_deps.contains(dep_name_in_toml.as_str()) {
fixes += 1;
if let Some(features) = parent
.entry("features")
.or_insert(toml_edit::table())
.as_table_like_mut()
{
features.insert(
dep_name_in_toml.as_str(),
toml_edit::Item::Value(toml_edit::Value::Array(toml_edit::Array::from_iter(
&[format!("dep:{}", dep_name_in_toml)],
))),
);
let activate_dep = format!("dep:{dep_name_in_toml}");
let strong_dep_feature_prefix = format!("{dep_name_in_toml}/");
features
.entry(dep_name_in_toml.as_str())
.or_insert_with(|| {
fixes += 1;
toml_edit::Item::Value(toml_edit::Value::Array(
toml_edit::Array::from_iter([&activate_dep]),
))
});
// Ensure `dep:dep_name` is present for `dep_name/feature_name` since `dep:` is the
// only way to guarantee an optional dependency is available for use.
//
// The way we avoid implicitly creating features in Edition2024 is we remove the
// dependency from `resolved_toml` if there is no `dep:` syntax as that is the only
// syntax that suppresses the creation of the implicit feature.
for (feature_name, activations) in features.iter_mut() {
let Some(activations) = activations.as_array_mut() else {
let _ = gctx.shell().warn(format_args!("skipping fix of feature `{feature_name}` in package `{}`: unsupported feature schema", pkg.name()));
continue;
};
if activations
.iter()
.any(|a| a.as_str().map(|a| a == activate_dep).unwrap_or(false))
{
continue;
}
let Some(activate_dep_pos) = activations.iter().position(|a| {
a.as_str()
.map(|a| a.starts_with(&strong_dep_feature_prefix))
.unwrap_or(false)
}) else {
continue;
};
fixes += 1;
activations.insert(activate_dep_pos, &activate_dep);
}
}
}
}
Expand Down
Loading

0 comments on commit 83a3964

Please sign in to comment.