Skip to content

Commit 415ba21

Browse files
committed
Auto merge of #11451 - y21:issue11408, r=xFrednet
[`slow_vector_initialization`]: use the source span of vec![] macro and fix another FP Fixes #11408 <details> <summary>Also fixes a FP when the vec initializer comes from a macro other than `vec![]`</summary> ```rs macro_rules! x { () => { vec![] } } fn f() { let mut v = x!(); v.resize(10, 0); } ``` This shouldn't warn. The `x!` macro might be doing other things, so just replacing `x!()` with `vec![0; 10]` is not always an option. </details> I added some test cases for macro expansions, however I don't think there's a way to write a test for that specific warning that appeared in the linked issue. As far as I understand, that happens when the rust-src rustup component isn't installed (so the stdlib source is unavailable) and the span points to the `vec![]` *expansion*, instead of the `vec![]` that the user wrote. changelog: [`slow_vector_initialization`]: use the source span of `vec![]` macro changelog: [`slow_vector_initialization`]: only warn on `vec![]` expansions and allow other macros
2 parents 69fcbfd + 5120632 commit 415ba21

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

clippy_lints/src/slow_vector_initialization.rs

Lines changed: 11 additions & 1 deletion
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
{
@@ -205,7 +215,7 @@ impl SlowVectorInit {
205215

206216
span_lint_and_then(cx, SLOW_VECTOR_INITIALIZATION, slow_fill.span, msg, |diag| {
207217
diag.span_suggestion(
208-
vec_alloc.allocation_expr.span,
218+
vec_alloc.allocation_expr.span.source_callsite(),
209219
"consider replacing this with",
210220
format!("vec![0; {len_expr}]"),
211221
Applicability::Unspecified,

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)