Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand on stability documentation. #462

Merged
merged 2 commits into from
Oct 11, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 82 additions & 5 deletions src/stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
This section is about the stability attributes and schemes that allow stable APIs to use unstable
APIs internally in the rustc standard library.

For instructions on stabilizing a language feature see
For instructions on stabilizing a language feature see
[Stabilizing Features](./stabilization_guide.md).

# unstable
## unstable

The `#[unstable(feature = "foo", issue = "1234", reason = "lorem ipsum")]` attribute explicitly
marks an item as unstable. This infects all sub-items, where the attribute doesn't have to be
marks an item as unstable. Items that are marked as "unstable" cannot be used
without a corresponding `#![feature]` attribute on the crate, even on a
nightly compiler. This restriction only applies across crate boundaries, unstable
items may be used within the crate they are defined.

The `unstable` attribute infects all sub-items, where the attribute doesn't have to be
reapplied. So if you apply this to a module, all items in the module will be unstable.

You can make specific sub-items stable by using the `#[stable]` attribute on them.
Expand All @@ -21,17 +26,22 @@ Note, however, that due to a [rustc bug], stable items inside unstable modules
can import `core::intrinsics::transmute` even though `intrinsics` is an unstable
module. Thus, this kind of nesting should be avoided when possible.

The `unstable` attribute may also have the `soft` value, which makes it a
future-incompatible deny-by-default lint instead of a hard error. This is used
by the `bench` attribute which was accidentally accepted in the past. This
prevents breaking dependencies by leveraging Cargo's lint capping.

[rustc bug]: https://github.com/rust-lang/rust/issues/15702

# stable
## stable

The `#[stable(feature = "foo", "since = "1.420.69")]` attribute explicitly marks an item as
stabilized. To do this, follow the instructions in
[Stabilizing Features](./stabilization_guide.md).

Note that stable functions may use unstable things in their body.

# allow_internal_unstable
## allow_internal_unstable

Macros, compiler desugarings and `const fn`s expose their bodies to the call site. To
work around not being able to use unstable things in the standard library's macros, there's the
Expand All @@ -49,4 +59,71 @@ are nondeterministic and often unknown at compile-time.
Always ping @oli-obk, @RalfJung, and @Centril if you are adding more `allow_internal_unstable`
attributes to any `const fn`

## staged_api

Any crate that uses the `stable`, `unstable`, or `rustc_deprecated` attributes
must include the `#![feature(staged_api)]` attribute on the crate.

## rustc_deprecated

The deprecation system shares the same infrastructure as the stable/unstable
attributes. The `rustc_deprecated` attribute is similar to the [`deprecated`
attribute]. It was previously called `deprecated`, but was split off when
`deprecated` was stabilized. The `deprecated` attribute cannot be used in a
`staged_api` crate, `rustc_deprecated` must be used instead. The deprecated
item must also have a `stable` or `unstable` attribute.

`rustc_deprecated` has the following form:

```rust,ignore
#[rustc_deprecated(
since = "1.38.0",
reason = "explanation for deprecation",
suggestion = "other_function"
)]
```

The `suggestion` field is optional. If given, it should be a string that can
be used as a machine-applicable suggestion to correct the warning. This is
typically used when the identifier is renamed, but no other significant
changes are necessary.

Another difference from the `deprecated` attribute is that the `since` field
is actually checked against the current version of `rustc`. If `since` is in a
future version, then the `deprecated_in_future` lint is triggered which is
default `allow`, but most of the standard library raises it to a warning with
`#![warn(deprecated_in_future)]`.

[`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute

## -Zforce-unstable-if-unmarked

The `-Zforce-unstable-if-unmarked` flag has a variety of purposes to help
enforce that the correct crates are marked as unstable. It was introduced
primarily to allow rustc and the standard library to link to arbitrary crates
on crates.io which do not themselves use `staged_api`. `rustc` also relies on
this flag to mark all of its crates as unstable with the `rustc_private`
feature so that each crate does not need to be carefully marked with
`unstable`.

This flag is automatically applied to all of `rustc` and the standard library
by the bootstrap scripts. This is needed because the compiler and all of its
dependencies are shipped in the sysroot to all users.

This flag has the following effects:

- Marks the crate as "unstable" with the `rustc_private` feature if it is not
itself marked as stable or unstable.
- Allows these crates to access other forced-unstable crates without any need
for attributes. Normally a crate would need a `#![feature(rustc_private)]`
attribute to use other unstable crates. However, that would make it
impossible for a crate from crates.io to access its own dependencies since
that crate won't have a `feature(rustc_private)` attribute, but *everything*
is compiled with `-Zforce-unstable-if-unmarked`.

Code which does not use `-Zforce-unstable-if-unmarked` should include the
`#![feature(rustc_private)]` crate attribute to access these force-unstable
crates. This is needed for things that link `rustc`, such as `miri`, `rls`, or
`clippy`.

[blog]: https://www.ralfj.de/blog/2018/07/19/const.html