Skip to content

Commit

Permalink
consider mutability on useless_vec suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
hmacias-avaya committed Apr 6, 2021
1 parent 86fb0e8 commit 8a50923
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 19 deletions.
54 changes: 42 additions & 12 deletions clippy_lints/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use clippy_utils::source::snippet_with_applicability;
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};
Expand Down Expand Up @@ -49,10 +49,10 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
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);
}
}

Expand All @@ -70,14 +70,20 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
.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) => {
Expand All @@ -87,11 +93,22 @@ impl UselessVec {
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;
}
Expand All @@ -104,9 +121,22 @@ impl UselessVec {
}
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(),
}
}
},
};
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/vec.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -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);
Expand All @@ -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] {
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -22,28 +27,38 @@ impl Line {
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);
Expand All @@ -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] {
Expand Down
44 changes: 37 additions & 7 deletions tests/ui/vec.stderr
Original file line number Diff line number Diff line change
@@ -1,40 +1,70 @@
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: `&[]`
|
= 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_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:29:14
--> $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:32:14
--> $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

0 comments on commit 8a50923

Please sign in to comment.