I want to avoid unimplementing a given auto trait for composite types containing a type for which the given auto trait is unimplemented.
I have this auto trait for anything that isn't ():
pub auto trait NotVoid {}
impl !NotVoid for () {}
I use this to mitigate conflicting implementations for the following trait; a Maybe trait which works similarly to Option but statically.
pub trait Maybe<T>
where
T: ?Sized {}
// This implementation conflicts with...
impl<T> Maybe<T> for T
where
T: ?Sized {}
// ...this one:
impl<T> Maybe<T> for ()
where
T: ?Sized {}
by doing this:
pub trait Maybe<T>
where
T: ?Sized {}
impl<T> Maybe<T> for T
where
T: ?Sized {}
impl<T> Maybe<T> for ()
where
T: NotVoid + ?Sized {}
which works fine. However, i've found this problem where if i have a composite type which is composed of (), it does not implement NotVoid, even though it's not an actual (). This makes sense in the case of auto traits such as Sync, Send and Copy, but this is not what i want to achieve with my NotVoid trait. For example:
struct A
{
nothing: ()
}
A does not implement NotVoid because it contains a (), even though it should (according to what i want NotVoid to do). How can i achieve a negative implementation of NotVoid only for (), but not for A and other composite types like it?
impl NotVoid for A {}, for which maybe you'd like to provide a derive macro. But yeah, auto traits are structural.auto traitwas designed. A composite type only implements the auto trait if all its contained types implement it.