summaryrefslogtreecommitdiffstats
path: root/src/test/ui/generic-associated-types/streaming_iterator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/generic-associated-types/streaming_iterator.rs')
-rw-r--r--src/test/ui/generic-associated-types/streaming_iterator.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/test/ui/generic-associated-types/streaming_iterator.rs b/src/test/ui/generic-associated-types/streaming_iterator.rs
new file mode 100644
index 000000000..e71b6805a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/streaming_iterator.rs
@@ -0,0 +1,76 @@
+// run-pass
+
+#![feature(generic_associated_types)]
+
+use std::fmt::Display;
+
+trait StreamingIterator {
+ type Item<'a> where Self: '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 + 'static> {
+ // 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>) where Self: '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 where Self: 'a;
+ 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();
+}