Skip to content

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

Description

@rustbot

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-rustdoc-jsArea: Rustdoc's JS front-endA-rustdoc-jsonArea: Rustdoc JSON backendA-rustdoc-searchArea: Rustdoc's search featureT-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.T-rust-analyzerRelevant to the rust-analyzer team, which will review and decide on the PR/issue.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.T-rustdoc-frontendRelevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.release-blog-postMarks issues tracking what text to put in the release blog post.relnotesMarks issues that should be documented in the release notes of the next release.relnotes-tracking-issueMarks issues tracking what text to put in release notes.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions