Skip to content

Remove From<!> for T *reservation* impl - #160705

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
WaffleLapkin:unreserve_Fromᐸǃᐳ
Aug 24, 2026

Hidden character warning

The head ref may contain hidden characters: "unreserve_From\u1438\u01c3\u1433"
Merged

Remove From<!> for T *reservation* impl#160705
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
WaffleLapkin:unreserve_Fromᐸǃᐳ

Conversation

@WaffleLapkin

@WaffleLapkin WaffleLapkin commented Aug 7, 2026

Copy link
Copy Markdown
Member

View all comments

This PR removes the <T> From<!> for T reservation implementation added in #62661 and tracked in #64715 and #64631.

The reservation impl in question was added in order to reserve some space for adding the following impl:

impl<T> From<!> for T {
    fn from(never: !) -> T { never }
}

It is meant to prevent users from writing some impls that would overlap if the From<!> for T impl is to be added.

This requires T-types FCP. Below is my proposal and necessary context:

The reservation impl is not sufficient

The reservation impl prevents one from assuming that From<!> for T is not implemented making the following not compile:

struct LocalType;
trait SomeTrait { }
impl<T: From<!>> SomeTrait for T { }
impl SomeTrait for LocalType { }

However, it does not prevent all implementation that would overlap given From<!> for T. Namely, From<!> for T would overlap with the following impls, all of which are currently permitted (and exist):

// T for T identity impl in `core`
impl<T> From<T> for T { ... }

// Various T->wrapper of T impls present in both the standard library,
// and in external crates
impl<T> From<T> for W<T> { ... }

// !->Local is also allowed
impl From<!> for Local {}

Also note that the reservation impl only exists for From<!>, but not for From<Infallible>, so even the impls that the reservation impl is meant to forbid, are currently allowed through Infallible anyway (we are planning to make Infallible a type alias to ! at the same time as stabilizing !).

Motivation for From<!> for T impl

It is surprisingly hard to find the original motivation for From<!> for T impl or the reservation impl, other than "people vaguely think that all types should implement From<!>, since there is never-to-any coercion".

One use-case seems to be "calling infallible function in a fallible one, and unwrapping Result<_, !> with ?". However, nowdays it is trivial to unwrap the result safely without ?:

let Ok(owo) = infallible_function();  

Another use-case that I've seen mentioned is "fallible function with a set error, taking an infallible function":

fn try_from<T>(t: T) -> Result<Meow, MyError>
where
    Meow: TryFrom<T>,
    <Meow as TryFrom<T>>::Error: Into<MyError>
{ ... }

With such definition, you can't pass Meow into try_from, because MyError: From<Infallible> doesn't hold.

This is more unfortunate, but it's not clear how widespread this problem is and how bad the workarounds would be. If a function expects impl FnOnce(...) -> Result<...>, it should be trivial to coerce the ! error to an appropriate type. With other trait bounds (like in the example above) it could be solved by adding a custom impl for your specific error type (annoying, but workable). Certaintly this doesn't feel like a big roadblock to me.

(let me know if you know more prior art on this)

There is no clear path for adding From<!> for T impl

Adding From<!> for T seems... hard... and hard to argue for.

It would require ignoring overlap with a bunch of impls (as described above) and would also require low priority impls (to avoid inference failures in cases where previously the only applicable impl was the identity one, so adding From<!> makes "one impl rule" not apply).

The tracking issue says:

The precise mechanism to permit us to add the From<!> for T impl is not yet clear. The current "plan of record" is to extend the "marker trait mechanism" to accommodate the idea of impls whose entire body consists of unreachable methods and to permit overlap.

Considering "traits with all methods having arguments of uninhabited types" as marker traits is technically possible (I think?), but feels like a bit of a stretch. Making overlap check consider if all trait functions take arguments which are uninhabited (known to be uninhabited in the current context) seems like a big complication, especially considering how From<T> would not be a marker trait in the general case — only From<!>/From<OtherUninhabitedTypes> would be (also that requires attaching the overlap check to some context from which we can check if a type is publically uninhabited, which can also lead to situations where impl A overlaps with impl B, but impl B doesn't overlap with impl A1). Allowing overlap with arbitrary user impls also is likely to cause unforcene issues in my opinion.

The reservation impl causes problems for the never type stabilization

Because the reservation impl reserves space for From<!> for T, but not for From<Infallible> for T, making Infallible an alias for ! makes some code fail to compile. See #155924:

  1. standard library contains a reservation impl, which forbids certain 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)

Given that both keeping the reservation impl (while making Infallible = !) and making the reservation a proper impl break code, we should decide which path we want to pursue before stabilizing the never type (and making Infallible = !).

Proposal

After trying to add From<!> for T as a proper impl, I'm not convinced that it's worth the complexity and messiness of allowing such widespread overlap (with user defined impls too!). As such, I propose to remove the reservation impl, to prevent unnecessary breakage from its combination with making Infallible = !, as described above.

Alternatives

  • Add proper impl<T> From<!> for T, accepting the breakage, overlap, and the complexity.
    • I'm not sure how feasible this is, after trying to do this approach, it doesn't feel right
  • Keep the reservation impl / add the reservation impl From<Infallible> for T formally accepting the breakage of that, with the hopes that we can still add impl<T> From<!> for T in the future
    • This is the most breaking of the option, as it breaks code that depends on From<Infallible> for T not existing, and expects future breakage when adding impl<T> From<!> for T
    • It is unlikely that adding impl<T> From<!> for T in the future will be much easier than right now

Closes #64715
r? types

I'll remove the rustc_reservation_impl attribute in a separate PR (cc #64631).

Footnotes

  1. i.e. in the context of impl A a certain type is not known to be uninhabited, and thus the overlap between impls should not be allowed. at the same time in the context of impl B same type might be known to be uninhabited, allowing the overlap.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 7, 2026
@WaffleLapkin WaffleLapkin added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-types Relevant to the types team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 7, 2026
@rust-log-analyzer

This comment has been minimized.

@lcnr

lcnr commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

cc @rust-lang/lang @rust-lang/libs-api

Given that this is largely a "the type system complexity of adding this impl significantly outweights its potential benefits".

rustc_trait_selection::traits::query::type_op::implied_outlives_bounds

It felt fine to me to accept overlap between the blanket From<T> for T impl and the From<!> for T impl, but also having overlap with arbitrary user written impls feels a lot worse. As argued by @WaffleLapkin I don't think there's a sensible language feature which would supersede any hack we do here and that, together with the somewhat minor arguments for adding this impl, leads me to quite strongly prefer removing this reservation impl.

@lcnr

lcnr commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

🤣 guess who just had the wrong thing in their clipboard

@rfcbot fcp merge types

@rust-rfcbot

rust-rfcbot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

@lcnr has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Aug 10, 2026
@theemathas theemathas added the I-libs-api-nominated [DEPRECATED; DO NOT USE] label Aug 10, 2026
@theemathas

Copy link
Copy Markdown
Contributor

Nominating for libs-api in case they're aware of any important use cases that require this reservation impl.

@WaffleLapkin
WaffleLapkin force-pushed the unreserve_Fromᐸǃᐳ branch from 7c94b9a to 27b7dcc Compare August 10, 2026 18:01
@rustbot

This comment has been minimized.

@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Aug 10, 2026
@clarfonthey

Copy link
Copy Markdown
Contributor

In our libs meeting we agree that it's fine to remove. We definitely lament the fact that error types have to essentially add their own boilerplate From<!> for Error and would rather not have to do that, but it's what people are doing for Infallible and if types can't find a way to make that work without breakage, we will deal.

@nikomatsakis

nikomatsakis commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Let me give some historical context—

The concept of a "reservation impl" was indeed ill-documented and quite frankly confusing. It was never meant to ensure that we could add a From<!> for T impl -- and I would not want that impl to exist.

The purpose of it was different. We were discussing the possibility of stabilizing ! without redefining Infallible = ! and the point was raised that, if we did that, people would like go and add impls like the following

impl From<!> for MyErrorType { }

But those same people already have

impl From<Infallible> for MyErrorType { }

and that would then create overlapping impls.

There was also way that you could depend on this with negative reasoning..? I may have the fine-grained details wrong, but that was the general idea. It was not a general purpose mechanism for "we may add this impl later" but rather something very tailored to ! and Infallible.

So, the idea was to add this rather wacky reservation impl which permitted the stdlib to add From<!> impls and the like but which prevented downstream crates from doing so. That way, when we later redefined Infallible = !, we could remove the reservation impl.

It seems like we are at that point, so I believe removing the reservation impl makes sense -- or at least it does at the point where we redefine Infallible = !.

@nikomatsakis

Copy link
Copy Markdown
Contributor

(Independently, I think it'd be useful to have a syntax like impl<T> ?SomeTrait for Box<T> which would mean the more straightforward concept of: we are not adding this impl, but we are reserving the right to add it later.)

@jackh726

Copy link
Copy Markdown
Member

On the note: we should not be landing this PR separately. It should be done together with changing Infallible to !.

@traviscross

Copy link
Copy Markdown
Contributor

(We discussed this in the lang call today for context and to uncover the history and original motivation.)

@traviscross traviscross removed the I-lang-nominated Nominated for discussion during a lang team meeting. label Aug 12, 2026
@WaffleLapkin
WaffleLapkin force-pushed the unreserve_Fromᐸǃᐳ branch from 2f18485 to 7c696e5 Compare August 19, 2026 14:35
@rustbot

rustbot commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. labels Aug 24, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@JonathanBrouwer

Copy link
Copy Markdown
Member

borsrplus in the style of the ToysRUs logo

@rust-bors

rust-bors Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 7c696e5 has been approved by JonathanBrouwer

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 24, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
…JonathanBrouwer

Remove `From<!> for T` *reservation* impl

This PR removes the `<T> From<!> for T` *reservation* implementation added in rust-lang#62661 and tracked in rust-lang#64715 and rust-lang#64631.

The reservation impl in question was added in order to reserve some space for adding the following impl:
```rust
impl<T> From<!> for T {
    fn from(never: !) -> T { never }
}
```

It is meant to prevent users from writing *some* impls that would overlap if the `From<!> for T` impl is to be added.

This requires T-types FCP. Below is my proposal and necessary context:

## The reservation impl is not sufficient

The reservation impl prevents one from assuming that `From<!> for T` is not implemented making the following [not compile](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=220e375c77db9a88c360230283f888cb):

```rust
struct LocalType;
trait SomeTrait { }
impl<T: From<!>> SomeTrait for T { }
impl SomeTrait for LocalType { }
```

However, it does not prevent *all* implementation that would overlap given `From<!> for T`. Namely, `From<!> for T` would overlap with the following impls, all of which are currently permitted (and exist):
```rust
// T for T identity impl in `core`
impl<T> From<T> for T { ... }

// Various T->wrapper of T impls present in both the standard library,
// and in external crates
impl<T> From<T> for W<T> { ... }

// !->Local is also allowed
impl From<!> for Local {}
```

Also note that the reservation impl only exists for `From<!>`, but not for `From<Infallible>`, so even the impls that the reservation impl is meant to forbid, are currently allowed through `Infallible` anyway (we are planning to make `Infallible` a type alias to `!` at the same time as stabilizing `!`).

## Motivation for `From<!> for T` impl

It is surprisingly hard to find the original motivation for `From<!> for T` impl or the reservation impl, other than "people vaguely think that all types should implement `From<!>`, since there is never-to-any coercion".

One use-case seems to be "calling infallible function in a fallible one, and unwrapping `Result<_, !>` with `?`". However, nowdays it is trivial to unwrap the result safely without `?`:

```rust
let Ok(owo) = infallible_function();
```

Another use-case that I've seen [mentioned](rust-lang#62661 (comment)) is "fallible function with a set error, taking an infallible function":

```rust
fn try_from<T>(t: T) -> Result<Meow, MyError>
where
    Meow: TryFrom<T>,
    <Meow as TryFrom<T>>::Error: Into<MyError>
{ ... }
```

With such definition, you can't pass `Meow` into `try_from`, because `MyError: From<Infallible>` doesn't hold.

This is more unfortunate, but it's not clear how widespread this problem is and how bad the workarounds would be. If a function expects `impl FnOnce(...) -> Result<...>`, it should be trivial to coerce the `!` error to an appropriate type. With other trait bounds (like in the example above) it could be solved by adding a custom impl for your specific error type (annoying, but workable). Certaintly this doesn't feel like a big roadblock to me.

(let me know if you know more prior art on this)

## There is no clear path for adding `From<!> for T` impl

Adding `From<!> for T` seems... hard... and hard to argue for.

It would require ignoring overlap with a *bunch* of impls (as described above) and would also require low priority impls (to avoid inference failures in cases where previously the only applicable impl was the identity one, so adding `From<!>` makes "one impl rule" not apply).

The [tracking issue](rust-lang#64715) says:

> The precise mechanism to permit us to add the `From<!> for T` impl is not yet clear. The current "plan of record" is to extend the ["marker trait mechanism"](rust-lang#29864) to accommodate the idea of impls whose entire body consists of unreachable methods and to permit overlap.

Considering "traits with all methods having arguments of uninhabited types" as marker traits is technically possible (I think?), but feels like a bit of a stretch. Making overlap check consider if all trait functions take arguments which are uninhabited (known to be uninhabited *in the current context*) seems like a big complication, especially considering how `From<T>` would not be a marker trait in the general case — only `From<!>`/`From<OtherUninhabitedTypes>` would be (also that requires attaching the overlap check to some context from which we can check if a type is publically uninhabited, which can also lead to situations where impl `A` overlaps with impl `B`, but impl `B` doesn't overlap with impl `A`[^1]). Allowing overlap with arbitrary user impls also is likely to cause unforcene issues in my opinion.

[^1]: i.e. in the context of impl `A` a certain type is not known to be uninhabited, and thus the overlap between impls should not be allowed. at the same time in the context of impl `B` same type might be known to be uninhabited, allowing the overlap.

## The reservation impl causes problems for the never type stabilization

Because the reservation impl reserves space for `From<!> for T`, but not for `From<Infallible> for T`, making `Infallible` an alias for `!` makes some code fail to compile. See rust-lang#155924:

> 3. standard library contains a [reservation impl](https://doc.rust-lang.org/1.94.0/src/core/convert/mod.rs.html#802-806), which forbids [certain](rust-lang#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)

Given that both keeping the reservation impl (while making `Infallible = !`) and making the reservation a proper impl break code, we should decide which path we want to pursue before stabilizing the never type (and making `Infallible = !`).

## Proposal

After trying to add `From<!> for T` as a proper impl, I'm not convinced that it's worth the complexity and messiness of allowing such widespread overlap (with user defined impls too!). **As such, I propose to remove the reservation impl**, to prevent unnecessary breakage from its combination with making `Infallible = !`, as described above.

## Alternatives

- Add proper `impl<T> From<!> for T`, accepting the breakage, overlap, and the complexity.
    - I'm not sure how feasible this is, after trying to do this approach, it doesn't feel right
- Keep the reservation impl / add the reservation impl `From<Infallible> for T` formally accepting the breakage of that, with the hopes that we can still add `impl<T> From<!> for T` in the future
    - This is the most breaking of the option, as it breaks code that depends on `From<Infallible> for T`  not existing, *and* expects future breakage when adding `impl<T> From<!> for T`
    - It is unlikely that adding `impl<T> From<!> for T` in the future will be much easier than right now

-----

Closes rust-lang#64715
r? types

I'll remove the `rustc_reservation_impl` attribute in a separate PR (cc rust-lang#64631).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
…JonathanBrouwer

Remove `From<!> for T` *reservation* impl

This PR removes the `<T> From<!> for T` *reservation* implementation added in rust-lang#62661 and tracked in rust-lang#64715 and rust-lang#64631.

The reservation impl in question was added in order to reserve some space for adding the following impl:
```rust
impl<T> From<!> for T {
    fn from(never: !) -> T { never }
}
```

It is meant to prevent users from writing *some* impls that would overlap if the `From<!> for T` impl is to be added.

This requires T-types FCP. Below is my proposal and necessary context:

## The reservation impl is not sufficient

The reservation impl prevents one from assuming that `From<!> for T` is not implemented making the following [not compile](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=220e375c77db9a88c360230283f888cb):

```rust
struct LocalType;
trait SomeTrait { }
impl<T: From<!>> SomeTrait for T { }
impl SomeTrait for LocalType { }
```

However, it does not prevent *all* implementation that would overlap given `From<!> for T`. Namely, `From<!> for T` would overlap with the following impls, all of which are currently permitted (and exist):
```rust
// T for T identity impl in `core`
impl<T> From<T> for T { ... }

// Various T->wrapper of T impls present in both the standard library,
// and in external crates
impl<T> From<T> for W<T> { ... }

// !->Local is also allowed
impl From<!> for Local {}
```

Also note that the reservation impl only exists for `From<!>`, but not for `From<Infallible>`, so even the impls that the reservation impl is meant to forbid, are currently allowed through `Infallible` anyway (we are planning to make `Infallible` a type alias to `!` at the same time as stabilizing `!`).

## Motivation for `From<!> for T` impl

It is surprisingly hard to find the original motivation for `From<!> for T` impl or the reservation impl, other than "people vaguely think that all types should implement `From<!>`, since there is never-to-any coercion".

One use-case seems to be "calling infallible function in a fallible one, and unwrapping `Result<_, !>` with `?`". However, nowdays it is trivial to unwrap the result safely without `?`:

```rust
let Ok(owo) = infallible_function();
```

Another use-case that I've seen [mentioned](rust-lang#62661 (comment)) is "fallible function with a set error, taking an infallible function":

```rust
fn try_from<T>(t: T) -> Result<Meow, MyError>
where
    Meow: TryFrom<T>,
    <Meow as TryFrom<T>>::Error: Into<MyError>
{ ... }
```

With such definition, you can't pass `Meow` into `try_from`, because `MyError: From<Infallible>` doesn't hold.

This is more unfortunate, but it's not clear how widespread this problem is and how bad the workarounds would be. If a function expects `impl FnOnce(...) -> Result<...>`, it should be trivial to coerce the `!` error to an appropriate type. With other trait bounds (like in the example above) it could be solved by adding a custom impl for your specific error type (annoying, but workable). Certaintly this doesn't feel like a big roadblock to me.

(let me know if you know more prior art on this)

## There is no clear path for adding `From<!> for T` impl

Adding `From<!> for T` seems... hard... and hard to argue for.

It would require ignoring overlap with a *bunch* of impls (as described above) and would also require low priority impls (to avoid inference failures in cases where previously the only applicable impl was the identity one, so adding `From<!>` makes "one impl rule" not apply).

The [tracking issue](rust-lang#64715) says:

> The precise mechanism to permit us to add the `From<!> for T` impl is not yet clear. The current "plan of record" is to extend the ["marker trait mechanism"](rust-lang#29864) to accommodate the idea of impls whose entire body consists of unreachable methods and to permit overlap.

Considering "traits with all methods having arguments of uninhabited types" as marker traits is technically possible (I think?), but feels like a bit of a stretch. Making overlap check consider if all trait functions take arguments which are uninhabited (known to be uninhabited *in the current context*) seems like a big complication, especially considering how `From<T>` would not be a marker trait in the general case — only `From<!>`/`From<OtherUninhabitedTypes>` would be (also that requires attaching the overlap check to some context from which we can check if a type is publically uninhabited, which can also lead to situations where impl `A` overlaps with impl `B`, but impl `B` doesn't overlap with impl `A`[^1]). Allowing overlap with arbitrary user impls also is likely to cause unforcene issues in my opinion.

[^1]: i.e. in the context of impl `A` a certain type is not known to be uninhabited, and thus the overlap between impls should not be allowed. at the same time in the context of impl `B` same type might be known to be uninhabited, allowing the overlap.

## The reservation impl causes problems for the never type stabilization

Because the reservation impl reserves space for `From<!> for T`, but not for `From<Infallible> for T`, making `Infallible` an alias for `!` makes some code fail to compile. See rust-lang#155924:

> 3. standard library contains a [reservation impl](https://doc.rust-lang.org/1.94.0/src/core/convert/mod.rs.html#802-806), which forbids [certain](rust-lang#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)

Given that both keeping the reservation impl (while making `Infallible = !`) and making the reservation a proper impl break code, we should decide which path we want to pursue before stabilizing the never type (and making `Infallible = !`).

## Proposal

After trying to add `From<!> for T` as a proper impl, I'm not convinced that it's worth the complexity and messiness of allowing such widespread overlap (with user defined impls too!). **As such, I propose to remove the reservation impl**, to prevent unnecessary breakage from its combination with making `Infallible = !`, as described above.

## Alternatives

- Add proper `impl<T> From<!> for T`, accepting the breakage, overlap, and the complexity.
    - I'm not sure how feasible this is, after trying to do this approach, it doesn't feel right
- Keep the reservation impl / add the reservation impl `From<Infallible> for T` formally accepting the breakage of that, with the hopes that we can still add `impl<T> From<!> for T` in the future
    - This is the most breaking of the option, as it breaks code that depends on `From<Infallible> for T`  not existing, *and* expects future breakage when adding `impl<T> From<!> for T`
    - It is unlikely that adding `impl<T> From<!> for T` in the future will be much easier than right now

-----

Closes rust-lang#64715
r? types

I'll remove the `rustc_reservation_impl` attribute in a separate PR (cc rust-lang#64631).
rust-bors Bot pushed a commit that referenced this pull request Aug 24, 2026
…uwer

Rollup of 7 pull requests

Successful merges:

 - #161648 (`rust-analyzer` subtree update)
 - #160132 (make `pad_i32` of `PassMode::cast` an integer)
 - #160705 (Remove `From<!> for T` *reservation* impl)
 - #161600 (bootstrap: Rename `Build` to `Session`)
 - #161665 (delegation: add tests for delegations to inherent impls)
 - #161637 (Clarify token cursor behaviour)
 - #161653 (Add codegen test for Vec::clear lowering to an unconditional store)
@rust-bors
rust-bors Bot merged commit e9b6e63 into rust-lang:main Aug 24, 2026
13 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Aug 24, 2026
rust-bors Bot pushed a commit that referenced this pull request Aug 24, 2026
Rollup merge of #160705 - WaffleLapkin:unreserve_Fromᐸǃᐳ, r=JonathanBrouwer

Remove `From<!> for T` *reservation* impl

This PR removes the `<T> From<!> for T` *reservation* implementation added in #62661 and tracked in #64715 and #64631.

The reservation impl in question was added in order to reserve some space for adding the following impl:
```rust
impl<T> From<!> for T {
    fn from(never: !) -> T { never }
}
```

It is meant to prevent users from writing *some* impls that would overlap if the `From<!> for T` impl is to be added.

This requires T-types FCP. Below is my proposal and necessary context:

## The reservation impl is not sufficient

The reservation impl prevents one from assuming that `From<!> for T` is not implemented making the following [not compile](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=220e375c77db9a88c360230283f888cb):

```rust
struct LocalType;
trait SomeTrait { }
impl<T: From<!>> SomeTrait for T { }
impl SomeTrait for LocalType { }
```

However, it does not prevent *all* implementation that would overlap given `From<!> for T`. Namely, `From<!> for T` would overlap with the following impls, all of which are currently permitted (and exist):
```rust
// T for T identity impl in `core`
impl<T> From<T> for T { ... }

// Various T->wrapper of T impls present in both the standard library,
// and in external crates
impl<T> From<T> for W<T> { ... }

// !->Local is also allowed
impl From<!> for Local {}
```

Also note that the reservation impl only exists for `From<!>`, but not for `From<Infallible>`, so even the impls that the reservation impl is meant to forbid, are currently allowed through `Infallible` anyway (we are planning to make `Infallible` a type alias to `!` at the same time as stabilizing `!`).

## Motivation for `From<!> for T` impl

It is surprisingly hard to find the original motivation for `From<!> for T` impl or the reservation impl, other than "people vaguely think that all types should implement `From<!>`, since there is never-to-any coercion".

One use-case seems to be "calling infallible function in a fallible one, and unwrapping `Result<_, !>` with `?`". However, nowdays it is trivial to unwrap the result safely without `?`:

```rust
let Ok(owo) = infallible_function();
```

Another use-case that I've seen [mentioned](#62661 (comment)) is "fallible function with a set error, taking an infallible function":

```rust
fn try_from<T>(t: T) -> Result<Meow, MyError>
where
    Meow: TryFrom<T>,
    <Meow as TryFrom<T>>::Error: Into<MyError>
{ ... }
```

With such definition, you can't pass `Meow` into `try_from`, because `MyError: From<Infallible>` doesn't hold.

This is more unfortunate, but it's not clear how widespread this problem is and how bad the workarounds would be. If a function expects `impl FnOnce(...) -> Result<...>`, it should be trivial to coerce the `!` error to an appropriate type. With other trait bounds (like in the example above) it could be solved by adding a custom impl for your specific error type (annoying, but workable). Certaintly this doesn't feel like a big roadblock to me.

(let me know if you know more prior art on this)

## There is no clear path for adding `From<!> for T` impl

Adding `From<!> for T` seems... hard... and hard to argue for.

It would require ignoring overlap with a *bunch* of impls (as described above) and would also require low priority impls (to avoid inference failures in cases where previously the only applicable impl was the identity one, so adding `From<!>` makes "one impl rule" not apply).

The [tracking issue](#64715) says:

> The precise mechanism to permit us to add the `From<!> for T` impl is not yet clear. The current "plan of record" is to extend the ["marker trait mechanism"](#29864) to accommodate the idea of impls whose entire body consists of unreachable methods and to permit overlap.

Considering "traits with all methods having arguments of uninhabited types" as marker traits is technically possible (I think?), but feels like a bit of a stretch. Making overlap check consider if all trait functions take arguments which are uninhabited (known to be uninhabited *in the current context*) seems like a big complication, especially considering how `From<T>` would not be a marker trait in the general case — only `From<!>`/`From<OtherUninhabitedTypes>` would be (also that requires attaching the overlap check to some context from which we can check if a type is publically uninhabited, which can also lead to situations where impl `A` overlaps with impl `B`, but impl `B` doesn't overlap with impl `A`[^1]). Allowing overlap with arbitrary user impls also is likely to cause unforcene issues in my opinion.

[^1]: i.e. in the context of impl `A` a certain type is not known to be uninhabited, and thus the overlap between impls should not be allowed. at the same time in the context of impl `B` same type might be known to be uninhabited, allowing the overlap.

## The reservation impl causes problems for the never type stabilization

Because the reservation impl reserves space for `From<!> for T`, but not for `From<Infallible> for T`, making `Infallible` an alias for `!` makes some code fail to compile. See #155924:

> 3. standard library contains a [reservation impl](https://doc.rust-lang.org/1.94.0/src/core/convert/mod.rs.html#802-806), which forbids [certain](#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)

Given that both keeping the reservation impl (while making `Infallible = !`) and making the reservation a proper impl break code, we should decide which path we want to pursue before stabilizing the never type (and making `Infallible = !`).

## Proposal

After trying to add `From<!> for T` as a proper impl, I'm not convinced that it's worth the complexity and messiness of allowing such widespread overlap (with user defined impls too!). **As such, I propose to remove the reservation impl**, to prevent unnecessary breakage from its combination with making `Infallible = !`, as described above.

## Alternatives

- Add proper `impl<T> From<!> for T`, accepting the breakage, overlap, and the complexity.
    - I'm not sure how feasible this is, after trying to do this approach, it doesn't feel right
- Keep the reservation impl / add the reservation impl `From<Infallible> for T` formally accepting the breakage of that, with the hopes that we can still add `impl<T> From<!> for T` in the future
    - This is the most breaking of the option, as it breaks code that depends on `From<Infallible> for T`  not existing, *and* expects future breakage when adding `impl<T> From<!> for T`
    - It is unlikely that adding `impl<T> From<!> for T` in the future will be much easier than right now

-----

Closes #64715
r? types

I'll remove the `rustc_reservation_impl` attribute in a separate PR (cc #64631).
@WaffleLapkin
WaffleLapkin deleted the unreserve_Fromᐸǃᐳ branch August 24, 2026 17:09
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
… r=JonathanBrouwer

stabilize never type

### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](rust-lang#155499 (comment)) and [refresher on never type fallback](rust-lang#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- rust-lang#35121
- rust-lang#148922

### FCPs

- rust-lang#123508 (comment) (stabilization plan, T-lang)
- rust-lang#155499 (comment) (never type stabilization modulo bugs, T-lang)
- rust-lang#155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: rust-lang#141937
- Rust 2024 edition change:
   - rust-lang#123748
   - rust-lang#123508
- Various changes to lessen the effect of the breaking changes:
   - rust-lang#157820
   - rust-lang#156047
   - rust-lang#160705
- Never type documentation changes: rust-lang#158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: rust-lang#155499 (comment)
  - Analysis: rust-lang#155499 (comment)
  - Status of backports: rust-lang#155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: rust-lang#155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: rust-lang#155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: rust-lang#155657

---

Closes rust-lang#35121
Closes rust-lang#148922
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
… r=JonathanBrouwer

stabilize never type

### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](rust-lang#155499 (comment)) and [refresher on never type fallback](rust-lang#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- rust-lang#35121
- rust-lang#148922

### FCPs

- rust-lang#123508 (comment) (stabilization plan, T-lang)
- rust-lang#155499 (comment) (never type stabilization modulo bugs, T-lang)
- rust-lang#155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: rust-lang#141937
- Rust 2024 edition change:
   - rust-lang#123748
   - rust-lang#123508
- Various changes to lessen the effect of the breaking changes:
   - rust-lang#157820
   - rust-lang#156047
   - rust-lang#160705
- Never type documentation changes: rust-lang#158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: rust-lang#155499 (comment)
  - Analysis: rust-lang#155499 (comment)
  - Status of backports: rust-lang#155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: rust-lang#155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: rust-lang#155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: rust-lang#155657

---

Closes rust-lang#35121
Closes rust-lang#148922
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
… r=JonathanBrouwer

stabilize never type

### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](rust-lang#155499 (comment)) and [refresher on never type fallback](rust-lang#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- rust-lang#35121
- rust-lang#148922

### FCPs

- rust-lang#123508 (comment) (stabilization plan, T-lang)
- rust-lang#155499 (comment) (never type stabilization modulo bugs, T-lang)
- rust-lang#155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: rust-lang#141937
- Rust 2024 edition change:
   - rust-lang#123748
   - rust-lang#123508
- Various changes to lessen the effect of the breaking changes:
   - rust-lang#157820
   - rust-lang#156047
   - rust-lang#160705
- Never type documentation changes: rust-lang#158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: rust-lang#155499 (comment)
  - Analysis: rust-lang#155499 (comment)
  - Status of backports: rust-lang#155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: rust-lang#155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: rust-lang#155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: rust-lang#155657

---

Closes rust-lang#35121
Closes rust-lang#148922
rust-bors Bot pushed a commit that referenced this pull request Aug 24, 2026
…Brouwer

stabilize never type



### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](#155499 (comment)) and [refresher on never type fallback](#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- #35121
- #148922

### FCPs

- #123508 (comment) (stabilization plan, T-lang)
- #155499 (comment) (never type stabilization modulo bugs, T-lang)
- #155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: #141937
- Rust 2024 edition change:
   - #123748
   - #123508
- Various changes to lessen the effect of the breaking changes:
   - #157820
   - #156047
   - #160705
- Never type documentation changes: #158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: #155499 (comment)
  - Analysis: #155499 (comment)
  - Status of backports: #155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: #155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: #155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: #155657

---

Closes #35121
Closes #148922
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 24, 2026
… r=JonathanBrouwer

stabilize never type

### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](rust-lang#155499 (comment)) and [refresher on never type fallback](rust-lang#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- rust-lang#35121
- rust-lang#148922

### FCPs

- rust-lang#123508 (comment) (stabilization plan, T-lang)
- rust-lang#155499 (comment) (never type stabilization modulo bugs, T-lang)
- rust-lang#155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: rust-lang#141937
- Rust 2024 edition change:
   - rust-lang#123748
   - rust-lang#123508
- Various changes to lessen the effect of the breaking changes:
   - rust-lang#157820
   - rust-lang#156047
   - rust-lang#160705
- Never type documentation changes: rust-lang#158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: rust-lang#155499 (comment)
  - Analysis: rust-lang#155499 (comment)
  - Status of backports: rust-lang#155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: rust-lang#155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: rust-lang#155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: rust-lang#155657

---

Closes rust-lang#35121
Closes rust-lang#148922
rust-bors Bot pushed a commit that referenced this pull request Aug 24, 2026
…Brouwer

stabilize never type



### This PR

- stabilizes the [never type](https://doc.rust-lang.org/stable/std/primitive.never.html) (aka `!`) (!!!)
- sets the [never type fallback](https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html) to `!` on all editions (breaking change, see [crater report analysis](#155499 (comment)) and [refresher on never type fallback](#155499 (comment)))
- makes `Infallible` an alias to `!`
- removes `dependency_on_unit_never_type_fallback` lint (there is no more never type fallback to `()` so this lint can't be triggered)

### Cat
<img width="1024" height="683" alt="52270233795_5979a3174d_b" src="https://github.com/user-attachments/assets/f6b4737e-32ef-4c33-86b2-76b81673cf20" />

### Tracking

- #35121
- #148922

### FCPs

- #123508 (comment) (stabilization plan, T-lang)
- #155499 (comment) (never type stabilization modulo bugs, T-lang)
- #155924 (comment) (make `Infallible = !`, T-libs)

### Related changes

- Lint bump: #141937
- Rust 2024 edition change:
   - #123748
   - #123508
- Various changes to lessen the effect of the breaking changes:
   - #157820
   - #156047
   - #160705
- Never type documentation changes: #158370 (blocked on this pr)

### Experiments

- Fallback change and never type stabilization:
  - Run: #155499 (comment)
  - Analysis: #155499 (comment)
  - Status of backports: #155499 (comment)
- Fallback change, never type stabilization and making `Infallible = !`: #155500
- Fallback change, never type stabilization, making `Infallible = !`, and removing reservation impl: #155501
- Never type stabilization and `Infallible = !` change, _without_ fallback change: #155657

---

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

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-types Relevant to the types team, which will review and decide on the PR/issue. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking issue for reserved impl impl<T> From<!> for T