]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | #![feature(associated_type_defaults)] |
2 | ||
3 | // A Collection trait and collection families. Based on | |
136023e0 | 4 | // https://smallcultfollowing.com/babysteps/blog/2016/11/03/ |
f035d41b XL |
5 | // associated-type-constructors-part-2-family-traits/ |
6 | ||
7 | // check that we don't normalize with trait defaults. | |
8 | ||
9 | trait Collection<T> { | |
3c0e092e | 10 | type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter; |
f035d41b XL |
11 | type Family: CollectionFamily; |
12 | // Test associated type defaults with parameters | |
13 | type Sibling<U>: Collection<U> = | |
14 | <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>; | |
15 | ||
16 | fn empty() -> Self; | |
17 | ||
18 | fn add(&mut self, value: T); | |
19 | ||
20 | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; | |
21 | } | |
22 | ||
23 | trait CollectionFamily { | |
24 | type Member<T>: Collection<T, Family = Self>; | |
25 | } | |
26 | ||
27 | struct VecFamily; | |
28 | ||
29 | impl CollectionFamily for VecFamily { | |
30 | type Member<T> = Vec<T>; | |
31 | } | |
32 | ||
33 | impl<T> Collection<T> for Vec<T> { | |
5e7ed085 | 34 | type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter; |
f035d41b XL |
35 | type Family = VecFamily; |
36 | ||
37 | fn empty() -> Self { | |
38 | Vec::new() | |
39 | } | |
40 | ||
41 | fn add(&mut self, value: T) { | |
42 | self.push(value) | |
43 | } | |
44 | ||
45 | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { | |
46 | self.iter() | |
47 | } | |
48 | } | |
49 | ||
50 | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32> | |
51 | where | |
52 | C: Collection<i32>, | |
53 | { | |
54 | let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty(); | |
55 | for &v in ints.iterate() { | |
56 | res.add(v as f32); | |
57 | } | |
58 | res | |
59 | //~^ ERROR mismatched types | |
60 | } | |
61 | ||
62 | fn use_floatify() { | |
63 | let a = vec![1i32, 2, 3]; | |
64 | let c = floatify_sibling(&a); | |
65 | assert_eq!(Some(&1.0), c.iterate().next()); | |
66 | } | |
67 | ||
68 | fn main() { | |
69 | use_floatify(); | |
70 | } |