1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
#![allow(clippy::useless_vec)]
//@no-rustfix
const LOOP_OFFSET: usize = 5000;
pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
// plain manual memcpy
for i in 0..src.len() {
//~^ ERROR: it looks like you're manually copying between slices
//~| NOTE: `-D clippy::manual-memcpy` implied by `-D warnings`
dst[i] = src[i];
}
// dst offset memcpy
for i in 0..src.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i + 10] = src[i];
}
// src offset memcpy
for i in 0..src.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i + 10];
}
// src offset memcpy
for i in 11..src.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - 10];
}
// overwrite entire dst
for i in 0..dst.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i];
}
// manual copy with branch - can't easily convert to memcpy!
for i in 0..src.len() {
dst[i] = src[i];
if dst[i] > 5 {
break;
}
}
// multiple copies - suggest two memcpy statements
for i in 10..256 {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - 5];
dst2[i + 500] = src[i]
}
// this is a reversal - the copy lint shouldn't be triggered
for i in 10..LOOP_OFFSET {
dst[i + LOOP_OFFSET] = src[LOOP_OFFSET - i];
}
let some_var = 5;
// Offset in variable
for i in 10..LOOP_OFFSET {
//~^ ERROR: it looks like you're manually copying between slices
dst[i + LOOP_OFFSET] = src[i - some_var];
}
// Non continuous copy - don't trigger lint
for i in 0..10 {
dst[i + i] = src[i];
}
let src_vec = vec![1, 2, 3, 4, 5];
let mut dst_vec = vec![0, 0, 0, 0, 0];
// make sure vectors are supported
for i in 0..src_vec.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst_vec[i] = src_vec[i];
}
// lint should not trigger when either
// source or destination type is not
// slice-like, like DummyStruct
struct DummyStruct(i32);
impl ::std::ops::Index<usize> for DummyStruct {
type Output = i32;
fn index(&self, _: usize) -> &i32 {
&self.0
}
}
let src = DummyStruct(5);
let mut dst_vec = vec![0; 10];
for i in 0..10 {
dst_vec[i] = src[i];
}
// Simplify suggestion (issue #3004)
let src = [0, 1, 2, 3, 4];
let mut dst = [0, 0, 0, 0, 0, 0];
let from = 1;
for i in from..from + src.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - from];
}
for i in from..from + 3 {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i - from];
}
#[allow(clippy::identity_op)]
for i in 0..5 {
//~^ ERROR: it looks like you're manually copying between slices
dst[i - 0] = src[i];
}
#[allow(clippy::reversed_empty_ranges)]
for i in 0..0 {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i];
}
// `RangeTo` `for` loop - don't trigger lint
for i in 0.. {
dst[i] = src[i];
}
// VecDeque - ideally this would work, but would require something like `range_as_slices`
let mut dst = std::collections::VecDeque::from_iter([0; 5]);
let src = std::collections::VecDeque::from_iter([0, 1, 2, 3, 4]);
for i in 0..dst.len() {
dst[i] = src[i];
}
let src = vec![0, 1, 2, 3, 4];
for i in 0..dst.len() {
dst[i] = src[i];
}
}
#[warn(clippy::needless_range_loop, clippy::manual_memcpy)]
pub fn manual_clone(src: &[String], dst: &mut [String]) {
for i in 0..src.len() {
//~^ ERROR: it looks like you're manually copying between slices
dst[i] = src[i].clone();
}
}
fn main() {}
|