mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-15 20:45:45 +03:00
auto-fix slow_vector_initialization in some cases (#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 #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.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
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};
|
||||
@@ -206,6 +207,14 @@ fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocati
|
||||
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,
|
||||
@@ -213,7 +222,7 @@ fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocati
|
||||
msg,
|
||||
"consider replacing this with",
|
||||
format!("vec![0; {len_expr}]"),
|
||||
Applicability::Unspecified,
|
||||
app,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
//@no-rustfix
|
||||
#![allow(clippy::useless_vec)]
|
||||
use std::iter::repeat;
|
||||
fn main() {
|
||||
resize_vector();
|
||||
|
||||
Reference in New Issue
Block a user