use disjoint_impls::disjoint_impls; pub trait Dispatch { type Group: ?Sized; } pub enum GroupA {} impl Dispatch for String { type Group = GroupA; } impl Dispatch for Vec { type Group = GroupA; } pub struct GroupB; impl Dispatch for &str { type Group = GroupB; } impl Dispatch for [u8] { type Group = GroupB; } disjoint_impls! { pub trait Kita { fn kita(&self) -> String; } impl> Kita for T { fn kita(&self) -> String { "Blanket A".to_owned() } } impl + ?Sized> Kita for T { fn kita(&self) -> String { "Blanket B".to_owned() } } } /* pub trait Kita { fn kita(&self) -> String; } const _: () = { pub trait _Kita0<_0: ?Sized> { fn kita(&self) -> String; } impl<_0: Dispatch> _Kita0 for _0 { fn kita(&self) -> String { "Blanket A".to_owned() } } impl<_0: Dispatch + ?Sized> _Kita0 for _0 { fn kita(&self) -> String { "Blanket B".to_owned() } } impl<_0> Kita for _0 where _0: ?Sized + Dispatch, Self: _Kita0<<_0 as Dispatch>::Group> { fn kita(&self) -> String { ::Group>>::kita(self) } } }; */ #[test] fn unsized_type() { assert_eq!("Blanket A", String::new().kita()); assert_eq!("Blanket A", Vec::::new().kita()); assert_eq!("Blanket B", b"bytestring"[..].kita()); assert_eq!("Blanket B", "kita".kita()); }