Implement Iterator::last for vec::IntoIter

This commit is contained in:
Thalia Archibald 2025-04-12 17:49:53 -07:00
parent dd5113daab
commit 3564afaa77
5 changed files with 46 additions and 7 deletions

View file

@ -84,6 +84,19 @@ fn issue_14139() {
}
fn drop_order() {
struct DropDeIterator(std::vec::IntoIter<S>);
impl Iterator for DropDeIterator {
type Item = S;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl DoubleEndedIterator for DropDeIterator {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}
struct S(&'static str);
impl std::ops::Drop for S {
fn drop(&mut self) {
@ -92,7 +105,7 @@ fn drop_order() {
}
let v = vec![S("one"), S("two"), S("three")];
let mut v = v.into_iter();
let mut v = DropDeIterator(v.into_iter());
println!("Last element is {}", v.next_back().unwrap().0);
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
println!("Done");

View file

@ -84,6 +84,19 @@ fn issue_14139() {
}
fn drop_order() {
struct DropDeIterator(std::vec::IntoIter<S>);
impl Iterator for DropDeIterator {
type Item = S;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl DoubleEndedIterator for DropDeIterator {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}
struct S(&'static str);
impl std::ops::Drop for S {
fn drop(&mut self) {
@ -92,7 +105,7 @@ fn drop_order() {
}
let v = vec![S("one"), S("two"), S("three")];
let v = v.into_iter();
let v = DropDeIterator(v.into_iter());
println!("Last element is {}", v.last().unwrap().0);
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
println!("Done");

View file

@ -18,7 +18,7 @@ LL | let _ = DeIterator.last();
| help: try: `next_back()`
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
--> tests/ui/double_ended_iterator_last.rs:96:36
--> tests/ui/double_ended_iterator_last.rs:109:36
|
LL | println!("Last element is {}", v.last().unwrap().0);
| ^^^^^^^^
@ -26,7 +26,7 @@ LL | println!("Last element is {}", v.last().unwrap().0);
= note: this change will alter drop order which may be undesirable
help: try
|
LL ~ let mut v = v.into_iter();
LL ~ let mut v = DropDeIterator(v.into_iter());
LL ~ println!("Last element is {}", v.next_back().unwrap().0);
|

View file

@ -11,6 +11,19 @@ fn main() {
}
fn drop_order() {
struct DropDeIterator(std::vec::IntoIter<S>);
impl Iterator for DropDeIterator {
type Item = S;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl DoubleEndedIterator for DropDeIterator {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}
struct S(&'static str);
impl std::ops::Drop for S {
fn drop(&mut self) {
@ -19,7 +32,7 @@ fn drop_order() {
}
let v = vec![S("one"), S("two"), S("three")];
let v = (v.into_iter(), 42);
let v = (DropDeIterator(v.into_iter()), 42);
println!("Last element is {}", v.0.last().unwrap().0);
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
println!("Done");

View file

@ -1,5 +1,5 @@
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
--> tests/ui/double_ended_iterator_last_unfixable.rs:23:36
--> tests/ui/double_ended_iterator_last_unfixable.rs:36:36
|
LL | println!("Last element is {}", v.0.last().unwrap().0);
| ^^^^------
@ -8,7 +8,7 @@ LL | println!("Last element is {}", v.0.last().unwrap().0);
|
= note: this change will alter drop order which may be undesirable
note: this must be made mutable to use `.next_back()`
--> tests/ui/double_ended_iterator_last_unfixable.rs:23:36
--> tests/ui/double_ended_iterator_last_unfixable.rs:36:36
|
LL | println!("Last element is {}", v.0.last().unwrap().0);
| ^^^