Skip to content

Commit 0f306ac

Browse files
committed
emit lints in check_crate_post for useless_vec
1 parent 91c5653 commit 0f306ac

File tree

2 files changed

+44
-26
lines changed

2 files changed

+44
-26
lines changed

clippy_lints/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ extern crate clippy_utils;
5050
#[macro_use]
5151
extern crate declare_clippy_lint;
5252

53+
use std::collections::{BTreeMap, BTreeSet};
54+
5355
use rustc_data_structures::fx::FxHashSet;
5456
use rustc_lint::{Lint, LintId};
5557

@@ -722,6 +724,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
722724
Box::new(vec::UselessVec {
723725
too_large_for_stack,
724726
msrv: msrv(),
727+
span_to_lint_map: BTreeMap::new(),
728+
spans_sure_to_lint: BTreeSet::new(),
725729
})
726730
});
727731
store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));

clippy_lints/src/vec.rs

+40-26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::{BTreeMap, BTreeSet};
12
use std::ops::ControlFlow;
23

34
use clippy_config::msrvs::{self, Msrv};
@@ -20,6 +21,8 @@ use rustc_span::{sym, Span};
2021
pub struct UselessVec {
2122
pub too_large_for_stack: u64,
2223
pub msrv: Msrv,
24+
pub span_to_lint_map: BTreeMap<Span, Option<(SuggestedType, String, Applicability)>>,
25+
pub spans_sure_to_lint: BTreeSet<Span>,
2326
}
2427

2528
declare_clippy_lint! {
@@ -70,9 +73,7 @@ pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
7073
impl<'tcx> LateLintPass<'tcx> for UselessVec {
7174
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
7275
// search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
73-
if adjusts_to_slice(cx, expr)
74-
&& let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows())
75-
{
76+
if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) {
7677
let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
7778
// `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
7879
(SuggestedType::SliceRef(mutability), expr.span)
@@ -82,7 +83,11 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
8283
(SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site)
8384
};
8485

85-
self.check_vec_macro(cx, &vec_args, span, suggest_slice);
86+
if adjusts_to_slice(cx, expr) {
87+
self.check_vec_macro(cx, &vec_args, span, suggest_slice);
88+
} else if !self.spans_sure_to_lint.contains(&span) {
89+
self.span_to_lint_map.insert(span, None);
90+
}
8691
}
8792

8893
// search for `let foo = vec![_]` expressions where all uses of `foo`
@@ -110,12 +115,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
110115
.is_continue();
111116

112117
if only_slice_uses {
113-
self.check_vec_macro(
114-
cx,
115-
&vec_args,
116-
expr.span.ctxt().outer_expn_data().call_site,
117-
SuggestedType::Array,
118-
);
118+
let span = expr.span.ctxt().outer_expn_data().call_site;
119+
self.spans_sure_to_lint.insert(span);
120+
self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array);
119121
}
120122
}
121123

@@ -126,15 +128,38 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
126128
{
127129
// report the error around the `vec!` not inside `<std macros>:`
128130
let span = arg.span.ctxt().outer_expn_data().call_site;
131+
self.spans_sure_to_lint.insert(span);
129132
self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array);
130133
}
131134
}
132135

136+
fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
137+
for (span, lint_opt) in self.span_to_lint_map.clone() {
138+
if let Some((suggest_slice, snippet, applicability)) = lint_opt {
139+
span_lint_and_sugg(
140+
cx,
141+
USELESS_VEC,
142+
span,
143+
"useless use of `vec!`",
144+
&format!(
145+
"you can use {} directly",
146+
match suggest_slice {
147+
SuggestedType::SliceRef(_) => "a slice",
148+
SuggestedType::Array => "an array",
149+
}
150+
),
151+
snippet,
152+
applicability,
153+
);
154+
}
155+
}
156+
}
157+
133158
extract_msrv_attr!(LateContext);
134159
}
135160

136161
#[derive(Copy, Clone)]
137-
enum SuggestedType {
162+
pub enum SuggestedType {
138163
/// Suggest using a slice `&[..]` / `&mut [..]`
139164
SliceRef(Mutability),
140165
/// Suggest using an array: `[..]`
@@ -204,21 +229,10 @@ impl UselessVec {
204229
},
205230
};
206231

207-
span_lint_and_sugg(
208-
cx,
209-
USELESS_VEC,
210-
span,
211-
"useless use of `vec!`",
212-
&format!(
213-
"you can use {} directly",
214-
match suggest_slice {
215-
SuggestedType::SliceRef(_) => "a slice",
216-
SuggestedType::Array => "an array",
217-
}
218-
),
219-
snippet,
220-
applicability,
221-
);
232+
if !self.span_to_lint_map.contains_key(&span) || self.spans_sure_to_lint.contains(&span) {
233+
self.span_to_lint_map
234+
.insert(span, Some((suggest_slice, snippet, applicability)));
235+
}
222236
}
223237
}
224238

0 commit comments

Comments
 (0)