Skip to content

Commit bbfb9a4

Browse files
committed
for_loop: Split test into fixable/unfixable, make needless_range_loop use updated range syntax
1 parent 38a34b1 commit bbfb9a4

File tree

7 files changed

+379
-76
lines changed

7 files changed

+379
-76
lines changed

clippy_lints/src/loops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx
12721272
let start_snippet = snippet(cx, start.span, "_");
12731273
let end_snippet = snippet(cx, end.span, "_");
12741274
let dots = if limits == ast::RangeLimits::Closed {
1275-
"..."
1275+
"..="
12761276
} else {
12771277
".."
12781278
};

tests/ui/for_loop.stdout

Whitespace-only changes.

tests/ui/for_loop_fixable.fixed

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// run-rustfix
2+
3+
#![allow(dead_code, unused)]
4+
5+
use std::collections::*;
6+
7+
#[warn(clippy::all)]
8+
struct Unrelated(Vec<u8>);
9+
impl Unrelated {
10+
fn next(&self) -> std::slice::Iter<u8> {
11+
self.0.iter()
12+
}
13+
14+
fn iter(&self) -> std::slice::Iter<u8> {
15+
self.0.iter()
16+
}
17+
}
18+
19+
#[warn(
20+
clippy::needless_range_loop,
21+
clippy::explicit_iter_loop,
22+
clippy::explicit_into_iter_loop,
23+
clippy::iter_next_loop,
24+
clippy::reverse_range_loop,
25+
clippy::for_kv_map
26+
)]
27+
#[allow(
28+
clippy::linkedlist,
29+
clippy::shadow_unrelated,
30+
clippy::unnecessary_mut_passed,
31+
clippy::cognitive_complexity,
32+
clippy::similar_names
33+
)]
34+
#[allow(clippy::many_single_char_names, unused_variables, clippy::into_iter_on_array)]
35+
fn main() {
36+
const MAX_LEN: usize = 42;
37+
let mut vec = vec![1, 2, 3, 4];
38+
39+
for i in (0..10).rev() {
40+
println!("{}", i);
41+
}
42+
43+
for i in (0..=10).rev() {
44+
println!("{}", i);
45+
}
46+
47+
for i in (0..MAX_LEN).rev() {
48+
println!("{}", i);
49+
}
50+
51+
for i in 5..=5 {
52+
// not an error, this is the range with only one element “5”
53+
println!("{}", i);
54+
}
55+
56+
for i in 0..10 {
57+
// not an error, the start index is less than the end index
58+
println!("{}", i);
59+
}
60+
61+
for i in -10..0 {
62+
// not an error
63+
println!("{}", i);
64+
}
65+
66+
for i in (10..0).map(|x| x * 2) {
67+
// not an error, it can't be known what arbitrary methods do to a range
68+
println!("{}", i);
69+
}
70+
71+
// testing that the empty range lint folds constants
72+
for i in (5 + 4..10).rev() {
73+
println!("{}", i);
74+
}
75+
76+
for i in ((3 - 1)..(5 + 2)).rev() {
77+
println!("{}", i);
78+
}
79+
80+
for i in (2 * 2)..(2 * 3) {
81+
// no error, 4..6 is fine
82+
println!("{}", i);
83+
}
84+
85+
let x = 42;
86+
for i in x..10 {
87+
// no error, not constant-foldable
88+
println!("{}", i);
89+
}
90+
91+
// See #601
92+
for i in 0..10 {
93+
// no error, id_col does not exist outside the loop
94+
let mut id_col = vec![0f64; 10];
95+
id_col[i] = 1f64;
96+
}
97+
98+
for _v in &vec {}
99+
100+
for _v in &mut vec {}
101+
102+
let out_vec = vec![1, 2, 3];
103+
for _v in out_vec {}
104+
105+
let array = [1, 2, 3];
106+
for _v in &array {}
107+
108+
for _v in &vec {} // these are fine
109+
for _v in &mut vec {} // these are fine
110+
111+
for _v in &[1, 2, 3] {}
112+
113+
for _v in (&mut [1, 2, 3]).iter() {} // no error
114+
115+
for _v in &[0; 32] {}
116+
117+
for _v in [0; 33].iter() {} // no error
118+
119+
let ll: LinkedList<()> = LinkedList::new();
120+
for _v in &ll {}
121+
122+
let vd: VecDeque<()> = VecDeque::new();
123+
for _v in &vd {}
124+
125+
let bh: BinaryHeap<()> = BinaryHeap::new();
126+
for _v in &bh {}
127+
128+
let hm: HashMap<(), ()> = HashMap::new();
129+
for _v in &hm {}
130+
131+
let bt: BTreeMap<(), ()> = BTreeMap::new();
132+
for _v in &bt {}
133+
134+
let hs: HashSet<()> = HashSet::new();
135+
for _v in &hs {}
136+
137+
let bs: BTreeSet<()> = BTreeSet::new();
138+
for _v in &bs {}
139+
140+
let u = Unrelated(vec![]);
141+
for _v in u.next() {} // no error
142+
for _v in u.iter() {} // no error
143+
144+
let mut out = vec![];
145+
vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
146+
let _y = vec.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
147+
148+
// Loop with explicit counter variable
149+
150+
// Potential false positives
151+
let mut _index = 0;
152+
_index = 1;
153+
for _v in &vec {
154+
_index += 1
155+
}
156+
157+
let mut _index = 0;
158+
_index += 1;
159+
for _v in &vec {
160+
_index += 1
161+
}
162+
163+
let mut _index = 0;
164+
if true {
165+
_index = 1
166+
}
167+
for _v in &vec {
168+
_index += 1
169+
}
170+
171+
let mut _index = 0;
172+
let mut _index = 1;
173+
for _v in &vec {
174+
_index += 1
175+
}
176+
177+
let mut _index = 0;
178+
for _v in &vec {
179+
_index += 1;
180+
_index += 1
181+
}
182+
183+
let mut _index = 0;
184+
for _v in &vec {
185+
_index *= 2;
186+
_index += 1
187+
}
188+
189+
let mut _index = 0;
190+
for _v in &vec {
191+
_index = 1;
192+
_index += 1
193+
}
194+
195+
let mut _index = 0;
196+
197+
for _v in &vec {
198+
let mut _index = 0;
199+
_index += 1
200+
}
201+
202+
let mut _index = 0;
203+
for _v in &vec {
204+
_index += 1;
205+
_index = 0;
206+
}
207+
208+
let mut _index = 0;
209+
for _v in &vec {
210+
for _x in 0..1 {
211+
_index += 1;
212+
}
213+
_index += 1
214+
}
215+
216+
let mut _index = 0;
217+
for x in &vec {
218+
if *x == 1 {
219+
_index += 1
220+
}
221+
}
222+
223+
let mut _index = 0;
224+
if true {
225+
_index = 1
226+
};
227+
for _v in &vec {
228+
_index += 1
229+
}
230+
231+
let mut _index = 1;
232+
if false {
233+
_index = 0
234+
};
235+
for _v in &vec {
236+
_index += 1
237+
}
238+
239+
let mut index = 0;
240+
{
241+
let mut _x = &mut index;
242+
}
243+
for _v in &vec {
244+
_index += 1
245+
}
246+
247+
let mut index = 0;
248+
for _v in &vec {
249+
index += 1
250+
}
251+
println!("index: {}", index);
252+
253+
fn f<T>(_: &T, _: &T) -> bool {
254+
unimplemented!()
255+
}
256+
fn g<T>(_: &mut [T], _: usize, _: usize) {
257+
unimplemented!()
258+
}
259+
for i in 1..vec.len() {
260+
if f(&vec[i - 1], &vec[i]) {
261+
g(&mut vec, i - 1, i);
262+
}
263+
}
264+
265+
for mid in 1..vec.len() {
266+
let (_, _) = vec.split_at(mid);
267+
}
268+
}
269+
270+
fn partition<T: PartialOrd + Send>(v: &mut [T]) -> usize {
271+
let pivot = v.len() - 1;
272+
let mut i = 0;
273+
for j in 0..pivot {
274+
if v[j] <= v[pivot] {
275+
v.swap(i, j);
276+
i += 1;
277+
}
278+
}
279+
v.swap(i, pivot);
280+
i
281+
}
282+
283+
#[warn(clippy::needless_range_loop)]
284+
pub fn manual_copy_same_destination(dst: &mut [i32], d: usize, s: usize) {
285+
// Same source and destination - don't trigger lint
286+
for i in 0..dst.len() {
287+
dst[d + i] = dst[s + i];
288+
}
289+
}
290+
291+
mod issue_2496 {
292+
pub trait Handle {
293+
fn new_for_index(index: usize) -> Self;
294+
fn index(&self) -> usize;
295+
}
296+
297+
pub fn test<H: Handle>() -> H {
298+
for x in 0..5 {
299+
let next_handle = H::new_for_index(x);
300+
println!("{}", next_handle.index());
301+
}
302+
unimplemented!()
303+
}
304+
}

tests/ui/for_loop.rs renamed to tests/ui/for_loop_fixable.rs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use std::collections::*;
2-
use std::rc::Rc;
1+
// run-rustfix
2+
3+
#![allow(dead_code, unused)]
34

4-
static STATIC: [usize; 4] = [0, 1, 8, 16];
5-
const CONST: [usize; 4] = [0, 1, 8, 16];
5+
use std::collections::*;
66

77
#[warn(clippy::all)]
88
struct Unrelated(Vec<u8>);
@@ -48,10 +48,6 @@ fn main() {
4848
println!("{}", i);
4949
}
5050

51-
for i in 5..5 {
52-
println!("{}", i);
53-
}
54-
5551
for i in 5..=5 {
5652
// not an error, this is the range with only one element “5”
5753
println!("{}", i);
@@ -81,10 +77,6 @@ fn main() {
8177
println!("{}", i);
8278
}
8379

84-
for i in (5 + 2)..(8 - 1) {
85-
println!("{}", i);
86-
}
87-
8880
for i in (2 * 2)..(2 * 3) {
8981
// no error, 4..6 is fine
9082
println!("{}", i);
@@ -145,8 +137,6 @@ fn main() {
145137
let bs: BTreeSet<()> = BTreeSet::new();
146138
for _v in bs.iter() {}
147139

148-
for _v in vec.iter().next() {}
149-
150140
let u = Unrelated(vec![]);
151141
for _v in u.next() {} // no error
152142
for _v in u.iter() {} // no error
@@ -275,17 +265,8 @@ fn main() {
275265
for mid in 1..vec.len() {
276266
let (_, _) = vec.split_at(mid);
277267
}
278-
279-
const ZERO: usize = 0;
280-
281-
for i in ZERO..vec.len() {
282-
if f(&vec[i], &vec[i]) {
283-
panic!("at the disco");
284-
}
285-
}
286268
}
287269

288-
#[allow(dead_code)]
289270
fn partition<T: PartialOrd + Send>(v: &mut [T]) -> usize {
290271
let pivot = v.len() - 1;
291272
let mut i = 0;

0 commit comments

Comments
 (0)