Skip to content

Commit dcbe3ad

Browse files
authored
auto-fix slow_vector_initialization in some cases (rust-lang#13947)
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.
2 parents 0db6411 + 39269aa commit dcbe3ad

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

Diff for: clippy_lints/src/slow_vector_initialization.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use clippy_utils::macros::matching_root_macro_call;
33
use clippy_utils::sugg::Sugg;
44
use clippy_utils::{
55
SpanlessEq, get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id,
6+
span_contains_comment,
67
};
78
use rustc_errors::Applicability;
89
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
@@ -206,14 +207,22 @@ impl SlowVectorInit {
206207
let span_to_replace = slow_fill
207208
.span
208209
.with_lo(vec_alloc.allocation_expr.span.source_callsite().lo());
210+
211+
// If there is no comment in `span_to_replace`, Clippy can automatically fix the code.
212+
let app = if span_contains_comment(cx.tcx.sess.source_map(), span_to_replace) {
213+
Applicability::Unspecified
214+
} else {
215+
Applicability::MachineApplicable
216+
};
217+
209218
span_lint_and_sugg(
210219
cx,
211220
SLOW_VECTOR_INITIALIZATION,
212221
span_to_replace,
213222
msg,
214223
"consider replacing this with",
215224
format!("vec![0; {len_expr}]"),
216-
Applicability::Unspecified,
225+
app,
217226
);
218227
}
219228
}

Diff for: tests/ui/slow_vector_initialization.fixed

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#![allow(clippy::useless_vec)]
2+
use std::iter::repeat;
3+
fn main() {
4+
resize_vector();
5+
extend_vector();
6+
mixed_extend_resize_vector();
7+
from_empty_vec();
8+
}
9+
10+
fn extend_vector() {
11+
// Extend with constant expression
12+
let len = 300;
13+
let mut vec1 = vec![0; len];
14+
15+
// Extend with len expression
16+
let mut vec2 = vec![0; len - 10];
17+
18+
// Extend with mismatching expression should not be warned
19+
let mut vec3 = Vec::with_capacity(24322);
20+
vec3.extend(repeat(0).take(2));
21+
22+
let mut vec4 = vec![0; len];
23+
}
24+
25+
fn mixed_extend_resize_vector() {
26+
// Mismatching len
27+
let mut mismatching_len = Vec::with_capacity(30);
28+
mismatching_len.extend(repeat(0).take(40));
29+
30+
// Slow initialization
31+
let mut resized_vec = vec![0; 30];
32+
33+
let mut extend_vec = vec![0; 30];
34+
}
35+
36+
fn resize_vector() {
37+
// Resize with constant expression
38+
let len = 300;
39+
let mut vec1 = vec![0; len];
40+
41+
// Resize mismatch len
42+
let mut vec2 = Vec::with_capacity(200);
43+
vec2.resize(10, 0);
44+
45+
// Resize with len expression
46+
let mut vec3 = vec![0; len - 10];
47+
48+
let mut vec4 = vec![0; len];
49+
50+
// Reinitialization should be warned
51+
vec1 = vec![0; 10];
52+
}
53+
54+
fn from_empty_vec() {
55+
// Resize with constant expression
56+
let len = 300;
57+
let mut vec1 = vec![0; len];
58+
59+
// Resize with len expression
60+
let mut vec3 = vec![0; len - 10];
61+
62+
// Reinitialization should be warned
63+
vec1 = vec![0; 10];
64+
65+
vec1 = vec![0; 10];
66+
67+
macro_rules! x {
68+
() => {
69+
vec![]
70+
};
71+
}
72+
73+
// `vec![]` comes from another macro, don't warn
74+
vec1 = x!();
75+
vec1.resize(10, 0);
76+
}
77+
78+
fn do_stuff(vec: &mut [u8]) {}
79+
80+
fn extend_vector_with_manipulations_between() {
81+
let len = 300;
82+
let mut vec1: Vec<u8> = Vec::with_capacity(len);
83+
do_stuff(&mut vec1);
84+
vec1.extend(repeat(0).take(len));
85+
}

Diff for: tests/ui/slow_vector_initialization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@no-rustfix
1+
#![allow(clippy::useless_vec)]
22
use std::iter::repeat;
33
fn main() {
44
resize_vector();

0 commit comments

Comments
 (0)