Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 5120632

Browse files
committed
[slow_vector_initialization]: only warn on vec![] expn
1 parent 78983d9 commit 5120632

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

clippy_lints/src/slow_vector_initialization.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2+
use clippy_utils::macros::root_macro_call;
23
use clippy_utils::sugg::Sugg;
34
use clippy_utils::{
45
get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
@@ -148,6 +149,15 @@ impl SlowVectorInit {
148149
/// - `Some(InitializedSize::Uninitialized)` for `Vec::new()`
149150
/// - `None` for other, unrelated kinds of expressions
150151
fn as_vec_initializer<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<InitializedSize<'tcx>> {
152+
// Generally don't warn if the vec initializer comes from an expansion, except for the vec! macro.
153+
// This lets us still warn on `vec![]`, while ignoring other kinds of macros that may output an
154+
// empty vec
155+
if expr.span.from_expansion()
156+
&& root_macro_call(expr.span).map(|m| m.def_id) != cx.tcx.get_diagnostic_item(sym::vec_macro)
157+
{
158+
return None;
159+
}
160+
151161
if let ExprKind::Call(func, [len_expr]) = expr.kind
152162
&& is_expr_path_def_path(cx, func, &paths::VEC_WITH_CAPACITY)
153163
{

tests/ui/slow_vector_initialization.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::iter::repeat;
21
//@no-rustfix
2+
use std::iter::repeat;
33
fn main() {
44
resize_vector();
55
extend_vector();
@@ -86,6 +86,20 @@ fn from_empty_vec() {
8686
vec1 = Vec::new();
8787
vec1.resize(10, 0);
8888
//~^ ERROR: slow zero-filling initialization
89+
90+
vec1 = vec![];
91+
vec1.resize(10, 0);
92+
//~^ ERROR: slow zero-filling initialization
93+
94+
macro_rules! x {
95+
() => {
96+
vec![]
97+
};
98+
}
99+
100+
// `vec![]` comes from another macro, don't warn
101+
vec1 = x!();
102+
vec1.resize(10, 0);
89103
}
90104

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

tests/ui/slow_vector_initialization.stderr

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,21 @@ LL | vec1 = Vec::new();
9696
LL | vec1.resize(10, 0);
9797
| ^^^^^^^^^^^^^^^^^^
9898

99+
error: slow zero-filling initialization
100+
--> $DIR/slow_vector_initialization.rs:91:5
101+
|
102+
LL | vec1 = vec![];
103+
| ------ help: consider replacing this with: `vec![0; 10]`
104+
LL | vec1.resize(10, 0);
105+
| ^^^^^^^^^^^^^^^^^^
106+
99107
error: this argument is a mutable reference, but not used mutably
100-
--> $DIR/slow_vector_initialization.rs:91:18
108+
--> $DIR/slow_vector_initialization.rs:105:18
101109
|
102110
LL | fn do_stuff(vec: &mut [u8]) {}
103111
| ^^^^^^^^^ help: consider changing to: `&[u8]`
104112
|
105113
= note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
106114

107-
error: aborting due to 13 previous errors
115+
error: aborting due to 14 previous errors
108116

0 commit comments

Comments
 (0)