Fix `useless_vec` suggestion in `for _ in vec![..]`

This commit is contained in:
Alex Macleod 2023-06-08 17:05:08 +00:00
parent b7c330fc78
commit 96697d2ee7
5 changed files with 88 additions and 51 deletions

View File

@ -699,7 +699,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
});
let too_large_for_stack = conf.too_large_for_stack;
store.register_late_pass(move |_| Box::new(escape::BoxedLocal { too_large_for_stack }));
store.register_late_pass(move |_| Box::new(vec::UselessVec { too_large_for_stack }));
store.register_late_pass(move |_| {
Box::new(vec::UselessVec {
too_large_for_stack,
msrv: msrv(),
})
});
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
store.register_late_pass(|_| Box::new(strings::StringLitAsBytes));
store.register_late_pass(|_| Box::new(derive::Derive));

View File

@ -2,6 +2,7 @@ use std::ops::ControlFlow;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_copy;
use clippy_utils::visitors::for_each_local_use_after_expr;
@ -18,9 +19,10 @@ use rustc_span::source_map::Span;
use rustc_span::sym;
#[expect(clippy::module_name_repetitions)]
#[derive(Copy, Clone)]
#[derive(Clone)]
pub struct UselessVec {
pub too_large_for_stack: u64,
pub msrv: Msrv,
}
declare_clippy_lint! {
@ -122,14 +124,16 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
if_chain! {
if let Some(higher::ForLoop { arg, .. }) = higher::ForLoop::hir(expr);
if let Some(vec_args) = higher::VecArgs::hir(cx, arg);
if is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(arg)));
if self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR);
then {
// report the error around the `vec!` not inside `<std macros>:`
let span = arg.span.ctxt().outer_expn_data().call_site;
self.check_vec_macro(cx, &vec_args, Mutability::Not, span, SuggestSlice::Yes);
self.check_vec_macro(cx, &vec_args, Mutability::Not, span, SuggestSlice::No);
}
}
}
extract_msrv_attr!(LateContext);
}
#[derive(Copy, Clone)]
@ -142,7 +146,7 @@ enum SuggestSlice {
impl UselessVec {
fn check_vec_macro<'tcx>(
self,
&mut self,
cx: &LateContext<'tcx>,
vec_args: &higher::VecArgs<'tcx>,
mutability: Mutability,

View File

@ -1,6 +1,6 @@
//@run-rustfix
#![warn(clippy::useless_vec)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
use std::rc::Rc;
@ -8,9 +8,6 @@ struct StructWithVec {
_x: Vec<i32>,
}
#[derive(Debug)]
struct NonCopy;
fn on_slice(_: &[u8]) {}
fn on_mut_slice(_: &mut [u8]) {}
@ -66,14 +63,6 @@ fn main() {
on_mut_slice(&mut vec![2; line.length]);
on_mut_slice(&mut vec![2; line.length()]);
for a in &[1, 2, 3] {
println!("{:?}", a);
}
for a in vec![NonCopy, NonCopy] {
println!("{:?}", a);
}
on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`
on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`
@ -91,7 +80,7 @@ fn main() {
let _x: &[i32] = &[1, 2, 3];
for _ in &[1, 2, 3] {}
for _ in [1, 2, 3] {}
// Don't lint
let x = vec![1, 2, 3];
@ -122,3 +111,25 @@ fn main() {
// Too large
let _x = vec![1; 201];
}
#[clippy::msrv = "1.53"]
fn above() {
for a in [1, 2, 3] {
let _: usize = a;
}
for a in [String::new(), String::new()] {
let _: String = a;
}
}
#[clippy::msrv = "1.52"]
fn below() {
for a in vec![1, 2, 3] {
let _: usize = a;
}
for a in vec![String::new(), String::new()] {
let _: String = a;
}
}

View File

@ -1,6 +1,6 @@
//@run-rustfix
#![warn(clippy::useless_vec)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)]
#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)]
use std::rc::Rc;
@ -8,9 +8,6 @@ struct StructWithVec {
_x: Vec<i32>,
}
#[derive(Debug)]
struct NonCopy;
fn on_slice(_: &[u8]) {}
fn on_mut_slice(_: &mut [u8]) {}
@ -66,14 +63,6 @@ fn main() {
on_mut_slice(&mut vec![2; line.length]);
on_mut_slice(&mut vec![2; line.length()]);
for a in vec![1, 2, 3] {
println!("{:?}", a);
}
for a in vec![NonCopy, NonCopy] {
println!("{:?}", a);
}
on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`
on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`
@ -122,3 +111,25 @@ fn main() {
// Too large
let _x = vec![1; 201];
}
#[clippy::msrv = "1.53"]
fn above() {
for a in vec![1, 2, 3] {
let _: usize = a;
}
for a in vec![String::new(), String::new()] {
let _: String = a;
}
}
#[clippy::msrv = "1.52"]
fn below() {
for a in vec![1, 2, 3] {
let _: usize = a;
}
for a in vec![String::new(), String::new()] {
let _: String = a;
}
}

View File

@ -1,5 +1,5 @@
error: useless use of `vec!`
--> $DIR/vec.rs:34:14
--> $DIR/vec.rs:31:14
|
LL | on_slice(&vec![]);
| ^^^^^^^ help: you can use a slice directly: `&[]`
@ -7,82 +7,88 @@ LL | on_slice(&vec![]);
= note: `-D clippy::useless-vec` implied by `-D warnings`
error: useless use of `vec!`
--> $DIR/vec.rs:36:18
--> $DIR/vec.rs:33:18
|
LL | on_mut_slice(&mut vec![]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`
error: useless use of `vec!`
--> $DIR/vec.rs:38:14
--> $DIR/vec.rs:35:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:40:18
--> $DIR/vec.rs:37:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:42:14
--> $DIR/vec.rs:39:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:44:18
--> $DIR/vec.rs:41:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:46:14
--> $DIR/vec.rs:43:14
|
LL | on_slice(&vec!(1, 2));
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:48:18
--> $DIR/vec.rs:45:18
|
LL | on_mut_slice(&mut vec![1, 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:50:14
--> $DIR/vec.rs:47:14
|
LL | on_slice(&vec![1; 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:52:18
--> $DIR/vec.rs:49:18
|
LL | on_mut_slice(&mut vec![1; 2]);
| ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:69:14
|
LL | for a in vec![1, 2, 3] {
| ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
error: useless use of `vec!`
--> $DIR/vec.rs:86:17
--> $DIR/vec.rs:75:17
|
LL | let mut x = vec![1, 2, 3];
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!`
--> $DIR/vec.rs:92:22
--> $DIR/vec.rs:81:22
|
LL | let _x: &[i32] = &vec![1, 2, 3];
| ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
error: useless use of `vec!`
--> $DIR/vec.rs:94:14
--> $DIR/vec.rs:83:14
|
LL | for _ in vec![1, 2, 3] {}
| ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: aborting due to 14 previous errors
error: useless use of `vec!`
--> $DIR/vec.rs:117:14
|
LL | for a in vec![1, 2, 3] {
| ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`
error: useless use of `vec!`
--> $DIR/vec.rs:121:14
|
LL | for a in vec![String::new(), String::new()] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`
error: aborting due to 15 previous errors