]> git.lizzy.rs Git - rust.git/blob - src/test/ui/generic-associated-types/collections.rs
Rollup merge of #94019 - hermitcore:target, r=Mark-Simulacrum
[rust.git] / src / test / ui / generic-associated-types / collections.rs
1 #![feature(generic_associated_types)]
2 #![feature(associated_type_defaults)]
3
4 // A Collection trait and collection families. Based on
5 // https://smallcultfollowing.com/babysteps/blog/2016/11/03/
6 // associated-type-constructors-part-2-family-traits/
7
8 // run-pass
9
10 trait Collection<T> {
11     type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter;
12     type Family: CollectionFamily;
13     // Test associated type defaults with parameters
14     type Sibling<U>: Collection<U> =
15         <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
16
17     fn empty() -> Self;
18
19     fn add(&mut self, value: T);
20
21     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
22 }
23
24 trait CollectionFamily {
25     type Member<T>: Collection<T, Family = Self>;
26 }
27
28 struct VecFamily;
29
30 impl CollectionFamily for VecFamily {
31     type Member<T> = Vec<T>;
32 }
33
34 impl<T> Collection<T> for Vec<T> {
35     type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>;
36     type Family = VecFamily;
37
38     fn empty() -> Self {
39         Vec::new()
40     }
41
42     fn add(&mut self, value: T) {
43         self.push(value)
44     }
45
46     fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
47         self.iter()
48     }
49 }
50
51 fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
52 where
53     C: Collection<i32>,
54 {
55     let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
56     for &v in ints.iterate() {
57         res.add(v as f32);
58     }
59     res
60 }
61
62 fn use_floatify() {
63     let a = vec![1, 2, 3];
64     let b = floatify(&a);
65     assert_eq!(Some(&1.0), b.iterate().next());
66 }
67
68 fn main() {
69     use_floatify();
70 }