]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-dev-guide/src/stability.md
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / src / stability.md
1 # Stability attributes
2
3 <!-- toc -->
4
5 This section is about the stability attributes and schemes that allow stable
6 APIs to use unstable APIs internally in the rustc standard library.
7
8 For instructions on stabilizing a language feature see [Stabilizing
9 Features](./stabilization_guide.md).
10
11 ## unstable
12
13 The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]`
14 attribute explicitly marks an item as unstable. Items that are marked as
15 "unstable" cannot be used without a corresponding `#![feature]` attribute on
16 the crate, even on a nightly compiler. This restriction only applies across
17 crate boundaries, unstable items may be used within the crate that defines
18 them.
19
20 The `issue` field specifies the associated GitHub [issue number]. This field is
21 required and all unstable features should have an associated tracking issue. In
22 rare cases where there is no sensible value `issue = "none"` is used.
23
24 The `unstable` attribute infects all sub-items, where the attribute doesn't
25 have to be reapplied. So if you apply this to a module, all items in the module
26 will be unstable.
27
28 You can make specific sub-items stable by using the `#[stable]` attribute on
29 them. The stability scheme works similarly to how `pub` works. You can have
30 public functions of nonpublic modules and you can have stable functions in
31 unstable modules or vice versa.
32
33 Note, however, that due to a [rustc bug], stable items inside unstable modules
34 *are* available to stable code in that location! So, for example, stable code
35 can import `core::intrinsics::transmute` even though `intrinsics` is an
36 unstable module. Thus, this kind of nesting should be avoided when possible.
37
38 The `unstable` attribute may also have the `soft` value, which makes it a
39 future-incompatible deny-by-default lint instead of a hard error. This is used
40 by the `bench` attribute which was accidentally accepted in the past. This
41 prevents breaking dependencies by leveraging Cargo's lint capping.
42
43 [issue number]: https://github.com/rust-lang/rust/issues
44 [rustc bug]: https://github.com/rust-lang/rust/issues/15702
45
46 ## stable
47 The `#[stable(feature = "foo", since = "1.420.69")]` attribute explicitly
48 marks an item as stabilized. Note that stable functions may use unstable things in their body.
49
50 ## rustc_const_unstable
51
52 The `#[rustc_const_unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]`
53 has the same interface as the `unstable` attribute. It is used to mark
54 `const fn` as having their constness be unstable. This allows you to make a
55 function stable without stabilizing its constness or even just marking an existing
56 stable function as `const fn` without instantly stabilizing the `const fn`ness.
57
58 Furthermore this attribute is needed to mark an intrinsic as `const fn`, because
59 there's no way to add `const` to functions in `extern` blocks for now.
60
61 ## rustc_const_stable
62
63 The `#[rustc_const_stable(feature = "foo", since = "1.420.69")]` attribute explicitly marks
64 a `const fn` as having its constness be `stable`. This attribute can make sense
65 even on an `unstable` function, if that function is called from another
66 `rustc_const_stable` function.
67
68 Furthermore this attribute is needed to mark an intrinsic as callable from
69 `rustc_const_stable` functions.
70
71 ## Stabilizing a library feature
72
73 To stabilize a feature, follow these steps:
74
75 0. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for
76 the FCP to complete (with `disposition-merge`).
77 1. Change `#[unstable(...)]` to `#[stable(since = "version")]`.
78 `version` should be the *current nightly*, i.e. stable+2. You can see which version is
79 the current nightly [on Forge](https://forge.rust-lang.org/#current-release-versions).
80 2. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the
81 compiler or tools, remove it from there as well.
82 3. If applicable, change `#[rustc_const_unstable(...)]` to
83 `#[rustc_const_stable(since = "version")]`.
84 4. Open a PR against `rust-lang/rust`.
85 - Add the appropriate labels: `@rustbot modify labels: +T-libs-api`.
86 - Link to the tracking issue and say "Closes #XXXXX".
87
88 You can see an example of stabilizing a feature with
89 [tracking issue #81656 with FCP](https://github.com/rust-lang/rust/issues/81656)
90 and the associated
91 [implementation PR #84642](https://github.com/rust-lang/rust/pull/84642).
92
93 ## allow_internal_unstable
94
95 Macros and compiler desugarings expose their bodies to the call
96 site. To work around not being able to use unstable things in the standard
97 library's macros, there's the `#[allow_internal_unstable(feature1, feature2)]`
98 attribute that allows the given features to be used in stable macros.
99
100 ## rustc_allow_const_fn_unstable
101
102 `const fn`, while not directly exposing their body to the world, are going to get
103 evaluated at compile time in stable crates. If their body does something const-unstable,
104 that could lock us into certain features indefinitely by accident. Thus no unstable const
105 features are allowed inside stable `const fn`.
106
107 However, sometimes we do know that a feature will get
108 stabilized, just not when, or there is a stable (but e.g. runtime-slow) workaround, so we
109 could always fall back to some stable version if we scrapped the unstable feature.
110 In those cases, the rustc_allow_const_fn_unstable attribute can be used to allow some
111 unstable features in the body of a stable `const fn`.
112
113 You also need to take care to uphold the `const fn` invariant that calling it at runtime and
114 compile-time needs to behave the same (see also [this blog post][blog]). This means that you
115 may not create a `const fn` that e.g. transmutes a memory address to an integer,
116 because the addresses of things are nondeterministic and often unknown at
117 compile-time.
118
119 Always ping @rust-lang/wg-const-eval if you are adding more
120 `rustc_allow_const_fn_unstable` attributes to any `const fn`.
121
122 ## staged_api
123
124 Any crate that uses the `stable`, `unstable`, or `rustc_deprecated` attributes
125 must include the `#![feature(staged_api)]` attribute on the crate.
126
127 ## rustc_deprecated
128
129 The deprecation system shares the same infrastructure as the stable/unstable
130 attributes. The `rustc_deprecated` attribute is similar to the [`deprecated`
131 attribute]. It was previously called `deprecated`, but was split off when
132 `deprecated` was stabilized. The `deprecated` attribute cannot be used in a
133 `staged_api` crate, `rustc_deprecated` must be used instead. The deprecated
134 item must also have a `stable` or `unstable` attribute.
135
136 `rustc_deprecated` has the following form:
137
138 ```rust,ignore
139 #[rustc_deprecated(
140 since = "1.38.0",
141 reason = "explanation for deprecation",
142 suggestion = "other_function"
143 )]
144 ```
145
146 The `suggestion` field is optional. If given, it should be a string that can be
147 used as a machine-applicable suggestion to correct the warning. This is
148 typically used when the identifier is renamed, but no other significant changes
149 are necessary.
150
151 Another difference from the `deprecated` attribute is that the `since` field is
152 actually checked against the current version of `rustc`. If `since` is in a
153 future version, then the `deprecated_in_future` lint is triggered which is
154 default `allow`, but most of the standard library raises it to a warning with
155 `#![warn(deprecated_in_future)]`.
156
157 [`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute
158 [blog]: https://www.ralfj.de/blog/2018/07/19/const.html