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.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions