| // run-pass |
| |
| #![allow(incomplete_features)] |
| #![feature(generic_associated_types)] |
| |
| use std::fmt::Display; |
| |
| trait StreamingIterator { |
| type Item<'a>; |
| // Applying the lifetime parameter `'a` to `Self::Item` inside the trait. |
| fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>; |
| } |
| |
| struct Foo<T: StreamingIterator> { |
| // Applying a concrete lifetime to the constructor outside the trait. |
| bar: <T as StreamingIterator>::Item<'static>, |
| } |
| |
| // Users can bound parameters by the type constructed by that trait's associated type constructor |
| // of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid: |
| //FIXME(#44265): This next line should parse and be valid |
| //fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ } |
| fn _foo<T>(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } |
| |
| // Full example of enumerate iterator |
| |
| #[must_use = "iterators are lazy and do nothing unless consumed"] |
| struct StreamEnumerate<I> { |
| iter: I, |
| count: usize, |
| } |
| |
| impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> { |
| type Item<'a> = (usize, I::Item<'a>); |
| fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> { |
| match self.iter.next() { |
| None => None, |
| Some(val) => { |
| let r = Some((self.count, val)); |
| self.count += 1; |
| r |
| } |
| } |
| } |
| } |
| |
| impl<I: Iterator> StreamingIterator for I { |
| type Item<'a> = <I as Iterator>::Item; |
| fn next(&mut self) -> Option<<I as StreamingIterator>::Item<'_>> { |
| Iterator::next(self) |
| } |
| } |
| |
| impl<I> StreamEnumerate<I> { |
| pub fn new(iter: I) -> Self { |
| StreamEnumerate { |
| count: 0, |
| iter, |
| } |
| } |
| } |
| |
| fn test_stream_enumerate() { |
| let v = vec!["a", "b", "c"]; |
| let mut se = StreamEnumerate::new(v.iter()); |
| while let Some(item) = se.next() { |
| assert_eq!(v[item.0], *item.1); |
| } |
| let x = Foo::<std::slice::Iter<'static, u32>> { |
| bar: &0u32, |
| }; |
| assert_eq!(*x.bar, 0u32); |
| } |
| |
| fn main() { |
| test_stream_enumerate(); |
| } |