diff options
| author | Rémy Rakic <remy.rakic+github@gmail.com> | 2025-08-07 13:06:35 +0000 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic+github@gmail.com> | 2025-08-07 13:06:35 +0000 |
| commit | e3aae6162e7f0bdacb8b41c7b2f1d92100a0c476 (patch) | |
| tree | 4500478e89556d58b482ca1d6ae9d9385cb7cf68 | |
| parent | d6dc3634dbd3ccfaf13bce4422afa5449b1ce2c8 (diff) | |
| download | rust-e3aae6162e7f0bdacb8b41c7b2f1d92100a0c476.tar.gz rust-e3aae6162e7f0bdacb8b41c7b2f1d92100a0c476.zip | |
add filtering lending iterator known-bug
| -rw-r--r-- | tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr | 14 | ||||
| -rw-r--r-- | tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs | 56 |
2 files changed, 70 insertions, 0 deletions
diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr new file mode 100644 index 00000000000..d5c85a2af23 --- /dev/null +++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.nll.stderr @@ -0,0 +1,14 @@ +error[E0499]: cannot borrow `self.iter` as mutable more than once at a time + --> $DIR/filtering-lending-iterator-issue-92985.rs:49:32 + | +LL | fn next(&mut self) -> Option<I::Item<'_>> { + | - let's call the lifetime of this reference `'1` +LL | while let Some(item) = self.iter.next() { + | ^^^^^^^^^ `self.iter` was mutably borrowed here in the previous iteration of the loop +LL | if (self.predicate)(&item) { +LL | return Some(item); + | ---------- returning this value requires that `self.iter` is borrowed for `'1` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs new file mode 100644 index 00000000000..27da62ef00b --- /dev/null +++ b/tests/ui/nll/polonius/filtering-lending-iterator-issue-92985.rs @@ -0,0 +1,56 @@ +#![crate_type = "lib"] + +// This test is an example of a filtering lending iterator with GATs from #92985 (that is similar to +// NLL problem case #3) to ensure it "works" with the polonius alpha analysis as with the datalog +// implementation. +// +// The polonius analysis only changes how the `Filter::next` function is borrowcked, not the bounds +// on the predicate from using the GAT. So even if the #92985 limitation is removed, the unrelated +// 'static limitation on the predicate argument is still there, and the pattern is still impractical +// to use in the real world. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #92985 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +trait LendingIterator { + type Item<'a> + where + Self: 'a; + fn next(&mut self) -> Option<Self::Item<'_>>; + + fn filter<P>(self, predicate: P) -> Filter<Self, P> + where + Self: Sized, + P: FnMut(&Self::Item<'_>) -> bool, + { + Filter { iter: self, predicate } + } +} + +pub struct Filter<I, P> { + iter: I, + predicate: P, +} +impl<I: LendingIterator, P> LendingIterator for Filter<I, P> +where + P: FnMut(&I::Item<'_>) -> bool, +{ + type Item<'a> + = I::Item<'a> + where + Self: 'a; + + fn next(&mut self) -> Option<I::Item<'_>> { + while let Some(item) = self.iter.next() { + if (self.predicate)(&item) { + return Some(item); + } + } + return None; + } +} |
