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