From b414a915f2484b82593a201c05a5ff69b6a23454 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:38:15 +0100 Subject: [PATCH 1/9] test(feature-metadata): test valid and invalid feature metadata --- tests/testsuite/features.rs | 173 ++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 94a69cc6e11..c4a7611ffcf 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -1,6 +1,9 @@ //! Tests for `[features]` table. +use std::fs::File; + use cargo_test_support::prelude::*; +use cargo_test_support::publish::validate_crate_contents; use cargo_test_support::registry::{Dependency, Package}; use cargo_test_support::str; use cargo_test_support::{basic_manifest, project}; @@ -2282,3 +2285,173 @@ fn invalid_feature_name_slash_error() { "#]]) .run(); } + +#[cargo_test] +fn feature_metadata() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + a = [] + b = [] + c = { enables = ["a", "b"] } + "#, + ) + .file( + "src/main.rs", + r#" + #[cfg(feature = "a")] + fn a() {} + #[cfg(feature = "b")] + fn b() {} + fn main() { + a(); + b(); + } + "#, + ) + .build(); + + p.cargo("check --features c").run(); +} + +#[cargo_test] +fn feature_metadata_missing_enables() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + foo = {} + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] missing field `enables` + --> Cargo.toml:7:23 + | +7 | foo = {} + | ^^ + | + +"#]]) + .run(); +} + +#[cargo_test] +fn unused_keys_in_feature_metadata() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + foo = { enables = ["bar"], foobar = false } + bar = [] + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .with_stderr_data(str![[r#" +[WARNING] unused manifest key: `features.foo.foobar` +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn normalize_feature_metadata() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + a = [] + b = [] + c = { enables = ["a", "b"] } + "#, + ) + .file( + "src/main.rs", + r#" + #[cfg(feature = "a")] + fn a() {} + #[cfg(feature = "b")] + fn b() {} + fn main() { + a(); + b(); + } + "#, + ) + .build(); + + p.cargo("package --no-verify -v").run(); + let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap(); + let normalized_manifest = str![[r#" +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2015" +name = "foo" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +readme = false + +[features] +a = [] +b = [] +c = [ + "a", + "b", +] + +[[bin]] +name = "foo" +path = "src/main.rs" + +"#]]; + validate_crate_contents( + f, + "foo-0.0.0.crate", + &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + [("Cargo.toml", normalized_manifest)], + ); +} From af99addc4cf44114df407d8eb8a4a16a9dde4bc9 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sun, 12 Jan 2025 09:51:18 +0100 Subject: [PATCH 2/9] feat(manifest)!: implement feature-metadata RFC3416 --- crates/cargo-util-schemas/src/manifest/mod.rs | 61 ++++++++++++++++++- src/cargo/ops/registry/publish.rs | 2 +- src/cargo/util/toml/mod.rs | 60 ++++++++++++++---- tests/testsuite/features.rs | 21 ++----- 4 files changed, 112 insertions(+), 32 deletions(-) diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index 906ff3d431f..06f7f881947 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -41,7 +41,7 @@ pub struct TomlManifest { pub package: Option>, pub project: Option>, pub badges: Option>>, - pub features: Option>>, + pub features: Option>, pub lib: Option, pub bin: Option>, pub example: Option>, @@ -110,7 +110,7 @@ impl TomlManifest { .or(self.build_dependencies2.as_ref()) } - pub fn features(&self) -> Option<&BTreeMap>> { + pub fn features(&self) -> Option<&BTreeMap> { self.features.as_ref() } @@ -1521,6 +1521,63 @@ impl TomlPlatform { } } +/// Definition of a feature. +#[derive(Clone, Debug, Serialize)] +#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] +#[serde(untagged)] +pub enum FeatureDefinition { + /// Features that this feature enables. + Array(Vec), + /// Metadata of this feature. + Metadata(FeatureMetadata), +} + +// Implementing `Deserialize` manually allows for a better error message when the `enables` key is +// missing. +impl<'de> de::Deserialize<'de> for FeatureDefinition { + fn deserialize(d: D) -> Result + where + D: de::Deserializer<'de>, + { + UntaggedEnumVisitor::new() + .seq(|seq| { + seq.deserialize::>() + .map(FeatureDefinition::Array) + }) + .map(|seq| { + seq.deserialize::() + .map(FeatureDefinition::Metadata) + }) + .deserialize(d) + } +} + +impl FeatureDefinition { + /// Returns the features that this feature enables. + pub fn enables(&self) -> &[String] { + match self { + Self::Array(features) => features, + Self::Metadata(FeatureMetadata { + enables: features, .. + }) => features, + } + } +} + +/// Metadata of a feature. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] +pub struct FeatureMetadata { + /// Features that this feature enables. + pub enables: Vec, + + /// This is here to provide a way to see the "unused manifest keys" when deserializing + #[serde(skip_serializing)] + #[serde(flatten)] + #[cfg_attr(feature = "unstable-schema", schemars(skip))] + pub _unused_keys: BTreeMap, +} + #[derive(Serialize, Debug, Clone)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] pub struct InheritableLints { diff --git a/src/cargo/ops/registry/publish.rs b/src/cargo/ops/registry/publish.rs index de0f9ac4e0a..5b4d5e01cff 100644 --- a/src/cargo/ops/registry/publish.rs +++ b/src/cargo/ops/registry/publish.rs @@ -539,7 +539,7 @@ pub(crate) fn prepare_transmit( .map(|(feat, values)| { ( feat.to_string(), - values.iter().map(|fv| fv.to_string()).collect(), + values.enables().iter().map(|fv| fv.to_string()).collect(), ) }) .collect::>>(), diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index bc80097b705..0f7074e42c2 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -11,7 +11,8 @@ use anyhow::{anyhow, bail, Context as _}; use cargo_platform::Platform; use cargo_util::paths; use cargo_util_schemas::manifest::{ - self, PackageName, PathBaseName, TomlDependency, TomlDetailedDependency, TomlManifest, + self, FeatureDefinition, FeatureMetadata, FeatureName, PackageName, PathBaseName, + TomlDependency, TomlDetailedDependency, TomlManifest, }; use cargo_util_schemas::manifest::{RustVersion, StringOrBool}; use itertools::Itertools; @@ -708,8 +709,8 @@ fn default_readme_from_package_root(package_root: &Path) -> Option { #[tracing::instrument(skip_all)] fn normalize_features( - original_features: Option<&BTreeMap>>, -) -> CargoResult>>> { + original_features: Option<&BTreeMap>, +) -> CargoResult>> { let Some(normalized_features) = original_features.cloned() else { return Ok(None); }; @@ -1296,6 +1297,8 @@ pub fn to_real_manifest( } } + validate_feature_definitions(original_toml.features.as_ref(), warnings)?; + validate_dependencies(original_toml.dependencies.as_ref(), None, None, warnings)?; validate_dependencies( original_toml.dev_dependencies(), @@ -1497,7 +1500,7 @@ pub fn to_real_manifest( .map(|(k, v)| { ( InternedString::new(k), - v.iter().map(InternedString::from).collect(), + v.enables().iter().map(InternedString::from).collect(), ) }) .collect(), @@ -1764,6 +1767,30 @@ fn to_virtual_manifest( Ok(manifest) } +fn validate_feature_definitions( + features: Option<&BTreeMap>, + warnings: &mut Vec, +) -> CargoResult<()> { + let Some(features) = features else { + return Ok(()); + }; + + for (feature, feature_definition) in features { + match feature_definition { + FeatureDefinition::Array(..) => {} + FeatureDefinition::Metadata(FeatureMetadata { _unused_keys, .. }) => { + warnings.extend( + _unused_keys + .keys() + .map(|k| format!("unused manifest key: `features.{feature}.{k}`")), + ); + } + } + } + + Ok(()) +} + #[tracing::instrument(skip_all)] fn validate_dependencies( original_deps: Option<&BTreeMap>, @@ -2902,16 +2929,23 @@ fn prepare_toml_for_publish( }; features.values_mut().for_each(|feature_deps| { - feature_deps.retain(|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) + 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); }); } diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index c4a7611ffcf..a0636d24a13 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2362,7 +2362,7 @@ fn unused_keys_in_feature_metadata() { edition = "2015" [features] - foo = { enables = ["bar"], foobar = false } + foo = { enables = ["bar"], a = false, b = true } bar = [] "#, ) @@ -2371,7 +2371,8 @@ fn unused_keys_in_feature_metadata() { p.cargo("check") .with_stderr_data(str![[r#" -[WARNING] unused manifest key: `features.foo.foobar` +[WARNING] unused manifest key: `features.foo.a` +[WARNING] unused manifest key: `features.foo.b` [CHECKING] foo v0.0.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -2395,22 +2396,10 @@ fn normalize_feature_metadata() { c = { enables = ["a", "b"] } "#, ) - .file( - "src/main.rs", - r#" - #[cfg(feature = "a")] - fn a() {} - #[cfg(feature = "b")] - fn b() {} - fn main() { - a(); - b(); - } - "#, - ) + .file("src/main.rs", "") .build(); - p.cargo("package --no-verify -v").run(); + p.cargo("package --no-verify").run(); let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap(); let normalized_manifest = str![[r#" # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO From 338281e3a609675a418d6971ffecf5da51a06f84 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:37:30 +0100 Subject: [PATCH 3/9] fixup! feat(manifest)!: implement feature-metadata RFC3416 --- .../cargo-util-schemas/manifest.schema.json | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/crates/cargo-util-schemas/manifest.schema.json b/crates/cargo-util-schemas/manifest.schema.json index 5bc43e49d37..cd45723b17a 100644 --- a/crates/cargo-util-schemas/manifest.schema.json +++ b/crates/cargo-util-schemas/manifest.schema.json @@ -51,10 +51,7 @@ "null" ], "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/$defs/FeatureDefinition" } }, "lib": { @@ -597,6 +594,38 @@ ] }, "TomlValue": true, + "FeatureDefinition": { + "description": "Definition of a feature.", + "anyOf": [ + { + "description": "Features that this feature enables.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "Metadata of this feature.", + "$ref": "#/$defs/FeatureMetadata" + } + ] + }, + "FeatureMetadata": { + "description": "Metadata of a feature.", + "type": "object", + "properties": { + "enables": { + "description": "Features that this feature enables.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "enables" + ] + }, "TomlTarget": { "type": "object", "properties": { From 1cdcd4a9b50b271b5ed78ae03845e96da4855965 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Sun, 12 Jan 2025 20:18:05 +0100 Subject: [PATCH 4/9] fixup! test(feature-metadata): test valid and invalid feature metadata --- tests/testsuite/features.rs | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index a0636d24a13..41d2aecccc9 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2402,27 +2402,9 @@ fn normalize_feature_metadata() { p.cargo("package --no-verify").run(); let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap(); let normalized_manifest = str![[r#" -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. -# -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2015" -name = "foo" -build = false -autolib = false -autobins = false -autoexamples = false -autotests = false -autobenches = false -readme = false +... + +... [features] a = [] @@ -2432,10 +2414,7 @@ c = [ "b", ] -[[bin]] -name = "foo" -path = "src/main.rs" - +... "#]]; validate_crate_contents( f, From d67aee59ebea54cdb693eee7b06232fe04857979 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:53:15 +0100 Subject: [PATCH 5/9] fixup! test(feature-metadata): test valid and invalid feature metadata --- tests/testsuite/features.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 41d2aecccc9..8b2b4ac7337 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2357,13 +2357,14 @@ fn unused_keys_in_feature_metadata() { .file( "Cargo.toml", r#" - [package] - name = "foo" - edition = "2015" - [features] - foo = { enables = ["bar"], a = false, b = true } - bar = [] + [package] + name = "foo" + edition = "2015" + + [features] + foo = { enables = ["bar"], a = false, b = true } + bar = [] "#, ) .file("src/lib.rs", "") From 567a1042c2cb8f044d53159719ed3aa99a4dc599 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:07:46 +0100 Subject: [PATCH 6/9] feat(feature-metadata): feature-gate the unstable feature --- src/cargo/core/features.rs | 3 ++ src/cargo/util/toml/mod.rs | 4 ++- src/doc/src/reference/unstable.md | 16 +++++++++ tests/testsuite/features.rs | 56 ++++++++++++++++++++++++++++--- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 4e17898d6e0..ed8ba617369 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -519,6 +519,9 @@ features! { /// Allow paths that resolve relatively to a base specified in the config. (unstable, path_bases, "", "reference/unstable.html#path-bases"), + + /// Allow to use a table for defining features. + (unstable, feature_metadata, "", "reference/unstable.html#feature_metadata"), } /// Status and metadata for a single unstable feature. diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 0f7074e42c2..92164a680e8 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -1297,7 +1297,7 @@ pub fn to_real_manifest( } } - validate_feature_definitions(original_toml.features.as_ref(), warnings)?; + validate_feature_definitions(&features, original_toml.features.as_ref(), warnings)?; validate_dependencies(original_toml.dependencies.as_ref(), None, None, warnings)?; validate_dependencies( @@ -1768,6 +1768,7 @@ fn to_virtual_manifest( } fn validate_feature_definitions( + cargo_features: &Features, features: Option<&BTreeMap>, warnings: &mut Vec, ) -> CargoResult<()> { @@ -1779,6 +1780,7 @@ fn validate_feature_definitions( match feature_definition { FeatureDefinition::Array(..) => {} FeatureDefinition::Metadata(FeatureMetadata { _unused_keys, .. }) => { + cargo_features.require(Feature::feature_metadata())?; warnings.extend( _unused_keys .keys() diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 3eba4e45804..44e3a5fc13c 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -103,6 +103,7 @@ Each new feature described below should explain how to use it. * [Profile `trim-paths` option](#profile-trim-paths-option) --- Control the sanitization of file paths in build outputs. * [`[lints.cargo]`](#lintscargo) --- Allows configuring lints for Cargo. * [path bases](#path-bases) --- Named base directories for path dependencies. + * [feature-metadata](#feature-metadata) --- Table syntax for feature definitions. * Information and metadata * [Build-plan](#build-plan) --- Emits JSON information on which commands will be run. * [unit-graph](#unit-graph) --- Emits JSON for Cargo's internal graph structure. @@ -1619,6 +1620,21 @@ will prefer the value in the configuration. The allows Cargo to add new built-in path bases without compatibility issues (as existing uses will shadow the built-in name). +## feature-metadata + +* Tracking Issue: [#14157](https://github.com/rust-lang/cargo/issues/14157) + +This allows to use a table when defining features, with a required `enables` key: + +```toml +[features] +# same as `foo = []` +foo = { enables = [] } +``` + +This is equivalent to the array-of-strings syntax. +Support for other keys should be added later. + ## lockfile-path * Original Issue: [#5707](https://github.com/rust-lang/cargo/issues/5707) * Tracking Issue: [#14421](https://github.com/rust-lang/cargo/issues/14421) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 8b2b4ac7337..10f7dff818e 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2292,6 +2292,8 @@ fn feature_metadata() { .file( "Cargo.toml", r#" + cargo-features = ["feature-metadata"] + [package] name = "foo" edition = "2015" @@ -2317,7 +2319,42 @@ fn feature_metadata() { ) .build(); - p.cargo("check --features c").run(); + p.cargo("check --features c") + .masquerade_as_nightly_cargo(&[]) + .run(); +} + +#[cargo_test] +fn feature_metadata_is_unstable() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + a = { enables = [] } + "#, + ) + .file("src/main.rs", "") + .build(); + + p.cargo("check --features a") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` + +Caused by: + feature `feature-metadata` is required + + The package requires the Cargo feature called `feature-metadata`, but that feature is not stabilized in this version of Cargo ([..]). + Consider trying a newer version of Cargo (this may require the nightly release). + See https://doc.rust-lang.org/nightly/cargo/ for more information about the status of this feature. + +"#]]) + .run(); } #[cargo_test] @@ -2326,6 +2363,8 @@ fn feature_metadata_missing_enables() { .file( "Cargo.toml", r#" + cargo-features = ["feature-metadata"] + [package] name = "foo" edition = "2015" @@ -2338,12 +2377,13 @@ fn feature_metadata_missing_enables() { .build(); p.cargo("check") + .masquerade_as_nightly_cargo(&[]) .with_status(101) .with_stderr_data(str![[r#" [ERROR] missing field `enables` - --> Cargo.toml:7:23 + --> Cargo.toml:[..]:23 | -7 | foo = {} +[..] | foo = {} | ^^ | @@ -2357,6 +2397,7 @@ fn unused_keys_in_feature_metadata() { .file( "Cargo.toml", r#" + cargo-features = ["feature-metadata"] [package] name = "foo" @@ -2371,6 +2412,7 @@ fn unused_keys_in_feature_metadata() { .build(); p.cargo("check") + .masquerade_as_nightly_cargo(&[]) .with_stderr_data(str![[r#" [WARNING] unused manifest key: `features.foo.a` [WARNING] unused manifest key: `features.foo.b` @@ -2387,6 +2429,8 @@ fn normalize_feature_metadata() { .file( "Cargo.toml", r#" + cargo-features = ["feature-metadata"] + [package] name = "foo" edition = "2015" @@ -2400,13 +2444,17 @@ fn normalize_feature_metadata() { .file("src/main.rs", "") .build(); - p.cargo("package --no-verify").run(); + p.cargo("package --no-verify") + .masquerade_as_nightly_cargo(&[]) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap(); let normalized_manifest = str![[r#" ... ... +... + [features] a = [] b = [] From d61ffb50613e29985e0056da63594fd42fbc2f68 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:29:27 +0100 Subject: [PATCH 7/9] fixup! feat(manifest)!: implement feature-metadata RFC3416 --- crates/cargo-util-schemas/src/manifest/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index 06f7f881947..a0fc160abb0 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -1528,7 +1528,7 @@ impl TomlPlatform { pub enum FeatureDefinition { /// Features that this feature enables. Array(Vec), - /// Metadata of this feature. + /// Unstable feature `feature-metadata`. Metadata of this feature. Metadata(FeatureMetadata), } @@ -1564,7 +1564,7 @@ impl FeatureDefinition { } } -/// Metadata of a feature. +/// Unstable feature `feature-metadata`. Metadata of a feature. #[derive(Clone, Debug, Deserialize, Serialize)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] pub struct FeatureMetadata { From 2faf5e03192191070da962494ba3b359af32fd80 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Mon, 13 Jan 2025 22:51:39 +0100 Subject: [PATCH 8/9] fixup! feat(manifest)!: implement feature-metadata RFC3416 --- crates/cargo-util-schemas/manifest.schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cargo-util-schemas/manifest.schema.json b/crates/cargo-util-schemas/manifest.schema.json index cd45723b17a..d5a7e16c8de 100644 --- a/crates/cargo-util-schemas/manifest.schema.json +++ b/crates/cargo-util-schemas/manifest.schema.json @@ -605,13 +605,13 @@ } }, { - "description": "Metadata of this feature.", + "description": "Unstable feature `feature-metadata`. Metadata of this feature.", "$ref": "#/$defs/FeatureMetadata" } ] }, "FeatureMetadata": { - "description": "Metadata of a feature.", + "description": "Unstable feature `feature-metadata`. Metadata of a feature.", "type": "object", "properties": { "enables": { From 905820c63998157b63f60e5dc5ef620a9b163558 Mon Sep 17 00:00:00 2001 From: AudaciousAxiom <179637270+AudaciousAxiom@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:20:06 +0100 Subject: [PATCH 9/9] fixup! feat(feature-metadata): feature-gate the unstable feature --- tests/testsuite/features.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 10f7dff818e..21a10fe5f29 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2351,7 +2351,7 @@ Caused by: The package requires the Cargo feature called `feature-metadata`, but that feature is not stabilized in this version of Cargo ([..]). Consider trying a newer version of Cargo (this may require the nightly release). - See https://doc.rust-lang.org/nightly/cargo/ for more information about the status of this feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#feature_metadata for more information about the status of this feature. "#]]) .run();