Skip to content

Tracking issue for rustc_reservation_impl attribute #64631

Closed

Description

@nikomatsakis

Background

The #[rustc_reservation_impl] attribute was added as part of the effort to stabilize !. Its goal is to make it possible to add a impl<T> From<!> for T impl in the future by disallowing downstream crates to do negative reasoning that might conflict with that.

Warning: the effect of this attribute is quite subtle, and it should be used with caution! In particular, adding a "reservation impl" alone does not guarantee that one can add the impl in the future, as described below.

History

Current blockers before this attribute can be used to affect end-users

Usage

You can use the #[rustc_reservation_impl] attribute as follows:

#[rustc_reservation_impl]
impl<T> From<!> for T { .. }

For the most part, rustc will act as though this impl does not exist. For example, users can add overlapping impls if they prefer:

struct LocalType1<T>(T);
impl<T> From<!> for LocalType1<T> { }

struct LocalType2<T>(T);
impl<T> From<T> for LocalType2<T> { }

Note that this implies that the #[rustc_reservation_impl] attribute alone does not guarantee that you can add the reservation impl in a future compatible way. Adding the reserved impl in the future may still cause coherence overlap (e.g., the impl for LocalType<T> for the impl for all T would overlap here). This will typically result in errors.

In order to add the impl, you must be able to ensure that coherence will allow the overlapping impls. This can be done in two ways, both of which are presently unstable:

  • Specialization: but be careful! e.g., the current specialization rules do not suffice in the LocalType2 example above, since neither impl is a subset of one another.
  • Marker traits: we have a notion of marker traits that are allowed to overlap. Marker traits currently must have no items, which excludes e.g. From, but we could grow this definition.

What does the attribute do?

The attribute prevents negative reasoning. In particular, it forbids impls like this:

trait LocalTrait;
struct LocalType3;
impl<T> LocalTrait for T where T: From<!> { }
impl<T> LocalTrait for LocalType3 { }

Without the reservation impl, this would be legal, because the crate may assume that LocalType: From<!> does not hold (since LocalType is local to the crate). With the reservation impl, however, code like this will get an error.

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    F-rustc_attrsInternal rustc attributes gated on the `#[rustc_attrs]` feature gate.
    on Sep 20, 2019
  2. added
    T-langRelevant to the language team
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    on Sep 20, 2019
  3. added a commit that references this issue on Nov 25, 2019
  4. nikomatsakis commented on Jun 22, 2022

    @nikomatsakis
    ContributorAuthor

    We visited this during lang team backlog bonanza. Conclusions:

    • This was never meant to be an end-user feature, it is a temporary crutch and at most perma-unstable.
    • It's quite special purpose to ! -- there could be a useful end-user feature of "reserving" space to add an impl later, but this feature permits people to add things that overlap the intended impl, because we wanted people to be able to add impl From<!> for MyType even though we couldn't yet add the blanket impl (can't remember why).
    • We didn't think it was a good idea to remove it immediately, because it might be useful if we move to stabilize ! again.
  5. added a commit that references this issue on May 6, 2023
  6. Pr0methean commented on Jun 2, 2023

    @Pr0methean

    I say we should fix whatever's preventing the blanket impl. Implementations of a method that the compiler can prove is unreachable shouldn't be able to conflict with each other -- otherwise it'd be like making Clone and Debug conflict just because they both don't implement kwyjibo(&self) -> (u32,u8,u8,u16,Result<Vec<u8>,Vec<()>>).

  7. clarfonthey commented on Jun 5, 2026

    @clarfonthey
    Contributor

    Worth commenting that shockingly, I found a use case for this outside of just the never type in the standard library: bringing ToOwned into core: #t-libs > core::borrow::Cow (cowcore)

    Effectively, it would allow saying "these impls for core types will be defined in the alloc crate" without supercharging #[rustc_allow_incoherent_impl] to just tell the compiler to shut up on arbitrary trait/impl definitions, which would probably break the solver.

    My thought process is also that associated types would be treated as opaque for the sake of the solver, where the actual value of the type doesn't matter since the impls can't be used.

  8. JonathanBrouwer commented on Aug 18, 2026

    @JonathanBrouwer
    Member

    For people looking into this, including my future self:

    #160871 will remove this attribute after #160705 lands
    @clarfonthey mentioned in #160871 (comment) that the current implementation of #[rustc_allow_incoherent_impl] is not a good fit for their bringing ToOwned into core idea, so this is not a blocker

  9. added 3 commits that reference this issue on Aug 24, 2026
  10. added a commit that references this issue on Aug 24, 2026
  11. added a commit that references this issue on Aug 25, 2026
  12. added a commit that references this issue on Aug 25, 2026
  13. clarfonthey commented on Aug 25, 2026

    @clarfonthey
    Contributor

    I'm not sure exactly where I should bring up that option for allow_incoherent_impl as a potential solution. A lot of them may just be replaced by build-std eventually merging the libstd crates again.

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-trait-systemArea: Trait systemC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-rustc_attrsInternal rustc attributes gated on the `#[rustc_attrs]` feature gate.S-tracking-perma-unstableStatus: The feature will stay unstable indefinitely.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions