Skip to content

Commit bf8d470

Browse files
committed
WIP: use in double_ended_iterator_last
the unfixable warning is now fixable, but that's kind of a problem because the `_unfixable` file doesn't have any error patterns left, which uitest complains about
1 parent 0449954 commit bf8d470

6 files changed

+28
-50
lines changed

clippy_lints/src/methods/double_ended_iterator_last.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::ty::{has_non_owning_mutable_access, implements_trait};
3-
use clippy_utils::{is_mutable, is_trait_method, path_to_local, sym};
3+
use clippy_utils::{is_mutable, is_trait_method, path_to_local_with_projections, sym};
44
use rustc_errors::Applicability;
55
use rustc_hir::{Expr, Node, PatKind};
66
use rustc_lint::LateContext;
@@ -37,7 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp
3737
// TODO: Change this to lint only when the referred iterator is not used later. If it is used later,
3838
// changing to `next_back()` may change its behavior.
3939
if !(is_mutable(cx, self_expr) || self_type.is_ref()) {
40-
if let Some(hir_id) = path_to_local(self_expr)
40+
if let Some(hir_id) = path_to_local_with_projections(self_expr)
4141
&& let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
4242
&& let PatKind::Binding(_, _, ident, _) = pat.kind
4343
{

tests/ui/double_ended_iterator_last.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ fn drop_order() {
108108
let mut v = DropDeIterator(v.into_iter());
109109
println!("Last element is {}", v.next_back().unwrap().0);
110110
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
111+
112+
let v = vec![S("one"), S("two"), S("three")];
113+
let mut v = (DropDeIterator(v.into_iter()), 42);
114+
println!("Last element is {}", v.0.next_back().unwrap().0);
115+
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
116+
111117
println!("Done");
112118
}
113119

tests/ui/double_ended_iterator_last.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ fn drop_order() {
108108
let v = DropDeIterator(v.into_iter());
109109
println!("Last element is {}", v.last().unwrap().0);
110110
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
111+
112+
let v = vec![S("one"), S("two"), S("three")];
113+
let v = (DropDeIterator(v.into_iter()), 42);
114+
println!("Last element is {}", v.0.last().unwrap().0);
115+
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
116+
111117
println!("Done");
112118
}
113119

tests/ui/double_ended_iterator_last.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,18 @@ LL ~ let mut v = DropDeIterator(v.into_iter());
3030
LL ~ println!("Last element is {}", v.next_back().unwrap().0);
3131
|
3232

33-
error: aborting due to 3 previous errors
33+
error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator
34+
--> tests/ui/double_ended_iterator_last.rs:114:36
35+
|
36+
LL | println!("Last element is {}", v.0.last().unwrap().0);
37+
| ^^^^^^^^^^
38+
|
39+
= note: this change will alter drop order which may be undesirable
40+
help: try
41+
|
42+
LL ~ let mut v = (DropDeIterator(v.into_iter()), 42);
43+
LL ~ println!("Last element is {}", v.0.next_back().unwrap().0);
44+
|
45+
46+
error: aborting due to 4 previous errors
3447

tests/ui/double_ended_iterator_last_unfixable.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,3 @@ fn main() {
99
let _ = subindex.0.last();
1010
let _ = index.next();
1111
}
12-
13-
fn drop_order() {
14-
struct DropDeIterator(std::vec::IntoIter<S>);
15-
impl Iterator for DropDeIterator {
16-
type Item = S;
17-
fn next(&mut self) -> Option<Self::Item> {
18-
self.0.next()
19-
}
20-
}
21-
impl DoubleEndedIterator for DropDeIterator {
22-
fn next_back(&mut self) -> Option<Self::Item> {
23-
self.0.next_back()
24-
}
25-
}
26-
27-
struct S(&'static str);
28-
impl std::ops::Drop for S {
29-
fn drop(&mut self) {
30-
println!("Dropping {}", self.0);
31-
}
32-
}
33-
34-
let v = vec![S("one"), S("two"), S("three")];
35-
let v = (DropDeIterator(v.into_iter()), 42);
36-
println!("Last element is {}", v.0.last().unwrap().0);
37-
//~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`
38-
println!("Done");
39-
}

tests/ui/double_ended_iterator_last_unfixable.stderr

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)