@@ -53,22 +53,38 @@ marks an item as stabilized. Note that stable functions may use unstable things
5353
5454The `#[ rustc_const_unstable(feature = "foo", issue = "1234", reason = "lorem
5555ipsum")] ` 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
6162there'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
6572The ` #[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:
891052 . Change ` #[unstable(...)] ` to ` #[stable(since = "CURRENT_RUSTC_VERSION")] ` .
901063 . 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).
941115 . 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
107124library's macros, there's the ` #[allow_internal_unstable(feature1, feature2)] `
108125attribute 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
123143You also need to take care to uphold the ` const fn ` invariant that calling it at runtime and
124144compile-time needs to behave the same (see also [ this blog post] [ blog ] ). This means that you
125145may not create a ` const fn ` that e.g. transmutes a memory address to an integer,
126146because the addresses of things are nondeterministic and often unknown at
127147compile-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