Tracking issue for reserved impl impl<T> From<!> for T · Issue #64715 · rust-lang/rust (original) (raw)

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:

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