Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auto-fix slow_vector_initialization in some cases #13947

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
};
Comment on lines +211 to +216
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the span to be linted contains comments, use Applicability::Unspecified, otherwise use 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
Loading