|
| 1 | +#![crate_type = "lib"] |
| 2 | + |
| 3 | +// This test is an example of a filtering lending iterator with GATs from #92985 (that is similar to |
| 4 | +// NLL problem case #3) to ensure it "works" with the polonius alpha analysis as with the datalog |
| 5 | +// implementation. |
| 6 | +// |
| 7 | +// The polonius analysis only changes how the `Filter::next` function is borrowcked, not the bounds |
| 8 | +// on the predicate from using the GAT. So even if the #92985 limitation is removed, the unrelated |
| 9 | +// 'static limitation on the predicate argument is still there, and the pattern is still impractical |
| 10 | +// to use in the real world. |
| 11 | + |
| 12 | +//@ ignore-compare-mode-polonius (explicit revisions) |
| 13 | +//@ revisions: nll polonius legacy |
| 14 | +//@ [nll] known-bug: #92985 |
| 15 | +//@ [polonius] check-pass |
| 16 | +//@ [polonius] compile-flags: -Z polonius=next |
| 17 | +//@ [legacy] check-pass |
| 18 | +//@ [legacy] compile-flags: -Z polonius=legacy |
| 19 | + |
| 20 | +trait LendingIterator { |
| 21 | + type Item<'a> |
| 22 | + where |
| 23 | + Self: 'a; |
| 24 | + fn next(&mut self) -> Option<Self::Item<'_>>; |
| 25 | + |
| 26 | + fn filter<P>(self, predicate: P) -> Filter<Self, P> |
| 27 | + where |
| 28 | + Self: Sized, |
| 29 | + P: FnMut(&Self::Item<'_>) -> bool, |
| 30 | + { |
| 31 | + Filter { iter: self, predicate } |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +pub struct Filter<I, P> { |
| 36 | + iter: I, |
| 37 | + predicate: P, |
| 38 | +} |
| 39 | +impl<I: LendingIterator, P> LendingIterator for Filter<I, P> |
| 40 | +where |
| 41 | + P: FnMut(&I::Item<'_>) -> bool, |
| 42 | +{ |
| 43 | + type Item<'a> |
| 44 | + = I::Item<'a> |
| 45 | + where |
| 46 | + Self: 'a; |
| 47 | + |
| 48 | + fn next(&mut self) -> Option<I::Item<'_>> { |
| 49 | + while let Some(item) = self.iter.next() { |
| 50 | + if (self.predicate)(&item) { |
| 51 | + return Some(item); |
| 52 | + } |
| 53 | + } |
| 54 | + return None; |
| 55 | + } |
| 56 | +} |
0 commit comments