consider mutability on useless_vec suggestions

https://github.com/rust-lang/rust-clippy/issues/7035
This commit is contained in:
Horaci Macias 2021-04-05 13:27:39 +02:00
parent 86fb0e8266
commit 8a50923da4
4 changed files with 117 additions and 25 deletions

View File

@ -6,7 +6,7 @@ use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_copy; use clippy_utils::ty::is_copy;
use if_chain::if_chain; use if_chain::if_chain;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind}; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
@ -49,10 +49,10 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
if_chain! { if_chain! {
if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(expr).kind(); if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(expr).kind();
if let ty::Slice(..) = ty.kind(); if let ty::Slice(..) = ty.kind();
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref addressee) = expr.kind; if let ExprKind::AddrOf(BorrowKind::Ref, mutability, ref addressee) = expr.kind;
if let Some(vec_args) = higher::vec_macro(cx, addressee); if let Some(vec_args) = higher::vec_macro(cx, addressee);
then { then {
self.check_vec_macro(cx, &vec_args, expr.span); self.check_vec_macro(cx, &vec_args, mutability, expr.span);
} }
} }
@ -70,14 +70,20 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
.ctxt() .ctxt()
.outer_expn_data() .outer_expn_data()
.call_site; .call_site;
self.check_vec_macro(cx, &vec_args, span); self.check_vec_macro(cx, &vec_args, Mutability::Not, span);
} }
} }
} }
} }
impl UselessVec { impl UselessVec {
fn check_vec_macro<'tcx>(self, cx: &LateContext<'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) { fn check_vec_macro<'tcx>(
self,
cx: &LateContext<'tcx>,
vec_args: &higher::VecArgs<'tcx>,
mutability: Mutability,
span: Span,
) {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
let snippet = match *vec_args { let snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => { higher::VecArgs::Repeat(elem, len) => {
@ -87,11 +93,22 @@ impl UselessVec {
return; return;
} }
format!( match mutability {
"&[{}; {}]", Mutability::Mut => {
snippet_with_applicability(cx, elem.span, "elem", &mut applicability), format!(
snippet_with_applicability(cx, len.span, "len", &mut applicability) "&mut [{}; {}]",
) snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
snippet_with_applicability(cx, len.span, "len", &mut applicability)
)
},
Mutability::Not => {
format!(
"&[{}; {}]",
snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
snippet_with_applicability(cx, len.span, "len", &mut applicability)
)
},
}
} else { } else {
return; return;
} }
@ -104,9 +121,22 @@ impl UselessVec {
} }
let span = args[0].span.to(last.span); let span = args[0].span.to(last.span);
format!("&[{}]", snippet_with_applicability(cx, span, "..", &mut applicability)) match mutability {
Mutability::Mut => {
format!(
"&mut [{}]",
snippet_with_applicability(cx, span, "..", &mut applicability)
)
},
Mutability::Not => {
format!("&[{}]", snippet_with_applicability(cx, span, "..", &mut applicability))
},
}
} else { } else {
"&[]".into() match mutability {
Mutability::Mut => "&mut []".into(),
Mutability::Not => "&[]".into(),
}
} }
}, },
}; };

View File

@ -6,9 +6,14 @@
struct NonCopy; struct NonCopy;
fn on_slice(_: &[u8]) {} fn on_slice(_: &[u8]) {}
fn on_mut_slice(_: &mut [u8]) {}
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
fn on_vec(_: &Vec<u8>) {} fn on_vec(_: &Vec<u8>) {}
fn on_mut_vec(_: &mut Vec<u8>) {}
struct Line { struct Line {
length: usize, length: usize,
} }
@ -22,28 +27,38 @@ impl Line {
fn main() { fn main() {
on_slice(&[]); on_slice(&[]);
on_slice(&[]); on_slice(&[]);
on_mut_slice(&mut []);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut [1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut [1, 2]);
#[rustfmt::skip] #[rustfmt::skip]
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut [1, 2]);
on_slice(&[1; 2]); on_slice(&[1; 2]);
on_slice(&[1; 2]); on_slice(&[1; 2]);
on_mut_slice(&mut [1; 2]);
on_vec(&vec![]); on_vec(&vec![]);
on_vec(&vec![1, 2]); on_vec(&vec![1, 2]);
on_vec(&vec![1; 2]); on_vec(&vec![1; 2]);
on_mut_vec(&mut vec![]);
on_mut_vec(&mut vec![1, 2]);
on_mut_vec(&mut vec![1; 2]);
// Now with non-constant expressions // Now with non-constant expressions
let line = Line { length: 2 }; let line = Line { length: 2 };
on_slice(&vec![2; line.length]); on_slice(&vec![2; line.length]);
on_slice(&vec![2; line.length()]); on_slice(&vec![2; line.length()]);
on_mut_slice(&mut vec![2; line.length]);
on_mut_slice(&mut vec![2; line.length()]);
for a in &[1, 2, 3] { for a in &[1, 2, 3] {
println!("{:?}", a); println!("{:?}", a);
@ -54,6 +69,7 @@ fn main() {
} }
on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` 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`
// Ok // Ok
for a in vec![1; 201] { for a in vec![1; 201] {

View File

@ -6,9 +6,14 @@
struct NonCopy; struct NonCopy;
fn on_slice(_: &[u8]) {} fn on_slice(_: &[u8]) {}
fn on_mut_slice(_: &mut [u8]) {}
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
fn on_vec(_: &Vec<u8>) {} fn on_vec(_: &Vec<u8>) {}
fn on_mut_vec(_: &mut Vec<u8>) {}
struct Line { struct Line {
length: usize, length: usize,
} }
@ -22,28 +27,38 @@ impl Line {
fn main() { fn main() {
on_slice(&vec![]); on_slice(&vec![]);
on_slice(&[]); on_slice(&[]);
on_mut_slice(&mut vec![]);
on_slice(&vec![1, 2]); on_slice(&vec![1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
on_slice(&vec![1, 2]); on_slice(&vec![1, 2]);
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
#[rustfmt::skip] #[rustfmt::skip]
on_slice(&vec!(1, 2)); on_slice(&vec!(1, 2));
on_slice(&[1, 2]); on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
on_slice(&vec![1; 2]); on_slice(&vec![1; 2]);
on_slice(&[1; 2]); on_slice(&[1; 2]);
on_mut_slice(&mut vec![1; 2]);
on_vec(&vec![]); on_vec(&vec![]);
on_vec(&vec![1, 2]); on_vec(&vec![1, 2]);
on_vec(&vec![1; 2]); on_vec(&vec![1; 2]);
on_mut_vec(&mut vec![]);
on_mut_vec(&mut vec![1, 2]);
on_mut_vec(&mut vec![1; 2]);
// Now with non-constant expressions // Now with non-constant expressions
let line = Line { length: 2 }; let line = Line { length: 2 };
on_slice(&vec![2; line.length]); on_slice(&vec![2; line.length]);
on_slice(&vec![2; line.length()]); on_slice(&vec![2; line.length()]);
on_mut_slice(&mut vec![2; line.length]);
on_mut_slice(&mut vec![2; line.length()]);
for a in vec![1, 2, 3] { for a in vec![1, 2, 3] {
println!("{:?}", a); println!("{:?}", a);
@ -54,6 +69,7 @@ fn main() {
} }
on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` 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`
// Ok // Ok
for a in vec![1; 201] { for a in vec![1; 201] {

View File

@ -1,5 +1,5 @@
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:23:14 --> $DIR/vec.rs:28:14
| |
LL | on_slice(&vec![]); LL | on_slice(&vec![]);
| ^^^^^^^ help: you can use a slice directly: `&[]` | ^^^^^^^ help: you can use a slice directly: `&[]`
@ -7,34 +7,64 @@ LL | on_slice(&vec![]);
= note: `-D clippy::useless-vec` implied by `-D warnings` = note: `-D clippy::useless-vec` implied by `-D warnings`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:26:14 --> $DIR/vec.rs:30:18
| |
LL | on_slice(&vec![1, 2]); LL | on_mut_slice(&mut vec![]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`
error: useless use of `vec!`
--> $DIR/vec.rs:29:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:32:14 --> $DIR/vec.rs:32:14
| |
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:34: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:36:14
|
LL | on_slice(&vec![1, 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!`
--> $DIR/vec.rs:38: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:40:14
|
LL | on_slice(&vec!(1, 2)); LL | on_slice(&vec!(1, 2));
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:35:14 --> $DIR/vec.rs:42: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:44:14
| |
LL | on_slice(&vec![1; 2]); LL | on_slice(&vec![1; 2]);
| ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`
error: useless use of `vec!` error: useless use of `vec!`
--> $DIR/vec.rs:48:14 --> $DIR/vec.rs:46: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:63:14
| |
LL | for a in vec![1, 2, 3] { LL | for a in vec![1, 2, 3] {
| ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`
error: aborting due to 6 previous errors error: aborting due to 11 previous errors