use disjoint_impls::disjoint_impls; pub trait Dispatch { type Group: ?Sized; } pub enum GroupA {} pub enum GroupB {} pub enum GroupC {} pub enum GroupD {} impl Dispatch for (String, u32) { type Group = GroupA; } impl Dispatch for (Vec, u32) { type Group = GroupB; } impl Dispatch for (String, Vec) { type Group = GroupC; } impl Dispatch for (Vec, Vec) { type Group = GroupD; } disjoint_impls! { pub trait Kita { const NAME: &'static str; } impl Kita for (T, U) where (T, U): Dispatch { const NAME: &'static str = "Blanket A"; } impl Kita for (Vec, U) where (Vec, U): Dispatch { const NAME: &'static str = "Blanket B"; } impl Kita for (T, Vec) where (T, Vec): Dispatch { const NAME: &'static str = "Blanket C"; } impl Kita for (Vec, Vec) where (Vec, Vec): Dispatch { const NAME: &'static str = "Blanket D"; } } /* pub trait Kita { const NAME: &'static str; } const _: () = { pub trait _Kita0<_0: ?Sized> { const NAME: &'static str; } impl<_0, _1> _Kita0 for (_0, _1) where (_0, _1): Dispatch { const NAME: &'static str = "Blanket A"; } impl<_0, _1> _Kita0 for (Vec<_0>, _1) where (Vec<_0>, _1): Dispatch { const NAME: &'static str = "Blanket B"; } impl<_0, _1> _Kita0 for (_0, Vec<_1>) where (_0, Vec<_1>): Dispatch { const NAME: &'static str = "Blanket C"; } impl<_0, _1> _Kita0 for (Vec<_0>, Vec<_1>) where (Vec<_0>, Vec<_1>): Dispatch { const NAME: &'static str = "Blanket D"; } impl<_0, _1> Kita for (_0, _1) where (_0, _1): Dispatch, Self: _Kita0<<(_0, _1) as Dispatch>::Group> { const NAME: &'static str = ::Group>>::NAME; } }; */ fn main() { assert_eq!("Blanket A", <(String, u32)>::NAME); assert_eq!("Blanket B", <(Vec, u32)>::NAME); assert_eq!("Blanket C", <(String, Vec)>::NAME); assert_eq!("Blanket C", <(Vec, Vec)>::NAME); unimplemented!("Add what it expands to") }