Skip to content

Commit

Permalink
Auto merge of #10909 - Alexendoo:useless-for-in-vec, r=llogiq
Browse files Browse the repository at this point in the history
Fix `useless_vec` suggestion in `for _ in vec![..]`

Fixes rust-lang/rust#111034
Fixes #2256

changelog: [`useless_vec`]: Fix suggestion in `for _ in vec![..]`
  • Loading branch information
bors committed Jun 8, 2023
2 parents b7c330f + 96697d2 commit e2c655b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 51 deletions.
7 changes: 6 additions & 1 deletion clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
12 changes: 8 additions & 4 deletions clippy_lints/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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! {
Expand Down Expand Up @@ -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)]
Expand All @@ -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,
Expand Down
37 changes: 24 additions & 13 deletions tests/ui/vec.fixed
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
//@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;

struct StructWithVec {
_x: Vec<i32>,
}

#[derive(Debug)]
struct NonCopy;

fn on_slice(_: &[u8]) {}

fn on_mut_slice(_: &mut [u8]) {}
Expand Down Expand Up @@ -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`

Expand All @@ -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];
Expand Down Expand Up @@ -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;
}
}
35 changes: 23 additions & 12 deletions tests/ui/vec.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
//@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;

struct StructWithVec {
_x: Vec<i32>,
}

#[derive(Debug)]
struct NonCopy;

fn on_slice(_: &[u8]) {}

fn on_mut_slice(_: &mut [u8]) {}
Expand Down Expand Up @@ -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`

Expand Down Expand Up @@ -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;
}
}
48 changes: 27 additions & 21 deletions tests/ui/vec.stderr
Original file line number Diff line number Diff line change
@@ -1,88 +1,94 @@
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: `&[]`
|
= 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: 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 14 previous errors
error: aborting due to 15 previous errors

0 comments on commit e2c655b

Please sign in to comment.