rust-lang / rust-lang/rust

Tracking issue for release notes of #155499: stabilize never type

Open
#158,197 7 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-rustdoc-js A-rustdoc-json A-rustdoc-search release-blog-post relnotes relnotes-tracking-issue T-clippy T-compiler T-lang T-libs T-rust-analyzer T-rustdoc T-rustdoc-frontend
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

This issue tracks the release notes text for #155499.

cc @WaffleLapkin, @jackh726 -- original issue/PR authors and assignees for drafting text

See the forge.rust-lang.org chapter about release notes for an overview of how the release team makes use of these tracking issues.

Release notes text

This section should be edited to specify the correct category(s) for the change, with succinct description(s) of what changed. Some things worth considering:

  • Does this need an additional compat notes section?
  • Was this a libs stabilization that should have additional headers to list new APIs under Stabilized APIs and Const Stabilized APIs?
# Language
- [Stabilize never type](https://github.com/rust-lang/rust/pull/155499)

# Compatibility notes
- [`Infallible` is now a type alias to `!`](https://github.com/rust-lang/rust/pull/155499)
- [The never type fallback was changed to `!` on all editions](https://github.com/rust-lang/rust/pull/155499)

[!TIP]
Use the previous releases for inspiration on how to write the release notes text and which categories to pick.

Release blog section

If this change is notable enough for inclusion in the blog post then this section should be edited to contain a draft for the blog post. Otherwise leave it empty.

# Never type

After 10 years and 5 failed stabilization attempts, **the [never type] is finally stable**!

[never type]: https://doc.rust-lang.org/stable/std/primitive.never.html

The never type (spelled `!` in code) is the canonical uninhabited type, it represents the type of diverging computations – computations which never resolve to any value. It is impossible to create a value of the never type, as such, it is a marker of unreachable code. It is the type of expressions that terminate control flow, such as `return`, `break`, and [`std::process::exit`].

[`std::process::exit`]: https://doc.rust-lang.org/stable/std/process/fn.exit.html

Since having a value of the never type is impossible, Rust permits a never-to-any coercion, allowing to turn `!` into any other type (this is what distinguishes it from any other uninhabited types). This can be used, for example, to not return a value from one of the branches of a `match` or an `if`:

```rust
fn mrrrow(option: Option<u32>) {
    let value = match option {
        // `x` has type `u32`
        Some(x) => x,
        // `return` has type `!`, which is then coerced to `u32`,
        // allowing the `match` to pass type checking.
        None => return,
    };
    // ...
}
```

The never type could already have been "observed" on stable before – it was permitted as the return type of functions (`-> !`) and it was already the type of some built-in constructs (`return`, `break`, etc). What this release allows, is to name the never type anywhere:

```rust
fn infallible_unwrap(res: Result<T, !>) -> T {
    // ^^ writing `Result<_, !>` was not allowed before
    let Ok(v) = res;
    v
}
```

Additionally this release changes [`Infallible`] to be an alias to the never type. That makes all old APIs that used `Infallible` be compatible with using `!`. This was the plan ever since the introduction of `Infallible` and is one of the reasons why the never type stabilization was so hard (waffle gave a [talk](https://www.youtube.com/watch?v=3jM4cnEVrLc) about some of the troubles of the stabilization).

[`Infallible`]: https://doc.rust-lang.org/nightly/std/convert/type.Infallible.html

Unfortunately, to allow changing `Infallible`, we had to introduce a breaking change. This release changes the "never type fallback" from `()` to `!` in editions **before** 2024 (i.e. 2015, 2018, and 2021), similarly to what has [already been done in edition 2024]. This should largely be unnoticeable, but can affect code in some rare cases (for example when ignoring a result of a function returning a generic parameter). Note that this change might also make the compiler detect more code as unreachable.

[already been done in edition 2024]: https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html

We tried to minimize the impact of this breaking change as much as possible, by providing future compatibility warnings far in advance and releasing fixes to public crates that have been broken by this. If a dependency is failing due to issues with the never type, consider updating it, as a fix might have already been released for it.

[!NOTE]

If a blog post section is required the release-blog-post label should be added (@rustbot label +release-blog-post) to this issue as otherwise it may be missed by the release team.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the forge.rust-lang.org release notes chapter and compare the draft with previous releases. Review the Release notes text and Release blog section for accurate categories, compatibility notes, and concise wording for stabilizing the never type. The work is done when the release-note text is finalized and any needed blog-post label is added.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation, release
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.