@@ -53,22 +53,37 @@ 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-callls 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+ ** Adding this attribute to an intrinsic requires t-lang and wg-const-eval approval!**
7287
7388## rustc_default_body_unstable
7489
@@ -89,8 +104,9 @@ To stabilize a feature, follow these steps:
891042 . Change ` #[unstable(...)] ` to ` #[stable(since = "CURRENT_RUSTC_VERSION")] ` .
901053 . Remove ` #![feature(...)] ` from any test or doc-test for this API. If the feature is used in the
91106 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")] ` .
107+ 4 . If this is a ` const fn ` , add ` #[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")] ` .
108+ Alternatively, if this is not supposed to be const-stabilized yet,
109+ add ` #[rustc_const_unstable(...)] ` for some new feature gate (with a new tracking issue).
941105 . Open a PR against ` rust-lang/rust ` .
95111 - Add the appropriate labels: ` @rustbot modify labels: +T-libs-api ` .
96112 - Link to the tracking issue and say "Closes #XXXXX".
@@ -107,27 +123,30 @@ site. To work around not being able to use unstable things in the standard
107123library's macros, there's the ` #[allow_internal_unstable(feature1, feature2)] `
108124attribute that allows the given features to be used in stable macros.
109125
126+ Note that if a macro is used in const context and generates a call to a
127+ ` #[rustc_const_unstable(...)] ` function, that will * still* be rejected even with
128+ ` allow_internal_unstable ` . Add ` #[rustc_const_stable_indirect] ` to the function to ensure the macro
129+ cannot accidentally bypass the recursive const stability checks.
130+
110131## rustc_allow_const_fn_unstable
111132
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 ` .
133+ As explained above, no unstable const features are allowed inside stable ` const fn ` , not even
134+ indirectly.
116135
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 ` .
136+ However, sometimes we do know that a feature will get stabilized, just not when, or there is a
137+ stable (but e.g. runtime-slow) workaround, so we could always fall back to some stable version if we
138+ scrapped the unstable feature. In those cases, the ` [ rustc_allow_const_fn_unstable(feature1,
139+ feature2) ] ` attribute can be used to allow some unstable features in the body of a stable (or
140+ indirectly stable) ` const fn ` .
122141
123142You also need to take care to uphold the ` const fn ` invariant that calling it at runtime and
124143compile-time needs to behave the same (see also [ this blog post] [ blog ] ). This means that you
125144may not create a ` const fn ` that e.g. transmutes a memory address to an integer,
126145because the addresses of things are nondeterministic and often unknown at
127146compile-time.
128147
129- Always ping @rust-lang/wg-const-eval if you are adding more
130- ` rustc_allow_const_fn_unstable ` attributes to any ` const fn ` .
148+ ** Always ping @rust-lang/wg-const-eval if you are adding more
149+ ` rustc_allow_const_fn_unstable ` attributes to any ` const fn ` .**
131150
132151## staged_api
133152
0 commit comments