blob: 8502c740b71266ff3dee11252ae6da4cf1a923b6 [file] [log] [blame]
#![warn(clippy::manual_memcpy)]
#![allow(
clippy::assigning_clones,
clippy::useless_vec,
clippy::needless_range_loop,
clippy::manual_slice_fill,
clippy::redundant_slicing
)]
const LOOP_OFFSET: usize = 5000;
pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
// plain manual memcpy
dst[..src.len()].copy_from_slice(&src[..]);
// dst offset memcpy
dst[10..(src.len() + 10)].copy_from_slice(&src[..]);
// src offset memcpy
dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);
// src offset memcpy
dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);
// overwrite entire dst
dst.copy_from_slice(&src[..dst.len()]);
// 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
dst[10..256].copy_from_slice(&src[(10 - 5)..(256 - 5)]);
dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);
// 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
dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - 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
dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);
// 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;
dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);
dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);
#[allow(clippy::identity_op)]
dst[..5].copy_from_slice(&src);
#[allow(clippy::reversed_empty_ranges)]
dst[..0].copy_from_slice(&src[..0]);
// `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];
}
// Range is equal to array length
let src = [0, 1, 2, 3, 4];
let mut dst = [0; 4];
dst.copy_from_slice(&src[..4]);
let mut dst = [0; 6];
dst[..5].copy_from_slice(&src);
let mut dst = [0; 5];
dst.copy_from_slice(&src);
// Don't trigger lint for following multi-dimensional arrays
let src = [[0; 5]; 5];
for i in 0..4 {
dst[i] = src[i + 1][i];
}
for i in 0..5 {
dst[i] = src[i][i];
}
for i in 0..5 {
dst[i] = src[i][3];
}
let src = [0; 5];
let mut dst = [[0; 5]; 5];
for i in 0..5 {
dst[i][i] = src[i];
}
let src = [[[0; 5]; 5]; 5];
let mut dst = [0; 5];
for i in 0..5 {
dst[i] = src[i][i][i];
}
for i in 0..5 {
dst[i] = src[i][i][0];
}
for i in 0..5 {
dst[i] = src[i][0][i];
}
for i in 0..5 {
dst[i] = src[0][i][i];
}
for i in 0..5 {
dst[i] = src[0][i][1];
}
for i in 0..5 {
dst[i] = src[i][0][1];
}
// Trigger lint
let src = [[0; 5]; 5];
let mut dst = [0; 5];
dst.copy_from_slice(&src[0]);
let src = [[[0; 5]; 5]; 5];
dst.copy_from_slice(&src[0][1]);
}
#[warn(clippy::needless_range_loop, clippy::manual_memcpy)]
pub fn manual_clone(src: &[String], dst: &mut [String]) {
dst[..src.len()].clone_from_slice(&src[..]);
}
fn main() {}