Skip to content

Commit 07f5e64

Browse files
committed
Improve diagnostic message for only_used_in_recursion
1 parent efc9e11 commit 07f5e64

File tree

2 files changed

+153
-27
lines changed

2 files changed

+153
-27
lines changed

clippy_lints/src/only_used_in_recursion.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
use clippy_utils::diagnostics::span_lint;
1+
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::{get_expr_use_or_unification_node, get_parent_node, path_def_id, path_to_local, path_to_local_id};
33
use core::cell::Cell;
44
use rustc_data_structures::fx::FxHashMap;
5+
use rustc_errors::Applicability;
56
use rustc_hir::def_id::DefId;
67
use rustc_hir::hir_id::HirIdMap;
78
use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind};
89
use rustc_lint::{LateContext, LateLintPass};
910
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
1011
use rustc_middle::ty::{self, ConstKind};
1112
use rustc_session::{declare_tool_lint, impl_lint_pass};
13+
use rustc_span::symbol::Ident;
1214
use rustc_span::Span;
1315

1416
declare_clippy_lint! {
@@ -99,19 +101,19 @@ struct Param {
99101
fn_kind: FnKind,
100102
/// The index of this parameter.
101103
idx: u32,
102-
span: Span,
104+
ident: Ident,
103105
/// Whether this parameter should be linted. Set by `Params::flag_for_linting`.
104106
block_lint: Cell<bool>,
105107
/// All the uses of this parameter.
106108
uses: Vec<Usage>,
107109
}
108110
impl Param {
109-
fn new(fn_id: DefId, fn_kind: FnKind, idx: u32, span: Span) -> Self {
111+
fn new(fn_id: DefId, fn_kind: FnKind, idx: u32, ident: Ident) -> Self {
110112
Self {
111113
fn_id,
112114
fn_kind,
113115
idx,
114-
span,
116+
ident,
115117
block_lint: Cell::new(false),
116118
uses: Vec::new(),
117119
}
@@ -120,7 +122,6 @@ impl Param {
120122

121123
#[derive(Debug)]
122124
struct Usage {
123-
#[allow(dead_code)]
124125
span: Span,
125126
idx: u32,
126127
}
@@ -271,7 +272,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
271272
.filter_map(|(idx, p)| match p.pat.kind {
272273
#[allow(clippy::cast_possible_truncation)]
273274
PatKind::Binding(_, id, ident, None) if !ident.as_str().starts_with('_') => {
274-
Some((id, Param::new(fn_id, fn_kind, idx as u32, ident.span)))
275+
Some((id, Param::new(fn_id, fn_kind, idx as u32, ident)))
275276
},
276277
_ => None,
277278
})
@@ -358,11 +359,23 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
358359
self.params.flag_for_linting();
359360
for param in &self.params.params {
360361
if !param.block_lint.get() {
361-
span_lint(
362+
span_lint_and_then(
362363
cx,
363364
ONLY_USED_IN_RECURSION,
364-
param.span,
365+
param.ident.span,
365366
"parameter is only used in recursion",
367+
|diag| {
368+
diag.span_suggestion(
369+
param.ident.span,
370+
"if this is intentional, prefix it with an underscore",
371+
format!("_{}", param.ident.name),
372+
Applicability::MaybeIncorrect,
373+
)
374+
.span_note(
375+
param.uses.iter().map(|x| x.span).collect::<Vec<_>>(),
376+
"parameter used here",
377+
);
378+
},
366379
);
367380
}
368381
}

tests/ui/only_used_in_recursion.stderr

Lines changed: 132 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,117 +2,230 @@ error: parameter is only used in recursion
22
--> $DIR/only_used_in_recursion.rs:11:27
33
|
44
LL | fn _one_unused(flag: u32, a: usize) -> usize {
5-
| ^
5+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
66
|
77
= note: `-D clippy::only-used-in-recursion` implied by `-D warnings`
8+
note: parameter used here
9+
--> $DIR/only_used_in_recursion.rs:12:53
10+
|
11+
LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) }
12+
| ^
813

914
error: parameter is only used in recursion
1015
--> $DIR/only_used_in_recursion.rs:15:27
1116
|
1217
LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
13-
| ^
18+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
19+
|
20+
note: parameter used here
21+
--> $DIR/only_used_in_recursion.rs:16:53
22+
|
23+
LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
24+
| ^
1425

1526
error: parameter is only used in recursion
1627
--> $DIR/only_used_in_recursion.rs:15:35
1728
|
1829
LL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {
19-
| ^
30+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
31+
|
32+
note: parameter used here
33+
--> $DIR/only_used_in_recursion.rs:16:56
34+
|
35+
LL | if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }
36+
| ^
2037

2138
error: parameter is only used in recursion
2239
--> $DIR/only_used_in_recursion.rs:19:26
2340
|
2441
LL | fn _with_calc(flag: u32, a: i64) -> usize {
25-
| ^
42+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
43+
|
44+
note: parameter used here
45+
--> $DIR/only_used_in_recursion.rs:23:32
46+
|
47+
LL | _with_calc(flag - 1, (-a + 10) * 5)
48+
| ^
2649

2750
error: parameter is only used in recursion
2851
--> $DIR/only_used_in_recursion.rs:32:33
2952
|
3053
LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
31-
| ^
54+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
55+
|
56+
note: parameter used here
57+
--> $DIR/only_used_in_recursion.rs:36:38
58+
|
59+
LL | _used_with_unused(flag - 1, -a, a + b)
60+
| ^ ^
3261

3362
error: parameter is only used in recursion
3463
--> $DIR/only_used_in_recursion.rs:32:41
3564
|
3665
LL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {
37-
| ^
66+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
67+
|
68+
note: parameter used here
69+
--> $DIR/only_used_in_recursion.rs:36:45
70+
|
71+
LL | _used_with_unused(flag - 1, -a, a + b)
72+
| ^
3873

3974
error: parameter is only used in recursion
4075
--> $DIR/only_used_in_recursion.rs:40:35
4176
|
4277
LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
43-
| ^
78+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
79+
|
80+
note: parameter used here
81+
--> $DIR/only_used_in_recursion.rs:44:39
82+
|
83+
LL | _codependent_unused(flag - 1, a * b, a + b)
84+
| ^ ^
4485

4586
error: parameter is only used in recursion
4687
--> $DIR/only_used_in_recursion.rs:40:43
4788
|
4889
LL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {
49-
| ^
90+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
91+
|
92+
note: parameter used here
93+
--> $DIR/only_used_in_recursion.rs:44:43
94+
|
95+
LL | _codependent_unused(flag - 1, a * b, a + b)
96+
| ^ ^
5097

5198
error: parameter is only used in recursion
5299
--> $DIR/only_used_in_recursion.rs:48:30
53100
|
54101
LL | fn _not_primitive(flag: u32, b: String) -> usize {
55-
| ^
102+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
103+
|
104+
note: parameter used here
105+
--> $DIR/only_used_in_recursion.rs:49:56
106+
|
107+
LL | if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }
108+
| ^
56109

57110
error: parameter is only used in recursion
58111
--> $DIR/only_used_in_recursion.rs:55:29
59112
|
60113
LL | fn _method(flag: usize, a: usize) -> usize {
61-
| ^
114+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
115+
|
116+
note: parameter used here
117+
--> $DIR/only_used_in_recursion.rs:56:59
118+
|
119+
LL | if flag == 0 { 0 } else { Self::_method(flag - 1, a) }
120+
| ^
62121

63122
error: parameter is only used in recursion
64123
--> $DIR/only_used_in_recursion.rs:59:22
65124
|
66125
LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
67-
| ^^^^
126+
| ^^^^ help: if this is intentional, prefix it with an underscore: `_self`
127+
|
128+
note: parameter used here
129+
--> $DIR/only_used_in_recursion.rs:60:35
130+
|
131+
LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
132+
| ^^^^
68133

69134
error: parameter is only used in recursion
70135
--> $DIR/only_used_in_recursion.rs:59:41
71136
|
72137
LL | fn _method_self(&self, flag: usize, a: usize) -> usize {
73-
| ^
138+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
139+
|
140+
note: parameter used here
141+
--> $DIR/only_used_in_recursion.rs:60:63
142+
|
143+
LL | if flag == 0 { 0 } else { self._method_self(flag - 1, a) }
144+
| ^
74145

75146
error: parameter is only used in recursion
76147
--> $DIR/only_used_in_recursion.rs:70:26
77148
|
78149
LL | fn method(flag: u32, a: usize) -> usize {
79-
| ^
150+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
151+
|
152+
note: parameter used here
153+
--> $DIR/only_used_in_recursion.rs:71:58
154+
|
155+
LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
156+
| ^
80157

81158
error: parameter is only used in recursion
82159
--> $DIR/only_used_in_recursion.rs:74:38
83160
|
84161
LL | fn method_self(&self, flag: u32, a: usize) -> usize {
85-
| ^
162+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
163+
|
164+
note: parameter used here
165+
--> $DIR/only_used_in_recursion.rs:75:62
166+
|
167+
LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
168+
| ^
86169

87170
error: parameter is only used in recursion
88171
--> $DIR/only_used_in_recursion.rs:100:26
89172
|
90173
LL | fn method(flag: u32, a: usize) -> usize {
91-
| ^
174+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
175+
|
176+
note: parameter used here
177+
--> $DIR/only_used_in_recursion.rs:101:58
178+
|
179+
LL | if flag == 0 { 0 } else { Self::method(flag - 1, a) }
180+
| ^
92181

93182
error: parameter is only used in recursion
94183
--> $DIR/only_used_in_recursion.rs:104:38
95184
|
96185
LL | fn method_self(&self, flag: u32, a: usize) -> usize {
97-
| ^
186+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
187+
|
188+
note: parameter used here
189+
--> $DIR/only_used_in_recursion.rs:105:62
190+
|
191+
LL | if flag == 0 { 0 } else { self.method_self(flag - 1, a) }
192+
| ^
98193

99194
error: parameter is only used in recursion
100195
--> $DIR/only_used_in_recursion.rs:113:35
101196
|
102197
LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize {
103-
| ^
198+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
199+
|
200+
note: parameter used here
201+
--> $DIR/only_used_in_recursion.rs:119:52
202+
|
203+
LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }
204+
| ^
104205

105206
error: parameter is only used in recursion
106207
--> $DIR/only_used_in_recursion.rs:114:25
107208
|
108209
LL | fn inner(flag: u32, a: u32) -> u32 {
109-
| ^
210+
| ^ help: if this is intentional, prefix it with an underscore: `_a`
211+
|
212+
note: parameter used here
213+
--> $DIR/only_used_in_recursion.rs:115:47
214+
|
215+
LL | if flag == 0 { 0 } else { inner(flag, a) }
216+
| ^
110217

111218
error: parameter is only used in recursion
112219
--> $DIR/only_used_in_recursion.rs:122:34
113220
|
114221
LL | fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {
115-
| ^
222+
| ^ help: if this is intentional, prefix it with an underscore: `_b`
223+
|
224+
note: parameter used here
225+
--> $DIR/only_used_in_recursion.rs:124:32
226+
|
227+
LL | _with_closure(Some(x), b, f)
228+
| ^
116229

117230
error: aborting due to 19 previous errors
118231

0 commit comments

Comments
 (0)