Open
Description
Summary
.last()
consumes its receiver, while .next_back()
only takes a mutable reference to it. While #14140 warns about the possible change in drop order if iterator elements implement Drop
, this might still extend the lifetime of the iterator, which might be problematic if it holds a reference.
Lint Name
No response
Reproducer
I tried this code:
struct T<'a> {
t: Option<&'a str>,
}
impl<'a> T<'a> {
fn new(t: &'a str) -> Self {
Self { t: Some(t) }
}
}
impl Drop for T<'_> {
fn drop(&mut self) {
}
}
impl Iterator for T<'_> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
self.t.take().map(|s| s.to_string())
}
}
impl DoubleEndedIterator for T<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
}
fn main() {
let mut s = String::from("hello");
let it = T::new(&s);
println!("last = {}", it.last().unwrap());
s.push_str(", world!");
println!("s = {s}");
}
I saw this happen when running Clippy:
32 | println!("last = {}", it.last().unwrap());
| ^^^^^^ help: try: `next_back()`
which does not compile (even after applying #14140 to make it
mutable).
I expected to see one of those happen:
- No lint (but that would prevent a performance gain)
- Make
it
droppable, by suggesting, for example,{ it }.next_back()
instead ofit.last()
..last()
to.next_back()
requires a mutable receiver #14140 does this when it cannot make the receiver mutable easily already.
Version
rustc 1.86.0-nightly (a9730c3b5 2025-02-05)
binary: rustc
commit-hash: a9730c3b5f84a001c052c60c97ed0765e9ceac04
commit-date: 2025-02-05
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
Additional Labels
@rustbot label +I-suggestion-causes-error