summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
blob: a224001a3dfd68ebb766f7c7e78ff02590f94e06 (plain)
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() {}