Remove no-rustfix marker for tests with valid suggestions (#16609)

changelog: none
This commit is contained in:
Jason Newcomb
2026-02-23 00:55:42 +00:00
committed by GitHub
24 changed files with 825 additions and 56 deletions
+19
View File
@@ -0,0 +1,19 @@
// originally from glacier/fixed/77218.rs
// ice while adjusting...
#![expect(clippy::useless_vec)]
pub struct Cache {
data: Vec<i32>,
}
pub fn list_data(cache: &Cache, key: usize) {
for reference in vec![1, 2, 3] {
if
/* let */
let Some(reference) = cache.data.get(key) {
//~^ ERROR: mismatched types
//~| ERROR: mismatched types
unimplemented!()
}
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
// originally from glacier/fixed/77218.rs
// ice while adjusting...
//@no-rustfix
#![expect(clippy::useless_vec)]
pub struct Cache {
data: Vec<i32>,
}
+2 -2
View File
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> tests/ui/crashes/ice-6250.rs:12:14
--> tests/ui/crashes/ice-6250.rs:13:14
|
LL | for reference in vec![1, 2, 3] {
| --------- expected due to the type of this binding
@@ -8,7 +8,7 @@ LL | Some(reference) = cache.data.get(key) {
| ^^^^^^^^^ expected integer, found `&i32`
error[E0308]: mismatched types
--> tests/ui/crashes/ice-6250.rs:12:9
--> tests/ui/crashes/ice-6250.rs:13:9
|
LL | Some(reference) = cache.data.get(key) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+12
View File
@@ -0,0 +1,12 @@
#![warn(clippy::search_is_some)]
#![allow(clippy::needless_borrow)]
pub struct Thing;
pub fn has_thing(things: &[Thing]) -> bool {
let is_thing_ready = |_peer: &Thing| -> bool { todo!() };
things.iter().any(|p| is_thing_ready(&p))
//~^ search_is_some
}
fn main() {}
+3 -1
View File
@@ -1,6 +1,8 @@
#![warn(clippy::search_is_some)]
#![allow(clippy::needless_borrow)]
pub struct Thing;
//@no-rustfix
pub fn has_thing(things: &[Thing]) -> bool {
let is_thing_ready = |_peer: &Thing| -> bool { todo!() };
things.iter().find(|p| is_thing_ready(p)).is_some()
+1 -1
View File
@@ -1,5 +1,5 @@
error: called `is_some()` after searching an `Iterator` with `find`
--> tests/ui/crashes/ice-9041.rs:6:19
--> tests/ui/crashes/ice-9041.rs:8:19
|
LL | things.iter().find(|p| is_thing_ready(p)).is_some()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))`
@@ -0,0 +1,55 @@
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
#![allow(clippy::redundant_slicing, clippy::identity_op)]
pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
let mut count = 0;
dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);
let mut count = 0;
dst[..(src.len() - 3)].copy_from_slice(&src[3..]);
let mut count = 3;
dst[3..(src.len() + 3)].copy_from_slice(&src[..]);
let mut count = 3;
dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);
let mut count = 0;
dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);
let mut count = 3;
dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);
let mut count = 2;
dst.copy_from_slice(&src[2..(dst.len() + 2)]);
let mut count = 5;
dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);
let mut count = 3;
let mut count2 = 30;
dst[3..(src.len() + 3)].copy_from_slice(&src[..]);
dst2[30..(src.len() + 30)].copy_from_slice(&src[..]);
// make sure parentheses are added properly to bitwise operators, which have lower precedence than
// arithmetic ones
let mut count = 0 << 1;
dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);
// make sure incrementing expressions without semicolons at the end of loops are handled correctly.
let mut count = 0;
dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);
// make sure ones where the increment is not at the end of the loop.
// As a possible enhancement, one could adjust the offset in the suggestion according to
// the position. For example, if the increment is at the top of the loop;
// treating the loop counter as if it were initialized 1 greater than the original value.
let mut count = 0;
#[allow(clippy::needless_range_loop)]
for i in 0..src.len() {
count += 1;
dst[i] = src[count];
}
}
fn main() {}
+2 -1
View File
@@ -1,5 +1,6 @@
#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
//@no-rustfix
#![allow(clippy::redundant_slicing, clippy::identity_op)]
pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
let mut count = 0;
for i in 3..src.len() {
@@ -1,5 +1,5 @@
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:5:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:6:5
|
LL | / for i in 3..src.len() {
LL | |
@@ -13,7 +13,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:13:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:14:5
|
LL | / for i in 3..src.len() {
LL | |
@@ -24,7 +24,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].copy_from_slice(&src[3..]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:21:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:22:5
|
LL | / for i in 0..src.len() {
LL | |
@@ -35,7 +35,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].copy_from_slice(&src[..]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:29:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:30:5
|
LL | / for i in 0..src.len() {
LL | |
@@ -46,7 +46,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:37:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:38:5
|
LL | / for i in 3..(3 + src.len()) {
LL | |
@@ -57,7 +57,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:45:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:46:5
|
LL | / for i in 5..src.len() {
LL | |
@@ -68,7 +68,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:53:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:54:5
|
LL | / for i in 0..dst.len() {
LL | |
@@ -79,7 +79,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[2..(dst.len() + 2)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:61:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:62:5
|
LL | / for i in 3..10 {
LL | |
@@ -90,7 +90,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:70:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:71:5
|
LL | / for i in 0..src.len() {
LL | |
@@ -108,7 +108,7 @@ LL + dst2[30..(src.len() + 30)].copy_from_slice(&src[..]);
|
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:82:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:83:5
|
LL | / for i in 0..1 << 1 {
LL | |
@@ -119,7 +119,7 @@ LL | | }
| |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);`
error: it looks like you're manually copying between slices
--> tests/ui/manual_memcpy/with_loop_counters.rs:91:5
--> tests/ui/manual_memcpy/with_loop_counters.rs:92:5
|
LL | / for i in 3..src.len() {
LL | |
@@ -0,0 +1,175 @@
#![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() {}
@@ -3,10 +3,10 @@
clippy::assigning_clones,
clippy::useless_vec,
clippy::needless_range_loop,
clippy::manual_slice_fill
clippy::manual_slice_fill,
clippy::redundant_slicing
)]
//@no-rustfix
const LOOP_OFFSET: usize = 5000;
pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
+69
View File
@@ -0,0 +1,69 @@
#![warn(clippy::map_flatten)]
#![allow(clippy::unnecessary_filter_map)]
// issue #8506, multi-line
#[rustfmt::skip]
fn long_span() {
let _: Option<i32> = Some(1)
.and_then(|x| {
//~^ map_flatten
if x <= 5 {
Some(x)
} else {
None
}
});
let _: Result<i32, i32> = Ok(1)
.and_then(|x| {
//~^ map_flatten
if x == 1 {
Ok(x)
} else {
Err(0)
}
});
let result: Result<i32, i32> = Ok(2);
fn do_something() { }
let _: Result<i32, i32> = result
.and_then(|res| {
//~^ map_flatten
if res > 0 {
do_something();
Ok(res)
} else {
Err(0)
}
});
let _: Vec<_> = vec![5_i8; 6]
.into_iter()
.filter_map(|some_value| {
//~^ map_flatten
if some_value > 3 {
Some(some_value)
} else {
None
}
})
.collect();
}
#[allow(clippy::useless_vec)]
fn no_suggestion_if_comments_present() {
let vec = vec![vec![1, 2, 3]];
let _ = vec
.iter()
// a lovely comment explaining the code in very detail
.flat_map(|x| x.iter());
}
fn main() {
long_span();
}
+2 -2
View File
@@ -1,6 +1,6 @@
#![warn(clippy::map_flatten)]
#![allow(clippy::unnecessary_filter_map)]
//@no-rustfix
// issue #8506, multi-line
#[rustfmt::skip]
fn long_span() {
@@ -43,7 +43,7 @@ fn do_something() { }
}
})
.flatten();
let _: Vec<_> = vec![5_i8; 6]
.into_iter()
.map(|some_value| {
+344
View File
@@ -0,0 +1,344 @@
#![allow(
clippy::uninlined_format_args,
clippy::useless_vec,
clippy::needless_ifs,
clippy::iter_next_slice,
clippy::iter_count
)]
#![warn(clippy::needless_collect)]
use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
fn main() {
let sample = [1; 5];
//~^ needless_collect
sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
//~^ needless_collect
sample.iter().count();
//~^ needless_collect
sample.iter().next().is_none();
//~^ needless_collect
sample.iter().any(|x| x == &5);
let indirect_negative = sample.iter().collect::<Vec<_>>();
indirect_negative.len();
indirect_negative
.into_iter()
.map(|x| (*x, *x + 1))
.collect::<HashMap<_, _>>();
// #6202
let a = "a".to_string();
let sample = vec![a.clone(), "b".to_string(), "c".to_string()];
//~^ needless_collect
sample.into_iter().any(|x| x == a);
// Fix #5991
let vec_a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let vec_b = vec_a.iter().collect::<Vec<_>>();
if vec_b.len() > 3 {}
let other_vec = vec![1, 3, 12, 4, 16, 2];
let we_got_the_same_numbers = other_vec.iter().filter(|item| vec_b.contains(item)).collect::<Vec<_>>();
// Fix #6297
let sample = [1; 5];
let multiple_indirect = sample.iter().collect::<Vec<_>>();
let sample2 = vec![2, 3];
if multiple_indirect.is_empty() {
// do something
} else {
let found = sample2
.iter()
.filter(|i| multiple_indirect.iter().any(|s| **s % **i == 0))
.collect::<Vec<_>>();
}
}
mod issue7110 {
// #7110 - lint for type annotation cases
use super::*;
fn lint_vec(string: &str) -> usize {
//~^ needless_collect
string.split('/').count()
}
fn lint_vec_deque() -> usize {
let sample = [1; 5];
//~^ needless_collect
sample.iter().count()
}
fn lint_linked_list() -> usize {
let sample = [1; 5];
//~^ needless_collect
sample.iter().count()
}
fn lint_binary_heap() -> usize {
let sample = [1; 5];
//~^ needless_collect
sample.iter().count()
}
fn dont_lint(string: &str) -> usize {
let buffer: Vec<&str> = string.split('/').collect();
for buff in &buffer {
println!("{}", buff);
}
buffer.len()
}
}
mod issue7975 {
use super::*;
fn direct_mapping_with_used_mutable_reference() -> Vec<()> {
let test_vec: Vec<()> = vec![];
let mut vec_2: Vec<()> = vec![];
let mut_ref = &mut vec_2;
let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();
collected_vec.into_iter().map(|_| mut_ref.push(())).collect()
}
fn indirectly_mapping_with_used_mutable_reference() -> Vec<()> {
let test_vec: Vec<()> = vec![];
let mut vec_2: Vec<()> = vec![];
let mut_ref = &mut vec_2;
let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();
let iter = collected_vec.into_iter();
iter.map(|_| mut_ref.push(())).collect()
}
fn indirect_collect_after_indirect_mapping_with_used_mutable_reference() -> Vec<()> {
let test_vec: Vec<()> = vec![];
let mut vec_2: Vec<()> = vec![];
let mut_ref = &mut vec_2;
let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();
let iter = collected_vec.into_iter();
let mapped_iter = iter.map(|_| mut_ref.push(()));
mapped_iter.collect()
}
}
fn allow_test() {
#[allow(clippy::needless_collect)]
let v = [1].iter().collect::<Vec<_>>();
v.into_iter().collect::<HashSet<_>>();
}
mod issue_8553 {
fn test_for() {
let vec = vec![1, 2];
let w: Vec<usize> = vec.iter().map(|i| i * i).collect();
for i in 0..2 {
// Do not lint, because this method call is in the loop
w.contains(&i);
}
for i in 0..2 {
//~^ needless_collect
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
vec.iter().map(|k| k * k).any(|x| x == i);
for j in 0..2 {
// Do not lint, because this method call is in the loop
z.contains(&j);
}
}
// Do not lint, because this variable is used.
w.contains(&0);
}
fn test_while() {
let vec = vec![1, 2];
let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut n = 0;
while n > 1 {
// Do not lint, because this method call is in the loop
x.contains(&n);
n += 1;
}
while n > 2 {
//~^ needless_collect
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
vec.iter().map(|k| k * k).any(|x| x == n);
n += 1;
while n > 4 {
// Do not lint, because this method call is in the loop
z.contains(&n);
n += 1;
}
}
}
fn test_loop() {
let vec = vec![1, 2];
let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut n = 0;
loop {
if n < 1 {
// Do not lint, because this method call is in the loop
x.contains(&n);
n += 1;
} else {
break;
}
}
loop {
if n < 2 {
//~^ needless_collect
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
// Do lint
vec.iter().map(|k| k * k).any(|x| x == n);
n += 1;
loop {
if n < 4 {
// Do not lint, because this method call is in the loop
z.contains(&n);
n += 1;
} else {
break;
}
}
} else {
break;
}
}
}
fn test_while_let() {
let vec = vec![1, 2];
let x: Vec<usize> = vec.iter().map(|i| i * i).collect();
let optional = Some(0);
let mut n = 0;
while let Some(value) = optional {
if n < 1 {
// Do not lint, because this method call is in the loop
x.contains(&n);
n += 1;
} else {
break;
}
}
while let Some(value) = optional {
//~^ needless_collect
let z: Vec<usize> = vec.iter().map(|k| k * k).collect();
if n < 2 {
// Do lint
vec.iter().map(|k| k * k).any(|x| x == n);
n += 1;
} else {
break;
}
while let Some(value) = optional {
if n < 4 {
// Do not lint, because this method call is in the loop
z.contains(&n);
n += 1;
} else {
break;
}
}
}
}
fn test_if_cond() {
let vec = vec![1, 2];
let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
//~^ needless_collect
// Do lint
for _ in 0..v.iter().count() {
todo!();
}
}
fn test_if_cond_false_case() {
let vec = vec![1, 2];
let v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used.
for _ in 0..w.len() {
todo!();
}
w.len();
}
fn test_while_cond() {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
//~^ needless_collect
// Do lint
while 1 == v.iter().count() {
todo!();
}
}
fn test_while_cond_false_case() {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used.
while 1 == w.len() {
todo!();
}
w.len();
}
fn test_while_let_cond() {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
//~^ needless_collect
// Do lint
while let Some(i) = Some(v.iter().count()) {
todo!();
}
}
fn test_while_let_cond_false_case() {
let mut vec = vec![1, 2];
let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();
let mut w = v.iter().collect::<Vec<_>>();
// Do not lint, because w is used.
while let Some(i) = Some(w.len()) {
todo!();
}
w.len();
}
}
+8 -2
View File
@@ -1,6 +1,12 @@
#![allow(clippy::uninlined_format_args, clippy::useless_vec, clippy::needless_ifs)]
#![allow(
clippy::uninlined_format_args,
clippy::useless_vec,
clippy::needless_ifs,
clippy::iter_next_slice,
clippy::iter_count
)]
#![warn(clippy::needless_collect)]
//@no-rustfix
use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
fn main() {
+16 -16
View File
@@ -1,5 +1,5 @@
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:8:39
--> tests/ui/needless_collect_indirect.rs:14:39
|
LL | let indirect_iter = sample.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -18,7 +18,7 @@ LL ~ sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:12:38
--> tests/ui/needless_collect_indirect.rs:18:38
|
LL | let indirect_len = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -35,7 +35,7 @@ LL ~ sample.iter().count();
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:16:40
--> tests/ui/needless_collect_indirect.rs:22:40
|
LL | let indirect_empty = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -52,7 +52,7 @@ LL ~ sample.iter().next().is_none();
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:20:43
--> tests/ui/needless_collect_indirect.rs:26:43
|
LL | let indirect_contains = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -69,7 +69,7 @@ LL ~ sample.iter().any(|x| x == &5);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:34:48
--> tests/ui/needless_collect_indirect.rs:40:48
|
LL | let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -86,7 +86,7 @@ LL ~ sample.into_iter().any(|x| x == a);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:65:51
--> tests/ui/needless_collect_indirect.rs:71:51
|
LL | let buffer: Vec<&str> = string.split('/').collect();
| ^^^^^^^
@@ -103,7 +103,7 @@ LL ~ string.split('/').count()
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:72:55
--> tests/ui/needless_collect_indirect.rs:78:55
|
LL | let indirect_len: VecDeque<_> = sample.iter().collect();
| ^^^^^^^
@@ -120,7 +120,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:79:57
--> tests/ui/needless_collect_indirect.rs:85:57
|
LL | let indirect_len: LinkedList<_> = sample.iter().collect();
| ^^^^^^^
@@ -137,7 +137,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:86:57
--> tests/ui/needless_collect_indirect.rs:92:57
|
LL | let indirect_len: BinaryHeap<_> = sample.iter().collect();
| ^^^^^^^
@@ -154,7 +154,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:148:59
--> tests/ui/needless_collect_indirect.rs:154:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -172,7 +172,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == i);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:175:59
--> tests/ui/needless_collect_indirect.rs:181:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -190,7 +190,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:206:63
--> tests/ui/needless_collect_indirect.rs:212:63
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -208,7 +208,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:244:59
--> tests/ui/needless_collect_indirect.rs:250:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -226,7 +226,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:271:26
--> tests/ui/needless_collect_indirect.rs:277:26
|
LL | let w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -244,7 +244,7 @@ LL ~ for _ in 0..v.iter().count() {
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:295:30
--> tests/ui/needless_collect_indirect.rs:301:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -262,7 +262,7 @@ LL ~ while 1 == v.iter().count() {
|
error: avoid using `collect()` when not needed
--> tests/ui/needless_collect_indirect.rs:319:30
--> tests/ui/needless_collect_indirect.rs:325:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
+22
View File
@@ -0,0 +1,22 @@
//@compile-flags: -Z track-diagnostics
// Normalize the emitted location so this doesn't need
// updating everytime someone adds or removes a line.
//@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC"
//@normalize-stderr-test: "src/tools/clippy/" -> ""
#![warn(clippy::let_and_return, clippy::unnecessary_cast)]
fn main() {
// Check the provenance of a lint sent through `LintContext::span_lint()`
let a = 3u32;
let b = a;
//~^ unnecessary_cast
// Check the provenance of a lint sent through `TyCtxt::node_span_lint()`
let c = {
42
//~^ let_and_return
};
}
-1
View File
@@ -1,5 +1,4 @@
//@compile-flags: -Z track-diagnostics
//@no-rustfix
// Normalize the emitted location so this doesn't need
// updating everytime someone adds or removes a line.
+38
View File
@@ -0,0 +1,38 @@
#![deny(clippy::transmute_ptr_to_ptr)]
#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]
fn main() {
unsafe {
let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];
let bools: &[bool] = unsafe { &*(single_u64 as *const [u64] as *const [bool]) };
//~^ transmute_ptr_to_ptr
let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];
let b: &[u8] = unsafe { &*(a as *const [u32] as *const [u8]) };
//~^ transmute_ptr_to_ptr
let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { &*(bytes as *const [u8] as *const [u32]) };
//~^ transmute_ptr_to_ptr
}
}
fn issue16104(make_ptr: fn() -> *const u32) {
macro_rules! call {
($x:expr) => {
$x()
};
}
macro_rules! take_ref {
($x:expr) => {
&$x
};
}
unsafe {
let _: *const f32 = call!(make_ptr).cast::<f32>();
//~^ transmute_ptr_to_ptr
let _: &f32 = &*(take_ref!(1u32) as *const u32 as *const f32);
//~^ transmute_ptr_to_ptr
}
}
+1 -3
View File
@@ -1,7 +1,5 @@
//@no-rustfix
#![deny(clippy::transmute_ptr_to_ptr)]
#![allow(dead_code, clippy::missing_transmute_annotations)]
#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]
fn main() {
unsafe {
+6 -6
View File
@@ -1,29 +1,29 @@
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref.rs:9:39
--> tests/ui/transmute_ref_to_ref.rs:7:39
|
LL | let bools: &[bool] = unsafe { std::mem::transmute(single_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`
|
note: the lint level is defined here
--> tests/ui/transmute_ref_to_ref.rs:3:9
--> tests/ui/transmute_ref_to_ref.rs:1:9
|
LL | #![deny(clippy::transmute_ptr_to_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref.rs:13:33
--> tests/ui/transmute_ref_to_ref.rs:11:33
|
LL | let b: &[u8] = unsafe { std::mem::transmute(a) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref.rs:17:42
--> tests/ui/transmute_ref_to_ref.rs:15:42
|
LL | let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
error: transmute from a pointer to a pointer
--> tests/ui/transmute_ref_to_ref.rs:35:29
--> tests/ui/transmute_ref_to_ref.rs:33:29
|
LL | let _: *const f32 = std::mem::transmute(call!(make_ptr));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL + let _: *const f32 = call!(make_ptr).cast::<f32>();
|
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref.rs:37:23
--> tests/ui/transmute_ref_to_ref.rs:35:23
|
LL | let _: &f32 = std::mem::transmute(take_ref!(1u32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(take_ref!(1u32) as *const u32 as *const f32)`
@@ -0,0 +1,30 @@
#![deny(clippy::transmute_ptr_to_ptr)]
#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]
#![feature(lang_items)]
#![no_std]
use core::panic::PanicInfo;
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
loop {}
}
fn main() {
unsafe {
let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];
let bools: &[bool] = unsafe { &*(single_u64 as *const [u64] as *const [bool]) };
//~^ transmute_ptr_to_ptr
let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];
let b: &[u8] = unsafe { &*(a as *const [u32] as *const [u8]) };
//~^ transmute_ptr_to_ptr
let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
let alt_slice: &[u32] = unsafe { &*(bytes as *const [u8] as *const [u32]) };
//~^ transmute_ptr_to_ptr
}
}
+1 -3
View File
@@ -1,7 +1,5 @@
//@no-rustfix
#![deny(clippy::transmute_ptr_to_ptr)]
#![allow(dead_code, clippy::missing_transmute_annotations)]
#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]
#![feature(lang_items)]
#![no_std]
+4 -4
View File
@@ -1,23 +1,23 @@
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref_no_std.rs:21:39
--> tests/ui/transmute_ref_to_ref_no_std.rs:19:39
|
LL | let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`
|
note: the lint level is defined here
--> tests/ui/transmute_ref_to_ref_no_std.rs:3:9
--> tests/ui/transmute_ref_to_ref_no_std.rs:1:9
|
LL | #![deny(clippy::transmute_ptr_to_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref_no_std.rs:25:33
--> tests/ui/transmute_ref_to_ref_no_std.rs:23:33
|
LL | let b: &[u8] = unsafe { core::mem::transmute(a) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`
error: transmute from a reference to a reference
--> tests/ui/transmute_ref_to_ref_no_std.rs:29:42
--> tests/ui/transmute_ref_to_ref_no_std.rs:27:42
|
LL | let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`