Closed
Description
trait NotSame { }
impl NotSame for .. { }
impl<A> !NotSame for (A, A) { }
If I understand default impls right, it should be possible to express S != T
using (S, T): NotSame
. In fact this does work in some situations, but not generally.
doesn't work:
#![feature(optin_builtin_traits)]
trait NotSame { }
impl NotSame for .. { }
impl<A> !NotSame for (A, A) { }
fn f<T, U>(_: T, _: U) where (T, U): NotSame {}
struct S;
struct Z;
fn main() {
f(S, Z); // error: the trait `NotSame` is not implemented for the type `(_, _)`
f(S, S); // error: the trait `NotSame` is not implemented for the type `(_, _)`
}
but this does:
#![feature(optin_builtin_traits)]
use std::marker::PhantomData;
trait NotSame { }
impl NotSame for .. { }
impl<A> !NotSame for (A, A) { }
struct Choose<S, P>(PhantomData<(S, P)>);
struct Finally<P>(PhantomData<P>);
pub trait Chooser<T> {
fn num() -> usize;
}
impl<S, Q> Chooser<S> for Choose<S, Q> {
fn num() -> usize { 0 }
}
impl<S> Chooser<S> for Finally<S> {
fn num() -> usize { 0 }
}
impl<R, S, Q: Chooser<S>> Chooser<S> for Choose<R, Q>
where (S, R): NotSame
{
fn num() -> usize { Q::num().checked_add(1).unwrap() }
}
fn main() { }
Perhaps it only works when trying to ensure there are no conflicting impls? Perhaps it's not meant to work, and the second example is a hole?