Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nikomatsakis opened this issue Sep 23, 2019 · 2 comments
Open

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

nikomatsakis opened this issue Sep 23, 2019 · 2 comments
Labels
A-traits Area: Trait system C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. S-tracking-perma-unstable Status: The feature will stay unstable indefinitely. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

Background

This is a tracking issue for a temporary limitation related to the From trait and the ! type. Specifically, we wish to eventually add an impl like the following:

impl<T> From<!> to T { }

We cannot do so now because it would overlap with existing impls. Specifically, the impl impl<T> From<T> for T as well as impls of the form impl<T> From<T> for Foo<T>, which exist for a number of smart pointer types. There are some plans for how we might add such an impl in the future, described below.

What is allowed today

Currently you are permitted to add impls of From<!> for your own types:

struct LocalType;
impl From<!> for LocalType { }

This is true even though such impls will overlap our planned addition: after all, we already have a number of overlapping cases to deal with.

However, you are not permitted to assume that From<!> is not implemented. If that double negative threw you for a loop, consider this example (which will not compile):

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

Here, the two impls do not presently overlap. This is because LocalType: From<!> is not implemented. However, if we were to add the impl<T> From<!> for T impl that we would like to add, then these two impls would start to overlap, and your code would stop compiling. Thus we say that this program assumes that From<!> is not implemented -- because it cannot pass the coherence check unless that is the case. This is precisely the sort of case that is not currently allowed. For more information, see RFC 1023, which introduced the rules limiting negative reasoning.

How might we add the reserved impl in the future?

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.

cc #64631 -- the internal rustc mechanism used to achieve this limitation

@nikomatsakis nikomatsakis added A-traits Area: Trait system T-lang Relevant to the language team, which will review and decide on the PR/issue. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. labels Sep 23, 2019
@AaronKutch
Copy link
Contributor

AaronKutch commented Feb 12, 2020

Edit: nevermind, the fix was #69448

Will this fix the problem I am having refactoring the apint crate? I am refactoring some code involving the invariant management type BitWidth. There are many function arguments whose signature I want to change to TryInto<BitWidth, Error=CrateErrorType>. When I update the signatures, is enables one ergonomic feature where I can directly input a literal into the function (due to a TryFrom<usize> impl for BitWidth), but at the same time disables inputing a simple BitWidth into the function.

The reason for this is the blanket impl impl TryFrom<T> for T which has return type Error=Infallible which conflicts with the Error=CrateErrorType bound, thus causing a collision when entering any plain Type into an argument with the bound TryInto<Type, Error=ErrorType>.

@nikomatsakis
Copy link
Contributor Author

@AaronKutch this is not an end-user facing feature, so it won't really fix anything with your crate. It was intended as a way for us to stabilize ! without closing the door to adding a impl From<!> for T impl in the future (though other problems arose that precluded us from stabilizing ! for the moment).

@joshtriplett joshtriplett added the S-tracking-perma-unstable Status: The feature will stay unstable indefinitely. label Jun 22, 2022
bors added a commit to rust-lang/rust-analyzer that referenced this issue May 6, 2023
fix: ignore impls with `#[rustc_reservation_impl]`

Fixes #12247
Fixes #14279

Currently core has two blanket impls for `From`: `impl<T> From<T> for T` and `impl<T> From<!> for T`. These are conflicting and thus chalk cannot uniquely solve `S: From<?0>` for any type `S`.

The latter impl is actually a reservation impl and should not be considered during trait selection. More generally, impls attributed with perma-unstable `#[rustc_reservation_impl]` attribute should be disregarded except for coherence checks. See rust-lang/rust#64631 and rust-lang/rust#64715 for details.

I chose to entirely ignore them in hir-ty because we don't do coherence checks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. S-tracking-perma-unstable Status: The feature will stay unstable indefinitely. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants