Skip to content

Commit c31d23b

Browse files
authored
update const stability docs (rust-lang#2098)
1 parent 7f82658 commit c31d23b

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

Diff for: src/stability.md

+42-22
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,38 @@ marks an item as stabilized. Note that stable functions may use unstable things
5353

5454
The `#[rustc_const_unstable(feature = "foo", issue = "1234", reason = "lorem
5555
ipsum")]` has the same interface as the `unstable` attribute. It is used to mark
56-
`const fn` as having their constness be unstable. Every `const fn` with
57-
stability attributes should carry either this attribute or
58-
`#[rustc_const_stable]` (see below).
56+
`const fn` as having their constness be unstable. This is only needed in rare cases:
57+
- If a `const fn` makes use of unstable language features or intrinsics.
58+
(The compiler will tell you to add the attribute if you run into this.)
59+
- If a `const fn` is `#[stable]` but not yet intended to be const-stable.
5960

60-
Furthermore this attribute is needed to mark an intrinsic as `const fn`, because
61+
Furthermore, this attribute is needed to mark an intrinsic as an *unstable* `const fn`, because
6162
there's no way to add `const` to functions in `extern` blocks for now.
6263

64+
Const-stability differs from regular stability in that it is *recursive*: a
65+
`#[rustc_const_unstable(...)]` function cannot even be indirectly called from stable code. This is
66+
to avoid accidentally leaking unstable compiler implementation artifacts to stable code or locking
67+
us into the accidental quirks of an incomplete implementation. See the rustc_const_stable_indirect
68+
and rustc_allow_const_fn_unstable attributes below for how to fine-tune this check.
69+
6370
## rustc_const_stable
6471

6572
The `#[rustc_const_stable(feature = "foo", since = "1.420.69")]` attribute explicitly marks
66-
a `const fn` as having its constness be `stable`. This attribute can make sense
67-
even on an `unstable` function, if that function is called from another
68-
`rustc_const_stable` function.
73+
a `const fn` as having its constness be `stable`.
74+
75+
## rustc_const_stable_indirect
76+
77+
The `#[rustc_const_stable_indirect]` attribute can be added to a `#[rustc_const_unstable(...)]`
78+
function to make it callable from `#[rustc_const_stable(...)]` functions. This indicates that the
79+
function is ready for stable in terms of its implementation (i.e., it doesn't use any unstable
80+
compiler features); the only reason it is not const-stable yet are API concerns.
6981

70-
Furthermore this attribute is needed to mark an intrinsic as callable from
71-
`rustc_const_stable` functions.
82+
This should also be added to lang items for which const-calls are synthesized in the compiler, to
83+
ensure those calls do not bypass recursive const stability rules.
84+
85+
On an intrinsic, this attribute marks the intrinsic as "ready to be used by public stable functions".
86+
The `rustc_const_unstable` can be removed when this attribute is added.
87+
**Adding this attribute to an intrinsic requires t-lang and wg-const-eval approval!**
7288

7389
## rustc_default_body_unstable
7490

@@ -89,8 +105,9 @@ To stabilize a feature, follow these steps:
89105
2. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`.
90106
3. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the
91107
compiler or tools, remove it from there as well.
92-
4. If applicable, change `#[rustc_const_unstable(...)]` to
93-
`#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`.
108+
4. If this is a `const fn`, add `#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`.
109+
Alternatively, if this is not supposed to be const-stabilized yet,
110+
add `#[rustc_const_unstable(...)]` for some new feature gate (with a new tracking issue).
94111
5. Open a PR against `rust-lang/rust`.
95112
- Add the appropriate labels: `@rustbot modify labels: +T-libs-api`.
96113
- Link to the tracking issue and say "Closes #XXXXX".
@@ -107,27 +124,30 @@ site. To work around not being able to use unstable things in the standard
107124
library's macros, there's the `#[allow_internal_unstable(feature1, feature2)]`
108125
attribute that allows the given features to be used in stable macros.
109126

127+
Note that if a macro is used in const context and generates a call to a
128+
`#[rustc_const_unstable(...)]` function, that will *still* be rejected even with
129+
`allow_internal_unstable`. Add `#[rustc_const_stable_indirect]` to the function to ensure the macro
130+
cannot accidentally bypass the recursive const stability checks.
131+
110132
## rustc_allow_const_fn_unstable
111133

112-
`const fn`, while not directly exposing their body to the world, are going to get
113-
evaluated at compile time in stable crates. If their body does something const-unstable,
114-
that could lock us into certain features indefinitely by accident. Thus no unstable const
115-
features are allowed inside stable `const fn`.
134+
As explained above, no unstable const features are allowed inside stable `const fn`, not even
135+
indirectly.
116136

117-
However, sometimes we do know that a feature will get
118-
stabilized, just not when, or there is a stable (but e.g. runtime-slow) workaround, so we
119-
could always fall back to some stable version if we scrapped the unstable feature.
120-
In those cases, the rustc_allow_const_fn_unstable attribute can be used to allow some
121-
unstable features in the body of a stable `const fn`.
137+
However, sometimes we do know that a feature will get stabilized, just not when, or there is a
138+
stable (but e.g. runtime-slow) workaround, so we could always fall back to some stable version if we
139+
scrapped the unstable feature. In those cases, the `[rustc_allow_const_fn_unstable(feature1,
140+
feature2)]` attribute can be used to allow some unstable features in the body of a stable (or
141+
indirectly stable) `const fn`.
122142

123143
You also need to take care to uphold the `const fn` invariant that calling it at runtime and
124144
compile-time needs to behave the same (see also [this blog post][blog]). This means that you
125145
may not create a `const fn` that e.g. transmutes a memory address to an integer,
126146
because the addresses of things are nondeterministic and often unknown at
127147
compile-time.
128148

129-
Always ping @rust-lang/wg-const-eval if you are adding more
130-
`rustc_allow_const_fn_unstable` attributes to any `const fn`.
149+
**Always ping @rust-lang/wg-const-eval if you are adding more
150+
`rustc_allow_const_fn_unstable` attributes to any `const fn`.**
131151

132152
## staged_api
133153

0 commit comments

Comments
 (0)