Skip to content

Commit 978a3cb

Browse files
committed
Implement Iterator::last for vec::IntoIter
1 parent 092a284 commit 978a3cb

6 files changed

+51
-7
lines changed

Diff for: library/alloc/src/vec/into_iter.rs

+5
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
258258
self.len()
259259
}
260260

261+
#[inline]
262+
fn last(mut self) -> Option<T> {
263+
self.next_back()
264+
}
265+
261266
#[inline]
262267
fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
263268
let mut raw_ary = [const { MaybeUninit::uninit() }; N];

Diff for: src/tools/clippy/tests/ui/double_ended_iterator_last.fixed

+14-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@ fn issue_14139() {
7777
}
7878

7979
fn drop_order() {
80+
struct DropDeIterator(std::vec::IntoIter<S>);
81+
impl Iterator for DropDeIterator {
82+
type Item = S;
83+
fn next(&mut self) -> Option<Self::Item> {
84+
self.0.next()
85+
}
86+
}
87+
impl DoubleEndedIterator for DropDeIterator {
88+
fn next_back(&mut self) -> Option<Self::Item> {
89+
self.0.next_back()
90+
}
91+
}
92+
8093
struct S(&'static str);
8194
impl std::ops::Drop for S {
8295
fn drop(&mut self) {
@@ -85,7 +98,7 @@ fn drop_order() {
8598
}
8699

87100
let v = vec![S("one"), S("two"), S("three")];
88-
let mut v = v.into_iter();
101+
let mut v = DropDeIterator(v.into_iter());
89102
println!("Last element is {}", v.next_back().unwrap().0);
90103
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
91104
println!("Done");

Diff for: src/tools/clippy/tests/ui/double_ended_iterator_last.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@ fn issue_14139() {
7777
}
7878

7979
fn drop_order() {
80+
struct DropDeIterator(std::vec::IntoIter<S>);
81+
impl Iterator for DropDeIterator {
82+
type Item = S;
83+
fn next(&mut self) -> Option<Self::Item> {
84+
self.0.next()
85+
}
86+
}
87+
impl DoubleEndedIterator for DropDeIterator {
88+
fn next_back(&mut self) -> Option<Self::Item> {
89+
self.0.next_back()
90+
}
91+
}
92+
8093
struct S(&'static str);
8194
impl std::ops::Drop for S {
8295
fn drop(&mut self) {
@@ -85,7 +98,7 @@ fn drop_order() {
8598
}
8699

87100
let v = vec![S("one"), S("two"), S("three")];
88-
let v = v.into_iter();
101+
let v = DropDeIterator(v.into_iter());
89102
println!("Last element is {}", v.last().unwrap().0);
90103
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
91104
println!("Done");

Diff for: src/tools/clippy/tests/ui/double_ended_iterator_last.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ LL ~ let _ = subindex.next_back();
6666
|
6767

6868
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
69-
--> tests/ui/double_ended_iterator_last.rs:89:36
69+
--> tests/ui/double_ended_iterator_last.rs:102:36
7070
|
7171
LL | println!("Last element is {}", v.last().unwrap().0);
7272
| ^^^^^^^^
7373
|
7474
= note: this change will alter drop order which may be undesirable
7575
help: try
7676
|
77-
LL ~ let mut v = v.into_iter();
77+
LL ~ let mut v = DropDeIterator(v.into_iter());
7878
LL ~ println!("Last element is {}", v.next_back().unwrap().0);
7979
|
8080

Diff for: src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ fn main() {
88
}
99

1010
fn drop_order() {
11+
struct DropDeIterator(std::vec::IntoIter<S>);
12+
impl Iterator for DropDeIterator {
13+
type Item = S;
14+
fn next(&mut self) -> Option<Self::Item> {
15+
self.0.next()
16+
}
17+
}
18+
impl DoubleEndedIterator for DropDeIterator {
19+
fn next_back(&mut self) -> Option<Self::Item> {
20+
self.0.next_back()
21+
}
22+
}
23+
1124
struct S(&'static str);
1225
impl std::ops::Drop for S {
1326
fn drop(&mut self) {
@@ -16,7 +29,7 @@ fn drop_order() {
1629
}
1730

1831
let v = vec![S("one"), S("two"), S("three")];
19-
let v = (v.into_iter(), 42);
32+
let v = (DropDeIterator(v.into_iter()), 42);
2033
println!("Last element is {}", v.0.last().unwrap().0);
2134
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
2235
println!("Done");

Diff for: src/tools/clippy/tests/ui/double_ended_iterator_last_unfixable.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | let _ = subindex.0.last();
1515
= help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]`
1616

1717
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
18-
--> tests/ui/double_ended_iterator_last_unfixable.rs:20:36
18+
--> tests/ui/double_ended_iterator_last_unfixable.rs:33:36
1919
|
2020
LL | println!("Last element is {}", v.0.last().unwrap().0);
2121
| ^^^^------
@@ -24,7 +24,7 @@ LL | println!("Last element is {}", v.0.last().unwrap().0);
2424
|
2525
= note: this change will alter drop order which may be undesirable
2626
note: this must be made mutable to use `.next_back()`
27-
--> tests/ui/double_ended_iterator_last_unfixable.rs:20:36
27+
--> tests/ui/double_ended_iterator_last_unfixable.rs:33:36
2828
|
2929
LL | println!("Last element is {}", v.0.last().unwrap().0);
3030
| ^^^

0 commit comments

Comments
 (0)