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::ty::is_copy;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind};
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
@ -49,10 +49,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if_chain! {
if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(expr).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);
then {
self.check_vec_macro(cx, &vec_args, expr.span);
self.check_vec_macro(cx, &vec_args, mutability, expr.span);
}
}
@ -70,14 +70,20 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
.ctxt()
.outer_expn_data()
.call_site;
self.check_vec_macro(cx, &vec_args, span);
self.check_vec_macro(cx, &vec_args, Mutability::Not, span);
}
}
}
}
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 snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => {
@ -87,11 +93,22 @@ fn check_vec_macro<'tcx>(self, cx: &LateContext<'tcx>, vec_args: &higher::VecArg
return;
}
format!(
"&[{}; {}]",
snippet_with_applicability(cx, elem.span, "elem", &mut applicability),
snippet_with_applicability(cx, len.span, "len", &mut applicability)
)
match mutability {
Mutability::Mut => {
format!(
"&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 {
return;
}
@ -104,9 +121,22 @@ fn check_vec_macro<'tcx>(self, cx: &LateContext<'tcx>, vec_args: &higher::VecArg
}
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 {
"&[]".into()
match mutability {
Mutability::Mut => "&mut []".into(),
Mutability::Not => "&[]".into(),
}
}
},
};

View File

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

View File

@ -6,9 +6,14 @@
struct NonCopy;
fn on_slice(_: &[u8]) {}
fn on_mut_slice(_: &mut [u8]) {}
#[allow(clippy::ptr_arg)]
fn on_vec(_: &Vec<u8>) {}
fn on_mut_vec(_: &mut Vec<u8>) {}
struct Line {
length: usize,
}
@ -22,28 +27,38 @@ fn length(&self) -> usize {
fn main() {
on_slice(&vec![]);
on_slice(&[]);
on_mut_slice(&mut vec![]);
on_slice(&vec![1, 2]);
on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
on_slice(&vec![1, 2]);
on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
#[rustfmt::skip]
on_slice(&vec!(1, 2));
on_slice(&[1, 2]);
on_mut_slice(&mut vec![1, 2]);
on_slice(&vec![1; 2]);
on_slice(&[1; 2]);
on_mut_slice(&mut vec![1; 2]);
on_vec(&vec![]);
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
let line = Line { length: 2 };
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] {
println!("{:?}", a);
@ -54,6 +69,7 @@ fn main() {
}
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
for a in vec![1; 201] {

View File

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