From 4b1c9100d06625d94b287e46fd58cb72c90f46d7 Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 12 Sep 2025 15:23:09 +0100 Subject: [PATCH] RFC for `#[stable(since)]` --- text/0000-stable_since.md | 81 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 text/0000-stable_since.md diff --git a/text/0000-stable_since.md b/text/0000-stable_since.md new file mode 100644 index 00000000000..d167ea9e243 --- /dev/null +++ b/text/0000-stable_since.md @@ -0,0 +1,81 @@ +- Feature Name: stable_since +- Start Date: 2025-09-12 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#74182](https://github.com/rust-lang/rust/issues/74182) + +# Summary +[summary]: #summary + +Allow crates to specify `#[stable(since = "version")]` on items for Rustdoc to render the information. + +# Motivation +[motivation]: #motivation + +This functionality is already implemented for the standard library. Other crates also expand their public API over time, and it would be helpful to inform users about the minimum crate version required for each item. + +It's possible to automatically infer in which version each item has been added by comparing public APIs of crates' public releases, but this is too expensive and complicated to perform each time when generating documentation. The `#[stable(since)]` attribute behaves like a first-class cache for this information for `rustdoc` and other tools. + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +When added to an item, it specifies in which version of the crate this item has been added: + +```rust +#[stable(since = "2.25.0")] +pub fn add_trombone_emoji() {} +``` + +Rustdoc will include the version in the documentation of the item, with a description such as "stable since $crate_name version 2.25.0". + +To ease development of unreleased features, there is no restriction on the version range, and it may refer to a future not-yet-released version. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +The `version` must parse as SemVer. It refers to a version of the crate that defines the item this attribute belongs to. + +`rustc` doesn't need to be made aware of crates' versions, because there's no restriction on the version range. + +`rustdoc` should not display the attribute on items re-exported from other crates. + +# Drawbacks +[drawbacks]: #drawbacks + +This attribute may be incorrect if added manually. It may be confused with rustc version compatibility. + +It specifies only a single version per item, which may not be enough to fully explain availability of items that are available conditionally or under different paths. + +Versions on re-exported items are not relevant for the crate re-exporting them, because it matters when the re-export has been added. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- The entire `#[stable(feature)]`/`#[unstable(feature)]` functionality could be stabilized for 3rd party crates +- API stability could be stored outside of the source code, e.g. in a file similar to `rustdoc`'s JSON +- It could be shortened to `#[since("version")]` +- It could be expanded to `#[stable(added = "version", changed = "version", rust_version = "msrv")]` + +# Prior art +[prior-art]: #prior-art + +The `#[stable(since = "version")]` attribute is a subset of standard library's `#[stable(feature, since)]`, but to keep the scope small, this RFC does not include support for feature flags nor unstable APIs outside of the standard library. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +Should crates reset the `version` when making semver-breaking changes to the item? + +Should the `version` allow a placeholder value like `UNRELEASED`? + +Is it clear enough that the version is the crate's own version and not the minimum requierd Rust version? + +How to support items re-exported from other crates? Could `use` support overriding `#[stable(since)]`? + +# Future possibilities +[future-possibilities]: #future-possibilities + +The entire `#[stable(feature)]`/`#[unstable(feature)]` functionality could be stabilized for 3rd party crates. + +Tools like rust-analyzer or clippy could help users bump versions in `Cargo.toml` when their crate uses items from a newer version of a dependency than the minimum version specified in `Cargo.toml`. + +These attributes could be automatically generated by tools like `cargo-public-api` or `cargo-semver-checks`.