Skip to content

"stabilize never type" T-types FCP #161925

Description

@lcnr

We forgot to T-types FCP #155499. See that PR for more detail.

As discussed on zulip:

My specific recommendation here would be that once we get a complete sense of the type system hacks that we're landing to support the stabilization, that we do a T-types FCP on the PR to confirm we're good.

This PR has three changes which make it worthy of a Types FCP


Allow users to name ! directly. It was already possible to use ! outside of function return types by using the following pattern:

trait Func {
    type Ret;
}
impl<F: FnOnce() -> R, R> Func for F {
    type Ret = R;
}
type Never = <fn() -> ! as Func>::Ret;

However, I remember us generally discouraging users from writing such impls. I don't think there are any significant complications from users being able to implement traits for ! more widely. So this seems fine to me.


This PR also changes the "never type fallback" to always fall-back to ! instead of () in old editions: 6656056. See the crater results for that change in #155499 (comment). This affects any inference variable resulting from a never-to-any coercion which we apply whenever we're coercing an value expression with type !, see #155499 (comment).


Finally, we're setting Infallible to be a type alias for ! instead of an enum without any variants. This was done in #155924. While this change is T-libs, we did 3 Types FCPs to minimize its impact.

@WaffleLapkin mentioned 4 kinds of breakage in #155924 (comment):

  1. Calling a method on a result from a coercion of never to any currently results in an error (see Inconsistent method lookup on never type #143349)
  2. It is possible to use hacks to avoid stability checking for the never type, thus being able to use it on stable. There are a few crates which do this and implement the same trait for both never and Infallible (or also crates which enable the nightly feature).
    • this breakage has not been fixed and there are 9 root causes and a few more dependencies which break because of that. This is fine and not a T-types issue :>
  3. standard library contains a reservation impl, which forbids Tracking issue for reserved impl impl<T> From<!> for T #64715 From<!> impls. After making Infallible = !, this reservation impl can conflict with existing implementations for Infallible - This breaks 14 crates total (including reverse-dependencies of broken crates)
  4. There is some weirdness with how coercions work, which I don't yet understand

Metadata

Metadata

Assignees

No one assigned

    Labels

    F-never_type`#![feature(never_type)]`T-typesRelevant to the types team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions