Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(manifest)!: implement feature-metadata RFC3416 #15056

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

AudaciousAxiom
Copy link

What does this PR try to resolve?

This PR implements RFC3416: feature-metadata.
It introduces an alternate syntax to define crate features in manifests: instead of simply being an array of features the feature enables, it can now be a table with, for now, one required array key, enables, which is equivalent to the existing array. This lays the groundwork for later supporting additional keys in that table, to provide feature metadata.

Related to #14157

How should we test and review this PR?

Integrations tests are included in this PR, including for the normalized manifest used for publishing on a crate registry.

Additional information

  • The JSON schema of the manifest was updated using:
cargo test -p cargo-util-schemas --features unstable-schema -- 'dump_manifest_schema'

Questions

  • Should there be a Cargo unstable feature for this change?
  • This PR of course introduces a breaking change in the cargo-util-schemas crate, is there anything to do regarding this in this PR?
  • Should this PR also attempt to update core::Summary or should this be left to future implementations of RFCs providing other keys (e.g., doc)?

@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2025

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @epage (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added A-interacts-with-crates.io Area: interaction with registries A-manifest Area: Cargo.toml issues Command-publish S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 12, 2025

impl FeatureDefinition {
/// Returns the features that this feature enables.
pub fn enables(&self) -> &[String] {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method could also return an impl Iterator<Item = String> if preferred.

src/cargo/util/toml/mod.rs Show resolved Hide resolved
tests/testsuite/features.rs Outdated Show resolved Hide resolved
Comment on lines +2932 to +2948
let feature_array = feature_deps
.enables()
.iter()
.filter(|feature_dep| {
let feature_value = FeatureValue::new(InternedString::new(feature_dep));
match feature_value {
FeatureValue::Dep { dep_name }
| FeatureValue::DepFeature { dep_name, .. } => {
let k = &manifest::PackageName::new(dep_name.to_string()).unwrap();
dep_name_set.contains(k)
}
_ => true,
}
_ => true,
}
});
})
.cloned()
.collect();
*feature_deps = FeatureDefinition::Array(feature_array);
Copy link
Author

@AudaciousAxiom AudaciousAxiom Jan 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For compatibility, this uses the array syntax for generating the normalized manifest, even when the table syntax is used by authors (see the corresponding integration test).

@AudaciousAxiom AudaciousAxiom force-pushed the feat/rfc-impl-feature-metadata branch from 790a0e8 to 338281e Compare January 12, 2025 17:49
@AudaciousAxiom AudaciousAxiom marked this pull request as ready for review January 12, 2025 18:04
for (feature, feature_definition) in features {
match feature_definition {
FeatureDefinition::Array(..) => {}
FeatureDefinition::Metadata(FeatureMetadata { _unused_keys, .. }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't got time into full review, though I think the meta field should be behind a nightly feature flag.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Should there be a Cargo unstable feature for this change?

Yes. Probably behind a cargo-feature "feature-metadata".

  • This PR of course introduces a breaking change in the cargo-util-schemas crate, is there anything to do regarding this in this PR?

Could add a doc comment on relevant field/variant indicating it is unstable/nightly only.

/// Unstable feature `-Ztrim-paths`.
pub trim_paths: Option<TomlTrimPaths>,

There is a CI job checking if a member crate needs a version bump. It didn't warn you so I assume it has already been bumped in this release cycle. You do not need to do anything.

  • Should this PR also attempt to update core::Summary or should this be left to future implementations of RFCs providing other keys (e.g., doc)?

Summary is more like a thing for dependency resolution. I think we revisit it in the future. Regardless, see epage's comment #14157 (comment) that the feature itself is not particularly useful until other RFC gets merged. Anyway, thanks for the contribution!

@epage
Copy link
Contributor

epage commented Jan 13, 2025

What is your motivation for moving this forward?

In #14157 (comment) I was wondering if this was worth it without a feature depending on it.

@rustbot rustbot added A-documenting-cargo-itself Area: Cargo's documentation A-unstable Area: nightly unstable support labels Jan 13, 2025
@AudaciousAxiom
Copy link
Author

What is your motivation for moving this forward?

I have recently published featurecomb, a crate that allows to define relations between Cargo features in manifests (e.g., mutual exclusion, or a feature requiring another one to be enabled), and to enforce these relations through a proc-macro that reads the manifest and generates #[cfg]-gated compile_error! statements.

I wanted to see how much of this could be introduced into Cargo (I am aware of other existing effort in that direction), and the first step for that was to tackle feature-metadata.
(The most challenging open question I think would be that enforcement cannot be done through the manifest only, even if fully implemented in Cargo, at the very least because of course Cargo is not mandatory for compiling Rust code and it would therefore not be possible to rely on these relations being actually enforced without a dedicated attribute/macro in the source code itself, as is the case with featurecomb.)


I have introduced a feature-metadata unstable feature which can be dynamically enabled through cargo-features. However, I realize now that the same cannot be done for the cargo-util-schemas crate (we can only document the FeatureDefinition::Metadata variant as unstable). So, unless there is a way to dynamically feature-gate the change in the schema, and to not cause unnecessary churn to the dependents of cargo-util-schemas, I agree it may be best not to move forward on this PR for now, until other keys are introduced. Future implementations of these could hopefully use this PR as a base.

@epage
Copy link
Contributor

epage commented Jan 13, 2025

I wanted to see how much of this could be introduced into Cargo (I am aware of other existing effort in that direction), and the first step for that was to tackle feature-metadata.

Interesting effort. Some cautions though

  • Trying to add mutually exclusive support for the existing feature system is likely a dead end because features must be additive
  • This would created "unused manifest fields" which are not subject to our compatibility guarantees. I'd recommend finding a different way to declare the relevant information

I have introduced a feature-metadata unstable feature which can be dynamically enabled through cargo-features. However, I realize now that the same cannot be done for the cargo-util-schemas crate (we can only document the FeatureDefinition::Metadata variant as unstable). So, unless there is a way to dynamically feature-gate the change in the schema, and to not cause unnecessary churn to the dependents of cargo-util-schemas, I agree it may be best not to move forward on this PR for now, until other keys are introduced. Future implementations of these could hopefully use this PR as a base.

cargo-util-schemas does not get feature gated. We do that in cargo/utils/toml/mod.rs or later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-documenting-cargo-itself Area: Cargo's documentation A-interacts-with-crates.io Area: interaction with registries A-manifest Area: Cargo.toml issues A-unstable Area: nightly unstable support Command-publish S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants