use disjoint_impls::disjoint_impls; pub trait Dispatch { type Group; } pub enum GroupA {} impl Dispatch for String { type Group = GroupA; } impl Dispatch for Vec { type Group = GroupA; } pub enum GroupB {} impl Dispatch for i32 { type Group = GroupB; } impl Dispatch for u32 { type Group = GroupB; } disjoint_impls! { pub trait Kita { const NAME: &'static str; } impl> Kita for T { const NAME: &'static str = "Blanket A"; } impl> Kita for U { const NAME: &'static str = "Blanket B"; } impl, U: Dispatch> Kita for (T, U) { const NAME: &'static str = "Blanket AA"; } impl Kita for (U, T) where U: Dispatch, T: Dispatch { const NAME: &'static str = "Blanket AB"; } impl, U: Dispatch> Kita for (T, U) { const NAME: &'static str = "Blanket B*"; } } /* pub trait Kita { const NAME: &'static str; } const _: () = { pub trait _Kita0<_0: ?Sized> { const NAME: &'static str; } pub trait _Kita1<_0: ?Sized, _1: ?Sized> { const NAME: &'static str; } impl<_0: Dispatch> _Kita0 for _0 { const NAME: &'static str = "Blanket A"; } impl<_0: Dispatch> _Kita0 for _0 { const NAME: &'static str = "Blanket B"; } impl<_0: Dispatch, _1: Dispatch> _Kita1 for (_0, _1) { const NAME: &'static str = "Blanket AA"; } impl<_0, _1> _Kita1 for (_0, _1) where _0: Dispatch, _1: Dispatch { const NAME: &'static str = "Blanket AB"; } impl<_0: Dispatch, _1: Dispatch> _Kita1::Group> for (_0, _1) { const NAME: &'static str = "Blanket B*"; } impl<_0> Kita for _0 where _0: Dispatch, Self: _Kita0<<_0 as Dispatch>::Group> { const NAME: &'static str = ::Group>>::NAME; } impl<_0, _1> Kita for (_0, _1) where _0: Dispatch, _1: Dispatch, Self: _Kita1<<_0 as Dispatch>::Group, <_1 as Dispatch>::Group> { const NAME: &'static str = ::Group, <_1 as Dispatch>::Group>>::NAME; } }; */ #[test] fn multiple_blanket_impls() { assert_eq!("Blanket A", String::NAME); assert_eq!("Blanket A", Vec::::NAME); assert_eq!("Blanket B", u32::NAME); assert_eq!("Blanket B", i32::NAME); assert_eq!("Blanket AA", <(String, String)>::NAME); assert_eq!("Blanket AB", <(String, u32)>::NAME); assert_eq!("Blanket B*", <(u32, i32)>::NAME); }