@@ -13,9 +13,12 @@ strong stability guarantees in stable releases.
13
13
14
14
It also redesigns and simplifies stability attributes to better
15
15
integrate with release channels and the other stability-moderating
16
- system in the language, 'feature gates'.
16
+ system in the language, 'feature gates'. While this version of
17
+ stability attributes is only suitable for use by the standard
18
+ distribution, we leave open the possibility of adding a redesigned
19
+ system for the greater cargo ecosystem to annotate feature stability.
17
20
18
- Finally, it discusses how Cargo will leverage feature gates to
21
+ Finally, it discusses how Cargo may leverage feature gates to
19
22
determine compatibility of Rust crates with specific revisions of the
20
23
Rust language.
21
24
@@ -193,42 +196,46 @@ unmarked functions (which are in most cases considered unstable).
193
196
As a simplifying measure stability attributes are unified with feature
194
197
gates, and thus tied to release channels and Rust language versions.
195
198
196
- * The unused ` #[frozen] ` and ` #[locked] ` levels are removed.
197
- * The ` #[experimental] ` level is removed in favor of simply
198
- ` #[unstable] ` .
199
- * Alter the syntax of the remaining ` unstable ` , ` stable ` and
200
- ` deprecated ` to require a ` feature ` parameter,
201
- e.g. ` #[unstable(feature = "chicken_dinner")] ` . This signals
202
- that the item tagged by the attribute is part of the named
203
- feature.
204
- * The ` stable ` and ` deprecated ` attributes require an additional
205
- parameter ` since ` , whose value is equal to a * version of the
206
- language* (where currently the language version is equal to the
199
+ * All existing stability attributes are removed of any semantic
200
+ meaning by the compiler. Existing code that uses these attributes
201
+ will continue to compile, but neither rustc nor rustdoc will
202
+ interpret them in any way.
203
+ * New ` #[staged_unstable(...)] ` , ` #[staged_stable(...)] ` ,
204
+ and ` #[staged_deprecated(...)] ` attributes are added.
205
+ * All three require a ` feature ` parameter,
206
+ e.g. ` #[staged_unstable(feature = "chicken_dinner")] ` . This signals
207
+ that the item tagged by the attribute is part of the named feature.
208
+ * The ` staged_stable ` and ` staged_deprecated ` attributes require an
209
+ additional parameter ` since ` , whose value is equal to a * version of
210
+ the language* (where currently the language version is equal to the
207
211
compiler version), e.g. `#[ stable(feature = "chicken_dinner", since
208
212
= "1.6")] `.
209
213
210
214
All stability attributes continue to support an optional ` description `
211
215
parameter.
212
216
217
+ The intent of adding the 'staged_ ' prefix to the stability attributes
218
+ is to leave the more desirable attribute names open for future use.
219
+
213
220
With these modifications, new API surface area becomes a new "language
214
221
feature" which is controlled via the ` #[feature] ` attribute just like
215
222
other normal language features. The compiler will disallow all usage
216
- of ` #[unstable (feature = "foo")] ` APIs unless the current crate
223
+ of ` #[staged_unstable (feature = "foo")] ` APIs unless the current crate
217
224
declares ` #![feature(foo)] ` . This enables crates to declare what API
218
225
features of the standard library they rely on without opting in to all
219
226
unstable API features.
220
227
221
228
Examples of APIs tagged with stability attributes:
222
229
223
230
```
224
- #[unstable (feature = "a")]
231
+ #[staged_unstable (feature = "a")]
225
232
fn foo() { }
226
233
227
- #[stable (feature = "b", since = "1.6")]
234
+ #[staged_stable (feature = "b", since = "1.6")]
228
235
fn bar() { }
229
236
230
- #[stable (feature = "c", since = "1.6")]
231
- #[deprecated (feature = "c", since = "1.7")]
237
+ #[staged_stable (feature = "c", since = "1.6")]
238
+ #[staged_deprecated (feature = "c", since = "1.7")]
232
239
fn baz() { }
233
240
```
234
241
@@ -241,54 +248,56 @@ into the language. More detail on these matters below.
241
248
Some additional restrictions are enforced by the compiler as a sanity
242
249
check that they are being used correctly.
243
250
244
- * The ` deprecated ` attribute * must* be paired with a ` stable `
245
- attribute, enforcing that the progression of all features is from
246
- 'unstable' to 'stable' to 'deprecated' and that the version in which
247
- the feature was promoted to stable is recorded and maintained as
248
- well as the version in which a feature was deprecated.
251
+ * The ` staged_deprecated ` attribute * must* be paired with a
252
+ ` staged_stable ` attribute, enforcing that the progression of all
253
+ features is from 'staged_unstable' to 'staged_stable' to
254
+ 'staged_deprecated' and that the version in which the feature was
255
+ promoted to stable is recorded and maintained as well as the version
256
+ in which a feature was deprecated.
249
257
* Within a crate, the compiler enforces that for all APIs with the
250
- same feature name where any are marked ` stable ` , all are either
251
- ` stable ` or ` deprecated ` . In other words, no single feature may be
252
- partially promoted from ` unstable ` to ` stable ` , but features may be
253
- partially deprecated. This ensures that no APIs are accidentally
254
- excluded from stabilization and that entire features may be
255
- considered either 'unstable' or 'stable'.
256
-
257
- It's important to note that * the role of stability attributes outside
258
- of the standard distribution is not clear * , moreso once they are
259
- explicitly tied to release channels and language versions, and
260
- * stability attributes should not be used outside of the standard
261
- distribution* . If such features become desirable generally they
262
- will be solved in Cargo .
258
+ same feature name where any are marked ` staged_stable ` , all are
259
+ either ` staged_stable ` or ` staged_deprecated ` . In other words, no
260
+ single feature may be partially promoted from ` unstable ` to
261
+ ` stable ` , but features may be partially deprecated. This ensures
262
+ that no APIs are accidentally excluded from stabilization and that
263
+ entire features may be considered either 'unstable' or 'stable'.
264
+
265
+ It's important to note that these stability attributes are * only known
266
+ to be useful to the standard distribution * , because of the explicit
267
+ linkage to language versions and release channels. There is though no
268
+ mechanism to explicitly forbid their use outside of the standard
269
+ distribution. A general mechanism for indicating API stability
270
+ will be reconsidered in the future .
263
271
264
272
### API lifecycle
265
273
266
274
These attributes alter the process of how new APIs are added to the
267
275
standard library slightly. First an API will be proposed via the RFC
268
- process, and a name for the API feature being added will be assigned at
269
- that time. When the RFC is accepted, the API will be added to the
270
- standard library with an ` #[unstable (feature = "...")] ` attribute
271
- indicating what feature the API was assigned to.
276
+ process, and a name for the API feature being added will be assigned
277
+ at that time. When the RFC is accepted, the API will be added to the
278
+ standard library with an `#[ staged_unstable (feature =
279
+ "...") ] `attribute indicating what feature the API was assigned to.
272
280
273
281
After receiving test coverage from nightly users (who have opted into
274
- the feature) or thorough review, all APIs with a given feature
275
- will be changed from ` unstable ` to ` stable ` , adding ` since = "..." `
276
- to mark the version in which the promotion occurred, and the feature
277
- is considered stable and may be used on the stable release channel.
282
+ the feature) or thorough review, all APIs with a given feature will be
283
+ changed from ` staged_unstable ` to ` staged_stable ` , adding `since =
284
+ "..."` to mark the version in which the promotion occurred, and the
285
+ feature is considered stable and may be used on the stable release
286
+ channel.
278
287
279
- When a stable API becomes deprecated the ` deprecated ` attribute is
280
- added in addition to the existing ` stable ` attribute, as well
281
- recording the version in which the deprecation was performed with the
282
- ` since ` parameter.
288
+ When a stable API becomes deprecated the ` staged_deprecated ` attribute
289
+ is added in addition to the existing ` staged_stable ` attribute, as
290
+ well recording the version in which the deprecation was performed with
291
+ the ` since ` parameter.
283
292
284
293
(Occassionally unstable APIs may be deprecated for the sake of easing
285
- user transitions, in which case they receive both the ` stable ` and
286
- ` deprecated ` attributes at once.)
294
+ user transitions, in which case they receive both the ` staged_stable `
295
+ and ` staged_deprecated ` attributes at once.)
287
296
288
297
### Checking ` #[feature] `
289
298
290
299
The names of features will no longer be a hardcoded list in the compiler
291
- due to the free-form nature of the ` #[unstable ] ` feature names.
300
+ due to the free-form nature of the ` #[staged_unstable ] ` feature names.
292
301
Instead, the compiler will perform the following steps when inspecting
293
302
` #[feature] ` attributes lists:
294
303
@@ -331,32 +340,33 @@ rust they indicate they can be compiled with. Some specific use cases are:
331
340
To solve this problem, Cargo and crates.io will grow the knowledge of
332
341
the minimum required Rust language version required to compile a
333
342
crate. Currently the Rust language version coincides with the version
334
- of the ` rustc ` compiler. Crucially, * on the stable release channel,
335
- analysis of feature usage is nearly sufficient to determine
336
- compatibility of a crate with both past and future revisions of the
337
- Rust language within a single major release series* : by knowing in
338
- which version each feature of the language and each feature of the
339
- library was stabilized, and by detecting every feature used by a
340
- crate, rustc can determine the minimum version required; and rustc may
341
- assume that the crate will be compatible with future stable
342
- releases. There are two caveats: first, conditional compilation makes
343
- it not possible in some cases to detect all features in use, which may
344
- result in Cargo detecting a minumum version less than that required on
345
- all platforms. For this and other reasons Cargo will allow the minimum
343
+ of the ` rustc ` compiler.
344
+
345
+ In the absense of user-supplied information about minimum language
346
+ version requirements, * Cargo will attempt to use feature information
347
+ to determine version compatibility* : by knowing in which version each
348
+ feature of the language and each feature of the library was
349
+ stabilized, and by detecting every feature used by a crate, rustc can
350
+ determine the minimum version required; and rustc may assume that the
351
+ crate will be compatible with future stable releases. There are two
352
+ caveats: first, conditional compilation makes it not possible in some
353
+ cases to detect all features in use, which may result in Cargo
354
+ detecting a minumum version less than that required on all
355
+ platforms. For this and other reasons Cargo will allow the minimum
346
356
version to be specified manually. Second, rustc can not make any
347
357
assumptions about compatibility across major revisions of the
348
358
language.
349
359
350
360
To calculate this information, Cargo will compile crates just before
351
361
publishing. In this process, the Rust compiler will record all used
352
- language features as well as all used ` #[stable ] ` APIs. Each compiler
353
- will contain archival knowledge of what stable version of the compiler
354
- language features were added to, and each ` #[stable] ` API has the
355
- ` since ` metadata to tell which version of the compiler it was released
356
- in. The compiler will calculate the maximum of all these versions
357
- (language plus library features) to pass to Cargo. If any ` #[feature] `
358
- directive is detected, however, the required Rust language version is
359
- "nightly".
362
+ language features as well as all used ` #[staged_stable ] ` APIs. Each
363
+ compiler will contain archival knowledge of what stable version of the
364
+ compiler language features were added to, and each ` #[staged_stable] `
365
+ API has the ` since ` metadata to tell which version of the compiler it
366
+ was released in. The compiler will calculate the maximum of all these
367
+ versions (language plus library features) to pass to Cargo. If any
368
+ ` #[feature] ` directive is detected, however, the required Rust
369
+ language version is "nightly".
360
370
361
371
Cargo will then pass this required language version to crates.io which
362
372
will both store it in the index as well as present it as part of the UI.
@@ -418,6 +428,9 @@ This is done as a judgement call that in each context the given syntax
418
428
looks best, and accepting that since this is a feature that is not
419
429
intended for general use the discrepancy is not a major problem.
420
430
431
+ Having Cargo do version detection through feature analysis is known
432
+ not to be foolproof, and may present further unknown obstacles.
433
+
421
434
# Alternatives
422
435
423
436
Leave feature gates and unstable APIs exposed to the stable
@@ -444,6 +457,9 @@ If stability attributes are only for std, that takes away the
444
457
` #[deprecated] ` attribute from Cargo libs, which is more clearly
445
458
applicable.
446
459
460
+ What mechanism ensures that all API's have stability coverage? Probably
461
+ the will just default to unstable with some 'default' feature name.
462
+
447
463
# See Also
448
464
449
465
* [ Stability as a deliverable] [ 1 ]
0 commit comments