#![feature(generic_associated_types)] #![feature(associated_type_defaults)] // A Collection trait and collection families. Based on // https://smallcultfollowing.com/babysteps/blog/2016/11/03/ // associated-type-constructors-part-2-family-traits/ // check that we don't normalize with trait defaults. trait Collection { type Iter<'iter>: Iterator where T: 'iter, Self: 'iter; type Family: CollectionFamily; // Test associated type defaults with parameters type Sibling: Collection = <>::Family as CollectionFamily>::Member; fn empty() -> Self; fn add(&mut self, value: T); fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; } trait CollectionFamily { type Member: Collection; } struct VecFamily; impl CollectionFamily for VecFamily { type Member = Vec; } impl Collection for Vec { type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter; type Family = VecFamily; fn empty() -> Self { Vec::new() } fn add(&mut self, value: T) { self.push(value) } fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { self.iter() } } fn floatify_sibling(ints: &C) -> >::Sibling where C: Collection, { let mut res = ::Member::::empty(); for &v in ints.iterate() { res.add(v as f32); } res //~^ ERROR mismatched types } fn use_floatify() { let a = vec![1i32, 2, 3]; let c = floatify_sibling(&a); assert_eq!(Some(&1.0), c.iterate().next()); } fn main() { use_floatify(); }