]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | # Stability attributes |
2 | ||
dfeec247 XL |
3 | This section is about the stability attributes and schemes that allow stable |
4 | APIs to use unstable APIs internally in the rustc standard library. | |
e1599b0c | 5 | |
dfeec247 XL |
6 | For instructions on stabilizing a language feature see [Stabilizing |
7 | Features](./stabilization_guide.md). | |
e1599b0c | 8 | |
60c5eb7d | 9 | ## unstable |
e1599b0c | 10 | |
dfeec247 XL |
11 | The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]` |
12 | attribute explicitly marks an item as unstable. Items that are marked as | |
13 | "unstable" cannot be used without a corresponding `#![feature]` attribute on | |
14 | the crate, even on a nightly compiler. This restriction only applies across | |
15 | crate boundaries, unstable items may be used within the crate that defines | |
16 | them. | |
17 | ||
18 | The `issue` field specifies the associated GitHub [issue number]. This field is | |
19 | required and all unstable features should have an associated tracking issue. In | |
20 | rare cases where there is no sensible value `issue = "none"` is used. | |
60c5eb7d | 21 | |
dfeec247 XL |
22 | The `unstable` attribute infects all sub-items, where the attribute doesn't |
23 | have to be reapplied. So if you apply this to a module, all items in the module | |
24 | will be unstable. | |
e1599b0c | 25 | |
dfeec247 XL |
26 | You can make specific sub-items stable by using the `#[stable]` attribute on |
27 | them. The stability scheme works similarly to how `pub` works. You can have | |
28 | public functions of nonpublic modules and you can have stable functions in | |
29 | unstable modules or vice versa. | |
e1599b0c XL |
30 | |
31 | Note, however, that due to a [rustc bug], stable items inside unstable modules | |
32 | *are* available to stable code in that location! So, for example, stable code | |
dfeec247 XL |
33 | can import `core::intrinsics::transmute` even though `intrinsics` is an |
34 | unstable module. Thus, this kind of nesting should be avoided when possible. | |
e1599b0c | 35 | |
60c5eb7d XL |
36 | The `unstable` attribute may also have the `soft` value, which makes it a |
37 | future-incompatible deny-by-default lint instead of a hard error. This is used | |
38 | by the `bench` attribute which was accidentally accepted in the past. This | |
39 | prevents breaking dependencies by leveraging Cargo's lint capping. | |
40 | ||
dfeec247 | 41 | [issue number]: https://github.com/rust-lang/rust/issues |
e1599b0c XL |
42 | [rustc bug]: https://github.com/rust-lang/rust/issues/15702 |
43 | ||
60c5eb7d | 44 | ## stable |
e1599b0c | 45 | |
dfeec247 XL |
46 | The `#[stable(feature = "foo", "since = "1.420.69")]` attribute explicitly |
47 | marks an item as stabilized. To do this, follow the instructions in | |
e1599b0c XL |
48 | [Stabilizing Features](./stabilization_guide.md). |
49 | ||
50 | Note that stable functions may use unstable things in their body. | |
51 | ||
dfeec247 XL |
52 | ## rustc_const_unstable |
53 | ||
54 | The `#[rustc_const_unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]` | |
55 | has the same interface as the `unstable` attribute. It is used to mark | |
56 | `const fn` as having their constness be unstable. This allows you to make a | |
57 | function stable without stabilizing its constness or even just marking an existing | |
58 | stable function as `const fn` without instantly stabilizing the `const fn`ness. | |
59 | ||
60 | Furthermore this attribute is needed to mark an intrinsic as `const fn`, because | |
61 | there's no way to add `const` to functions in `extern` blocks for now. | |
e1599b0c | 62 | |
dfeec247 | 63 | ## rustc_const_stable |
e1599b0c | 64 | |
dfeec247 XL |
65 | The `#[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. | |
69 | ||
70 | Furthermore this attribute is needed to mark an intrinsic as callable from | |
71 | `rustc_const_stable` functions. | |
72 | ||
73 | ||
74 | ## allow_internal_unstable | |
e1599b0c | 75 | |
dfeec247 XL |
76 | Macros, compiler desugarings and `const fn`s expose their bodies to the call |
77 | site. To work around not being able to use unstable things in the standard | |
78 | library's macros, there's the `#[allow_internal_unstable(feature1, feature2)]` | |
79 | attribute that whitelists the given features for usage in stable macros or | |
80 | `const fn`s. | |
81 | ||
82 | Note that `const fn`s are even more special in this regard. You can't just | |
83 | whitelist any feature, the features need an implementation in | |
84 | `qualify_min_const_fn.rs`. For example the `const_fn_union` feature gate allows | |
85 | accessing fields of unions inside stable `const fn`s. The rules for when it's | |
86 | ok to use such a feature gate are that behavior matches the runtime behavior of | |
87 | the same code (see also [this blog post][blog]). This means that you may not | |
88 | create a `const fn` that e.g. transmutes a memory address to an integer, | |
89 | because the addresses of things are nondeterministic and often unknown at | |
90 | compile-time. | |
91 | ||
92 | Always ping @oli-obk, @RalfJung, and @Centril if you are adding more | |
93 | `allow_internal_unstable` attributes to any `const fn` | |
e1599b0c | 94 | |
60c5eb7d XL |
95 | ## staged_api |
96 | ||
97 | Any crate that uses the `stable`, `unstable`, or `rustc_deprecated` attributes | |
98 | must include the `#![feature(staged_api)]` attribute on the crate. | |
99 | ||
100 | ## rustc_deprecated | |
101 | ||
102 | The deprecation system shares the same infrastructure as the stable/unstable | |
103 | attributes. The `rustc_deprecated` attribute is similar to the [`deprecated` | |
104 | attribute]. It was previously called `deprecated`, but was split off when | |
105 | `deprecated` was stabilized. The `deprecated` attribute cannot be used in a | |
106 | `staged_api` crate, `rustc_deprecated` must be used instead. The deprecated | |
107 | item must also have a `stable` or `unstable` attribute. | |
108 | ||
109 | `rustc_deprecated` has the following form: | |
110 | ||
111 | ```rust,ignore | |
112 | #[rustc_deprecated( | |
113 | since = "1.38.0", | |
114 | reason = "explanation for deprecation", | |
115 | suggestion = "other_function" | |
116 | )] | |
117 | ``` | |
118 | ||
dfeec247 XL |
119 | The `suggestion` field is optional. If given, it should be a string that can be |
120 | used as a machine-applicable suggestion to correct the warning. This is | |
121 | typically used when the identifier is renamed, but no other significant changes | |
122 | are necessary. | |
60c5eb7d | 123 | |
dfeec247 XL |
124 | Another difference from the `deprecated` attribute is that the `since` field is |
125 | actually checked against the current version of `rustc`. If `since` is in a | |
60c5eb7d XL |
126 | future version, then the `deprecated_in_future` lint is triggered which is |
127 | default `allow`, but most of the standard library raises it to a warning with | |
128 | `#![warn(deprecated_in_future)]`. | |
129 | ||
130 | [`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute | |
131 | ||
132 | ## -Zforce-unstable-if-unmarked | |
133 | ||
134 | The `-Zforce-unstable-if-unmarked` flag has a variety of purposes to help | |
135 | enforce that the correct crates are marked as unstable. It was introduced | |
136 | primarily to allow rustc and the standard library to link to arbitrary crates | |
137 | on crates.io which do not themselves use `staged_api`. `rustc` also relies on | |
138 | this flag to mark all of its crates as unstable with the `rustc_private` | |
139 | feature so that each crate does not need to be carefully marked with | |
140 | `unstable`. | |
141 | ||
142 | This flag is automatically applied to all of `rustc` and the standard library | |
143 | by the bootstrap scripts. This is needed because the compiler and all of its | |
144 | dependencies are shipped in the sysroot to all users. | |
145 | ||
146 | This flag has the following effects: | |
147 | ||
148 | - Marks the crate as "unstable" with the `rustc_private` feature if it is not | |
149 | itself marked as stable or unstable. | |
150 | - Allows these crates to access other forced-unstable crates without any need | |
151 | for attributes. Normally a crate would need a `#![feature(rustc_private)]` | |
152 | attribute to use other unstable crates. However, that would make it | |
153 | impossible for a crate from crates.io to access its own dependencies since | |
154 | that crate won't have a `feature(rustc_private)` attribute, but *everything* | |
155 | is compiled with `-Zforce-unstable-if-unmarked`. | |
156 | ||
157 | Code which does not use `-Zforce-unstable-if-unmarked` should include the | |
158 | `#![feature(rustc_private)]` crate attribute to access these force-unstable | |
159 | crates. This is needed for things that link `rustc`, such as `miri`, `rls`, or | |
160 | `clippy`. | |
161 | ||
e1599b0c | 162 | [blog]: https://www.ralfj.de/blog/2018/07/19/const.html |