Description
The idea of a !=
constraint form in where
clauses has come up multiple times, in discussions of the where
clause itself, in rust-lang/rust#20041 as a counterpart to the ==
constraint form, and in various proposals for negative trait reasoning (!Trait
). I'd like to extract this idea into its own RFC.
Say we want to write a From
instance for !
reflecting its ability to implicitly cast to any type.
#![feature(never_type)]
trait From<T> {
fn from(T) -> Self;
}
impl<T> From<T> for T {
fn from(t: T) -> Self { t }
}
impl<T> From<!> for T {
fn from(t: !) -> Self { t }
}
This produces an overlapping error because both impl
s cover !: From<!>
. Specialization can't help here, as the first impl
does not fully contain the second. What's necessary is a way to limit the scope of the second impl
to exclude T == !
, avoiding the overlap altogether. I'd like to propose the following syntax:
#![feature(inequality_constraints)]
#![feature(never_type)]
trait From<T> {
fn from(T) -> Self;
}
impl<T> From<T> for T {
fn from(t: T) -> Self { t }
}
impl<T> From<!> for T where T != ! {
fn from(t: !) -> Self { t }
}
Negative reasoning for traits has been held up in the past due to concerns over implementing a trait for a new type becoming a breaking change. The ==
constraint has been held up due to an expectation that it would affect normalization (see rust-lang/rust#22074 (comment)). The !=
constraint doesn't suffer from either of these issues and can be very useful on its own, so I think it makes sense to split it off.