diff --git a/crates/cargo-util-schemas/manifest.schema.json b/crates/cargo-util-schemas/manifest.schema.json index 60eb5434b76..664fc48aa1e 100644 --- a/crates/cargo-util-schemas/manifest.schema.json +++ b/crates/cargo-util-schemas/manifest.schema.json @@ -649,6 +649,13 @@ "items": { "type": "string" } + }, + "doc": { + "description": "Documentation for the feature.", + "type": [ + "string", + "null" + ] } }, "required": [ diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index a51ac3ef7fc..1ca28b70e73 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -1520,6 +1520,9 @@ pub struct FeatureMetadata { /// Features that this feature enables. pub enables: Vec, + /// Documentation for the feature. + pub doc: Option, + /// This is here to provide a way to see the "unused manifest keys" when deserializing #[serde(skip_serializing)] #[serde(flatten)] diff --git a/doc/book/src/reference/unstable.md b/doc/book/src/reference/unstable.md index e9989e951d7..6a36842ce50 100644 --- a/doc/book/src/reference/unstable.md +++ b/doc/book/src/reference/unstable.md @@ -2396,6 +2396,26 @@ foo = { enables = [] } This is equivalent to the array-of-strings syntax. Support for other keys should be added later. +### feature-documentation + +* Tracking Issue: [#17445](https://github.com/rust-lang/cargo/issues/17445) +* RFC: [#3485](https://github.com/rust-lang/rfcs/blob/master/text/3485-feature-documentation.md) + +This allows providing documentation for the feature inside the table introduced by +[`feature-metadata`](#feature-metadata): + +```toml +[features.serde] +enables = [] +doc = "Enables support for serialization and deserialization via serde." +``` + +The documentation can be consumed and displayed by tools. +It can be a multi-line TOML string, contain multiple paragraphs, and use Markdown markup, +similarly to Rust doc comments. +Tools may only display the first paragraph in some contexts, which should therefore be +relatively short and make sense without the rest of the description. + ## lockfile-path Support for `resolver.lockfile-path` config field has been stabilized in Rust 1.97.0. diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index ee57f1260ce..8af120a460f 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -2681,3 +2681,65 @@ c = [ [("Cargo.toml", normalized_manifest)], ); } + +#[cargo_test] +fn feature_documentation_is_unstable() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2015" + + [features] + foo = { enables = [], doc = "Enables foo." } + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("check") + .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/reference/unstable.html#feature_metadata for more information about the status of this feature. + +"#]]) + .run(); +} + +#[cargo_test] +fn feature_has_documentation() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["feature-metadata"] + + [package] + name = "foo" + edition = "2015" + + [features] + foo = { enables = [], doc = "Enables foo." } + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("check") + .masquerade_as_nightly_cargo(&["feature-metadata"]) + .with_stderr_data(str![[r#" +[CHECKING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +}