mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
sembr src/stability.md
This commit is contained in:
@@ -3,31 +3,36 @@
|
||||
This section is about the stability attributes and schemes that allow stable
|
||||
APIs to use unstable APIs internally in the rustc standard library.
|
||||
|
||||
**NOTE**: this section is for *library* features, not *language* features. For instructions on
|
||||
**NOTE**: this section is for *library* features, not *language* features.
|
||||
For instructions on
|
||||
stabilizing a language feature see [Stabilizing Features](./stabilization-guide.md).
|
||||
|
||||
## unstable
|
||||
|
||||
The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]`
|
||||
attribute explicitly marks an item as unstable. Items that are marked as
|
||||
attribute explicitly marks an item as unstable.
|
||||
Items that are marked as
|
||||
"unstable" cannot be used without a corresponding `#![feature]` attribute on
|
||||
the crate, even on a nightly compiler. This restriction only applies across
|
||||
crate boundaries, unstable items may be used within the crate that defines
|
||||
them.
|
||||
the crate, even on a nightly compiler.
|
||||
This restriction only applies across
|
||||
crate boundaries, unstable items may be used within the crate that defines them.
|
||||
|
||||
The `issue` field specifies the associated GitHub [issue number]. This field is
|
||||
required and all unstable features should have an associated tracking issue. In
|
||||
rare cases where there is no sensible value `issue = "none"` is used.
|
||||
The `issue` field specifies the associated GitHub [issue number].
|
||||
This field is
|
||||
required and all unstable features should have an associated tracking issue.
|
||||
In rare cases where there is no sensible value `issue = "none"` is used.
|
||||
|
||||
The `unstable` attribute infects all sub-items, where the attribute doesn't
|
||||
have to be reapplied. So if you apply this to a module, all items in the module
|
||||
will be unstable.
|
||||
have to be reapplied.
|
||||
So if you apply this to a module, all items in the module will be unstable.
|
||||
|
||||
If you rename a feature, you can add `old_name = "old_name"` to produce a
|
||||
useful error message.
|
||||
|
||||
You can make specific sub-items stable by using the `#[stable]` attribute on
|
||||
them. The stability scheme works similarly to how `pub` works. You can have
|
||||
them.
|
||||
The stability scheme works similarly to how `pub` works.
|
||||
You can have
|
||||
public functions of nonpublic modules and you can have stable functions in
|
||||
unstable modules or vice versa.
|
||||
|
||||
@@ -35,13 +40,15 @@ Previously, due to a [rustc bug], stable items inside unstable modules were
|
||||
available to stable code in that location.
|
||||
As of <!-- date-check --> September 2024, items with [accidentally stabilized
|
||||
paths] are marked with the `#[rustc_allowed_through_unstable_modules]` attribute
|
||||
to prevent code dependent on those paths from breaking. Do *not* add this attribute
|
||||
to prevent code dependent on those paths from breaking.
|
||||
Do *not* add this attribute
|
||||
to any more items unless that is needed to avoid breaking changes.
|
||||
|
||||
The `unstable` attribute may also have the `soft` value, which makes it a
|
||||
future-incompatible deny-by-default lint instead of a hard error. This is used
|
||||
by the `bench` attribute which was accidentally accepted in the past. This
|
||||
prevents breaking dependencies by leveraging Cargo's lint capping.
|
||||
future-incompatible deny-by-default lint instead of a hard error.
|
||||
This is used
|
||||
by the `bench` attribute which was accidentally accepted in the past.
|
||||
This prevents breaking dependencies by leveraging Cargo's lint capping.
|
||||
|
||||
[issue number]: https://github.com/rust-lang/rust/issues
|
||||
[rustc bug]: https://github.com/rust-lang/rust/issues/15702
|
||||
@@ -49,22 +56,26 @@ prevents breaking dependencies by leveraging Cargo's lint capping.
|
||||
|
||||
## stable
|
||||
The `#[stable(feature = "foo", since = "1.420.69")]` attribute explicitly
|
||||
marks an item as stabilized. Note that stable functions may use unstable things in their body.
|
||||
marks an item as stabilized.
|
||||
Note that stable functions may use unstable things in their body.
|
||||
|
||||
## rustc_const_unstable
|
||||
|
||||
The `#[rustc_const_unstable(feature = "foo", issue = "1234", reason = "lorem
|
||||
ipsum")]` has the same interface as the `unstable` attribute. It is used to mark
|
||||
`const fn` as having their constness be unstable. This is only needed in rare cases:
|
||||
ipsum")]` has the same interface as the `unstable` attribute.
|
||||
It is used to mark `const fn` as having their constness be unstable.
|
||||
This is only needed in rare cases:
|
||||
- If a `const fn` makes use of unstable language features or intrinsics.
|
||||
(The compiler will tell you to add the attribute if you run into this.)
|
||||
- If a `const fn` is `#[stable]` but not yet intended to be const-stable.
|
||||
- To change the feature gate that is required to call a const-unstable intrinsic.
|
||||
|
||||
Const-stability differs from regular stability in that it is *recursive*: a
|
||||
`#[rustc_const_unstable(...)]` function cannot even be indirectly called from stable code. This is
|
||||
`#[rustc_const_unstable(...)]` function cannot even be indirectly called from stable code.
|
||||
This is
|
||||
to avoid accidentally leaking unstable compiler implementation artifacts to stable code or locking
|
||||
us into the accidental quirks of an incomplete implementation. See the rustc_const_stable_indirect
|
||||
us into the accidental quirks of an incomplete implementation.
|
||||
See the rustc_const_stable_indirect
|
||||
and rustc_allow_const_fn_unstable attributes below for how to fine-tune this check.
|
||||
|
||||
## rustc_const_stable
|
||||
@@ -75,7 +86,8 @@ a `const fn` as having its constness be `stable`.
|
||||
## rustc_const_stable_indirect
|
||||
|
||||
The `#[rustc_const_stable_indirect]` attribute can be added to a `#[rustc_const_unstable(...)]`
|
||||
function to make it callable from `#[rustc_const_stable(...)]` functions. This indicates that the
|
||||
function to make it callable from `#[rustc_const_stable(...)]` functions.
|
||||
This indicates that the
|
||||
function is ready for stable in terms of its implementation (i.e., it doesn't use any unstable
|
||||
compiler features); the only reason it is not const-stable yet are API concerns.
|
||||
|
||||
@@ -105,7 +117,8 @@ To stabilize a feature, follow these steps:
|
||||
1. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for
|
||||
the FCP to complete (with `disposition-merge`).
|
||||
2. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`.
|
||||
3. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the
|
||||
3. Remove `#![feature(...)]` from any test or doc-test for this API.
|
||||
If the feature is used in the
|
||||
compiler or tools, remove it from there as well.
|
||||
4. If this is a `const fn`, add `#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`.
|
||||
Alternatively, if this is not supposed to be const-stabilized yet,
|
||||
@@ -121,14 +134,15 @@ and the associated
|
||||
|
||||
## allow_internal_unstable
|
||||
|
||||
Macros and compiler desugarings expose their bodies to the call
|
||||
site. To work around not being able to use unstable things in the standard
|
||||
Macros and compiler desugarings expose their bodies to the call site.
|
||||
To work around not being able to use unstable things in the standard
|
||||
library's macros, there's the `#[allow_internal_unstable(feature1, feature2)]`
|
||||
attribute that allows the given features to be used in stable macros.
|
||||
|
||||
Note that if a macro is used in const context and generates a call to a
|
||||
`#[rustc_const_unstable(...)]` function, that will *still* be rejected even with
|
||||
`allow_internal_unstable`. Add `#[rustc_const_stable_indirect]` to the function to ensure the macro
|
||||
`allow_internal_unstable`.
|
||||
Add `#[rustc_const_stable_indirect]` to the function to ensure the macro
|
||||
cannot accidentally bypass the recursive const stability checks.
|
||||
|
||||
## rustc_allow_const_fn_unstable
|
||||
@@ -138,12 +152,14 @@ indirectly.
|
||||
|
||||
However, sometimes we do know that a feature will get stabilized, just not when, or there is a
|
||||
stable (but e.g. runtime-slow) workaround, so we could always fall back to some stable version if we
|
||||
scrapped the unstable feature. In those cases, the `[rustc_allow_const_fn_unstable(feature1,
|
||||
scrapped the unstable feature.
|
||||
In those cases, the `[rustc_allow_const_fn_unstable(feature1,
|
||||
feature2)]` attribute can be used to allow some unstable features in the body of a stable (or
|
||||
indirectly stable) `const fn`.
|
||||
|
||||
You also need to take care to uphold the `const fn` invariant that calling it at runtime and
|
||||
compile-time needs to behave the same (see also [this blog post][blog]). This means that you
|
||||
compile-time needs to behave the same (see also [this blog post][blog]).
|
||||
This means that you
|
||||
may not create a `const fn` that e.g. transmutes a memory address to an integer,
|
||||
because the addresses of things are nondeterministic and often unknown at
|
||||
compile-time.
|
||||
@@ -159,7 +175,8 @@ Any crate that uses the `stable` or `unstable` attributes must include the
|
||||
## deprecated
|
||||
|
||||
Deprecations in the standard library are nearly identical to deprecations in
|
||||
user code. When `#[deprecated]` is used on an item, it must also have a `stable`
|
||||
user code.
|
||||
When `#[deprecated]` is used on an item, it must also have a `stable`
|
||||
or `unstable `attribute.
|
||||
|
||||
`deprecated` has the following form:
|
||||
@@ -172,20 +189,26 @@ or `unstable `attribute.
|
||||
)]
|
||||
```
|
||||
|
||||
The `suggestion` field is optional. If given, it should be a string that can be
|
||||
used as a machine-applicable suggestion to correct the warning. This is
|
||||
The `suggestion` field is optional.
|
||||
If given, it should be a string that can be
|
||||
used as a machine-applicable suggestion to correct the warning.
|
||||
This is
|
||||
typically used when the identifier is renamed, but no other significant changes
|
||||
are necessary. When the `suggestion` field is used, you need to have
|
||||
are necessary.
|
||||
When the `suggestion` field is used, you need to have
|
||||
`#![feature(deprecated_suggestion)]` at the crate root.
|
||||
|
||||
Another difference from user code is that the `since` field is actually checked
|
||||
against the current version of `rustc`. If `since` is in a future version, then
|
||||
against the current version of `rustc`.
|
||||
If `since` is in a future version, then
|
||||
the `deprecated_in_future` lint is triggered which is default `allow`, but most
|
||||
of the standard library raises it to a warning with
|
||||
`#![warn(deprecated_in_future)]`.
|
||||
|
||||
## unstable_feature_bound
|
||||
The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable. In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`. Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate.
|
||||
The `#[unstable_feature_bound(foo)]` attribute can be used together with `#[unstable]` attribute to mark an `impl` of stable type and stable trait as unstable.
|
||||
In std/core, an item annotated with `#[unstable_feature_bound(foo)]` can only be used by another item that is also annotated with `#[unstable_feature_bound(foo)]`.
|
||||
Outside of std/core, using an item with `#[unstable_feature_bound(foo)]` requires the feature to be enabled with `#![feature(foo)]` attribute on the crate.
|
||||
|
||||
Currently, the items that can be annotated with `#[unstable_feature_bound]` are:
|
||||
- `impl`
|
||||
@@ -193,7 +216,8 @@ Currently, the items that can be annotated with `#[unstable_feature_bound]` are:
|
||||
- trait
|
||||
|
||||
## renamed and removed features
|
||||
Unstable features can get renamed and removed. If you rename a feature, you can add `old_name = "old_name"` to the `#[unstable]` attribute.
|
||||
Unstable features can get renamed and removed.
|
||||
If you rename a feature, you can add `old_name = "old_name"` to the `#[unstable]` attribute.
|
||||
If you remove a feature, the `#!unstable_removed(feature = "foo", reason = "brief description", link = "link", since = "1.90.0")`
|
||||
attribute should be used to produce a good error message for users of the removed feature.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user