Skip to content

Commit

Permalink
auto-fix slow_vector_initialization in some cases (rust-lang#13947)
Browse files Browse the repository at this point in the history
changelog: [`slow_vector_initialization`]: auto-fix when appropriate

I made a change for `slow_vector_initialization` lint suggestion to use
`vec!` with size and remove the unneeded `resize` (or similar one) call
in rust-lang#13912, while only the former one was suggested in the previous
implementation. Now, I think this lint can be automatically fixed with
no unnecessary code in some cases. I wrote “in some cases” because if
there are comments between vector declaration and `resize`, Clippy
shouldn't apply auto-fix because the comment may informational.
  • Loading branch information
blyxyas authored Jan 13, 2025
2 parents 0db6411 + 39269aa commit dcbe3ad
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
11 changes: 10 additions & 1 deletion clippy_lints/src/slow_vector_initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clippy_utils::macros::matching_root_macro_call;
use clippy_utils::sugg::Sugg;
use clippy_utils::{
SpanlessEq, get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id,
span_contains_comment,
};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
Expand Down Expand Up @@ -206,14 +207,22 @@ impl SlowVectorInit {
let span_to_replace = slow_fill
.span
.with_lo(vec_alloc.allocation_expr.span.source_callsite().lo());

// If there is no comment in `span_to_replace`, Clippy can automatically fix the code.
let app = if span_contains_comment(cx.tcx.sess.source_map(), span_to_replace) {
Applicability::Unspecified
} else {
Applicability::MachineApplicable
};

span_lint_and_sugg(
cx,
SLOW_VECTOR_INITIALIZATION,
span_to_replace,
msg,
"consider replacing this with",
format!("vec![0; {len_expr}]"),
Applicability::Unspecified,
app,
);
}
}
Expand Down
85 changes: 85 additions & 0 deletions tests/ui/slow_vector_initialization.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#![allow(clippy::useless_vec)]
use std::iter::repeat;
fn main() {
resize_vector();
extend_vector();
mixed_extend_resize_vector();
from_empty_vec();
}

fn extend_vector() {
// Extend with constant expression
let len = 300;
let mut vec1 = vec![0; len];

// Extend with len expression
let mut vec2 = vec![0; len - 10];

// Extend with mismatching expression should not be warned
let mut vec3 = Vec::with_capacity(24322);
vec3.extend(repeat(0).take(2));

let mut vec4 = vec![0; len];
}

fn mixed_extend_resize_vector() {
// Mismatching len
let mut mismatching_len = Vec::with_capacity(30);
mismatching_len.extend(repeat(0).take(40));

// Slow initialization
let mut resized_vec = vec![0; 30];

let mut extend_vec = vec![0; 30];
}

fn resize_vector() {
// Resize with constant expression
let len = 300;
let mut vec1 = vec![0; len];

// Resize mismatch len
let mut vec2 = Vec::with_capacity(200);
vec2.resize(10, 0);

// Resize with len expression
let mut vec3 = vec![0; len - 10];

let mut vec4 = vec![0; len];

// Reinitialization should be warned
vec1 = vec![0; 10];
}

fn from_empty_vec() {
// Resize with constant expression
let len = 300;
let mut vec1 = vec![0; len];

// Resize with len expression
let mut vec3 = vec![0; len - 10];

// Reinitialization should be warned
vec1 = vec![0; 10];

vec1 = vec![0; 10];

macro_rules! x {
() => {
vec![]
};
}

// `vec![]` comes from another macro, don't warn
vec1 = x!();
vec1.resize(10, 0);
}

fn do_stuff(vec: &mut [u8]) {}

fn extend_vector_with_manipulations_between() {
let len = 300;
let mut vec1: Vec<u8> = Vec::with_capacity(len);
do_stuff(&mut vec1);
vec1.extend(repeat(0).take(len));
}
2 changes: 1 addition & 1 deletion tests/ui/slow_vector_initialization.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@no-rustfix
#![allow(clippy::useless_vec)]
use std::iter::repeat;
fn main() {
resize_vector();
Expand Down

0 comments on commit dcbe3ad

Please sign in to comment.