summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
blob: ea0535d076b81911d99676b6d785afe22141544a (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
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]

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() {
        dst[i] = src[i];
    }

    // dst offset memcpy
    for i in 0..src.len() {
        dst[i + 10] = src[i];
    }

    // src offset memcpy
    for i in 0..src.len() {
        dst[i] = src[i + 10];
    }

    // src offset memcpy
    for i in 11..src.len() {
        dst[i] = src[i - 10];
    }

    // overwrite entire dst
    for i in 0..dst.len() {
        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 {
        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 {
        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() {
        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() {
        dst[i] = src[i - from];
    }

    for i in from..from + 3 {
        dst[i] = src[i - from];
    }

    #[allow(clippy::identity_op)]
    for i in 0..5 {
        dst[i - 0] = src[i];
    }

    #[allow(clippy::reversed_empty_ranges)]
    for i in 0..0 {
        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() {
        dst[i] = src[i].clone();
    }
}

fn main() {}