Skip to content

Commit 929f746

Browse files
committed
fix the actual bug
1 parent 0d83a3a commit 929f746

File tree

4 files changed

+50
-41
lines changed

4 files changed

+50
-41
lines changed

clippy_lints/src/vec.rs

+35-40
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ops::ControlFlow;
44
use clippy_config::msrvs::{self, Msrv};
55
use clippy_utils::consts::{constant, Constant};
66
use clippy_utils::diagnostics::span_lint_hir_and_then;
7-
use clippy_utils::source::snippet_with_applicability;
7+
use clippy_utils::source::snippet_opt;
88
use clippy_utils::ty::is_copy;
99
use clippy_utils::visitors::for_each_local_use_after_expr;
1010
use clippy_utils::{get_parent_expr, higher, is_trait_method};
@@ -57,6 +57,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
5757
let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
5858
return;
5959
};
60+
// the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
61+
let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
6062

6163
match cx.tcx.parent_hir_node(expr.hir_id) {
6264
// search for `let foo = vec![_]` expressions where all uses of `foo`
@@ -84,41 +86,31 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
8486
})
8587
.is_continue();
8688

87-
let span = expr.span.ctxt().outer_expn_data().call_site;
8889
if only_slice_uses {
89-
self.check_vec_macro(cx, &vec_args, span, expr.hir_id, SuggestedType::Array);
90+
self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, SuggestedType::Array);
9091
} else {
91-
self.span_to_lint_map.insert(span, None);
92+
self.span_to_lint_map.insert(callsite, None);
9293
}
9394
},
9495
// if the local pattern has a specified type, do not lint.
9596
Node::Local(Local { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {
96-
let span = expr.span.ctxt().outer_expn_data().call_site;
97-
self.span_to_lint_map.insert(span, None);
97+
self.span_to_lint_map.insert(callsite, None);
9898
},
9999
// search for `for _ in vec![...]`
100100
Node::Expr(Expr { span, .. })
101101
if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR) =>
102102
{
103-
// report the error around the `vec!` not inside `<std macros>:`
104-
let span = expr.span.ctxt().outer_expn_data().call_site;
105-
self.check_vec_macro(cx, &vec_args, span, expr.hir_id, SuggestedType::Array);
103+
let suggest_slice = suggest_type(expr);
104+
self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, suggest_slice);
106105
},
107106
// search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
108107
_ => {
109-
let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
110-
// `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
111-
(SuggestedType::SliceRef(mutability), expr.span)
112-
} else {
113-
// `expr` is the `vec![_]` expansion, so suggest `[_]`
114-
// and also use the span of the actual `vec![_]` expression
115-
(SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site)
116-
};
108+
let suggest_slice = suggest_type(expr);
117109

118110
if adjusts_to_slice(cx, expr) {
119-
self.check_vec_macro(cx, &vec_args, span, expr.hir_id, suggest_slice);
111+
self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, suggest_slice);
120112
} else {
121-
self.span_to_lint_map.insert(span, None);
113+
self.span_to_lint_map.insert(callsite, None);
122114
}
123115
},
124116
}
@@ -151,8 +143,6 @@ impl UselessVec {
151143
return;
152144
}
153145

154-
let mut applicability = Applicability::MachineApplicable;
155-
156146
let snippet = match *vec_args {
157147
higher::VecArgs::Repeat(elem, len) => {
158148
if let Some(Constant::Int(len_constant)) = constant(cx, cx.typeck_results(), len) {
@@ -166,7 +156,7 @@ impl UselessVec {
166156
return;
167157
}
168158

169-
suggest_slice.snippet(cx, Some(elem.span), Some(len.span), &mut applicability)
159+
suggest_slice.snippet(cx, Some(elem.span), Some(len.span))
170160
} else {
171161
return;
172162
}
@@ -180,13 +170,16 @@ impl UselessVec {
180170
} else {
181171
None
182172
};
183-
suggest_slice.snippet(cx, args_span, None, &mut applicability)
173+
suggest_slice.snippet(cx, args_span, None)
184174
},
185175
};
186176

187-
self.span_to_lint_map
188-
.entry(span)
189-
.or_insert(Some((hir_id, suggest_slice, snippet, applicability)));
177+
self.span_to_lint_map.entry(span).or_insert(Some((
178+
hir_id,
179+
suggest_slice,
180+
snippet,
181+
Applicability::MachineApplicable,
182+
)));
190183
}
191184
}
192185

@@ -206,24 +199,16 @@ impl SuggestedType {
206199
}
207200
}
208201

209-
fn snippet(
210-
self,
211-
cx: &LateContext<'_>,
212-
args_span: Option<Span>,
213-
len_span: Option<Span>,
214-
app: &mut Applicability,
215-
) -> String {
216-
let args = args_span
217-
.map(|sp| snippet_with_applicability(cx, sp, "..", app))
218-
.unwrap_or_default();
202+
fn snippet(self, cx: &LateContext<'_>, args_span: Option<Span>, len_span: Option<Span>) -> String {
203+
let maybe_args = args_span.and_then(|sp| snippet_opt(cx, sp)).unwrap_or_default();
219204
let maybe_len = len_span
220-
.map(|sp| format!("; {}", snippet_with_applicability(cx, sp, "len", app)))
205+
.and_then(|sp| snippet_opt(cx, sp).map(|s| format!("; {s}")))
221206
.unwrap_or_default();
222207

223208
match self {
224-
Self::SliceRef(Mutability::Mut) => format!("&mut [{args}{maybe_len}]"),
225-
Self::SliceRef(Mutability::Not) => format!("&[{args}{maybe_len}]"),
226-
Self::Array => format!("[{args}{maybe_len}]"),
209+
Self::SliceRef(Mutability::Mut) => format!("&mut [{maybe_args}{maybe_len}]"),
210+
Self::SliceRef(Mutability::Not) => format!("&[{maybe_args}{maybe_len}]"),
211+
Self::Array => format!("[{maybe_args}{maybe_len}]"),
227212
}
228213
}
229214
}
@@ -249,3 +234,13 @@ pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
249234
is_trait_method(cx, e, sym::IntoIterator)
250235
}
251236
}
237+
238+
fn suggest_type(expr: &Expr<'_>) -> SuggestedType {
239+
if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
240+
// `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
241+
SuggestedType::SliceRef(mutability)
242+
} else {
243+
// `expr` is the `vec![_]` expansion, so suggest `[_]`
244+
SuggestedType::Array
245+
}
246+
}

tests/ui/vec.fixed

+4
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,7 @@ fn issue_11958() {
217217
// should not lint, `String` is not `Copy`
218218
f(&vec!["test".to_owned(); 2]);
219219
}
220+
221+
fn issue_12101() {
222+
for a in &[1, 2] {}
223+
}

tests/ui/vec.rs

+4
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,7 @@ fn issue_11958() {
217217
// should not lint, `String` is not `Copy`
218218
f(&vec!["test".to_owned(); 2]);
219219
}
220+
221+
fn issue_12101() {
222+
for a in &(vec![1, 2]) {}
223+
}

tests/ui/vec.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,11 @@ error: useless use of `vec!`
121121
LL | this_macro_doesnt_need_vec!(vec![1]);
122122
| ^^^^^^^ help: you can use an array directly: `[1]`
123123

124-
error: aborting due to 20 previous errors
124+
error: useless use of `vec!`
125+
--> tests/ui/vec.rs:222:14
126+
|
127+
LL | for a in &(vec![1, 2]) {}
128+
| ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
129+
130+
error: aborting due to 21 previous errors
125131

0 commit comments

Comments
 (0)