Skip to content

Commit 49241ba

Browse files
committed
Fix: index_refutable_slice multipart
1 parent 479e1fc commit 49241ba

File tree

6 files changed

+95
-96
lines changed

6 files changed

+95
-96
lines changed

clippy_lints/src/index_refutable_slice.rs

+16-22
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
135135
.map(|(index, _)| *index)
136136
.collect::<FxIndexSet<_>>();
137137

138-
let value_name = |index| format!("{}_{index}", slice.ident.name);
138+
let value_name = |index| format!("{}_{}", slice.ident.name, index);
139139

140140
if let Some(max_index) = used_indices.iter().max() {
141141
let opt_ref = if slice.needs_ref { "ref " } else { "" };
@@ -150,35 +150,29 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
150150
.collect::<Vec<_>>();
151151
let pat_sugg = format!("[{}, ..]", pat_sugg_idents.join(", "));
152152

153+
let mut suggestions = Vec::new();
154+
155+
// Add the binding pattern suggestion
156+
if !slice.pattern_spans.is_empty() {
157+
suggestions.extend(slice.pattern_spans.iter().map(|span| (*span, pat_sugg.clone())));
158+
}
159+
160+
// Add the index replacement suggestions
161+
if !slice.index_use.is_empty() {
162+
suggestions.extend(slice.index_use.iter().map(|(index, span)| (*span, value_name(*index))));
163+
}
164+
153165
span_lint_and_then(
154166
cx,
155167
INDEX_REFUTABLE_SLICE,
156168
slice.ident.span,
157169
"this binding can be a slice pattern to avoid indexing",
158170
|diag| {
159171
diag.multipart_suggestion(
160-
"try using a slice pattern here",
161-
slice
162-
.pattern_spans
163-
.iter()
164-
.map(|span| (*span, pat_sugg.clone()))
165-
.collect(),
166-
Applicability::MaybeIncorrect,
172+
"replace the binding and indexed access with a slice pattern",
173+
suggestions,
174+
Applicability::MachineApplicable,
167175
);
168-
169-
diag.multipart_suggestion(
170-
"and replace the index expressions here",
171-
slice
172-
.index_use
173-
.iter()
174-
.map(|(index, span)| (*span, value_name(*index)))
175-
.collect(),
176-
Applicability::MaybeIncorrect,
177-
);
178-
179-
// The lint message doesn't contain a warning about the removed index expression,
180-
// since `filter_lintable_slices` will only return slices where all access indices
181-
// are known at compile time. Therefore, they can be removed without side effects.
182176
},
183177
);
184178
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![deny(clippy::index_refutable_slice)]
2+
3+
fn below_limit() {
4+
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
5+
if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
6+
//~^ ERROR: binding can be a slice pattern
7+
// This would usually not be linted but is included now due to the
8+
// index limit in the config file
9+
println!("{}", slice_7);
10+
}
11+
}
12+
13+
fn above_limit() {
14+
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
15+
if let Some(slice) = slice {
16+
// This will not be linted as 8 is above the limit
17+
println!("{}", slice[8]);
18+
}
19+
}
20+
21+
fn main() {
22+
below_limit();
23+
above_limit();
24+
}

tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#![deny(clippy::index_refutable_slice)]
22

3-
//@no-rustfix: need to change the suggestion to a multipart suggestion
4-
53
fn below_limit() {
64
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
75
if let Some(slice) = slice {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this binding can be a slice pattern to avoid indexing
2-
--> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:7:17
2+
--> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:5:17
33
|
44
LL | if let Some(slice) = slice {
55
| ^^^^^
@@ -9,14 +9,14 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(clippy::index_refutable_slice)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
help: try using a slice pattern here
12+
help: replace the binding and indexed access with a slice pattern
1313
|
14-
LL | if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
15-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16-
help: and replace the index expressions here
14+
LL ~ if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
15+
LL |
16+
LL | // This would usually not be linted but is included now due to the
17+
LL | // index limit in the config file
18+
LL ~ println!("{}", slice_7);
1719
|
18-
LL | println!("{}", slice_7);
19-
| ~~~~~~~
2020

2121
error: aborting due to 1 previous error
2222

tests/ui/index_refutable_slice/if_let_slice_binding.stderr

+43-59
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,36 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(clippy::index_refutable_slice)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
help: try using a slice pattern here
12+
help: replace the binding and indexed access with a slice pattern
1313
|
14-
LL | if let Some([slice_0, ..]) = slice {
15-
| ~~~~~~~~~~~~~
16-
help: and replace the index expressions here
14+
LL ~ if let Some([slice_0, ..]) = slice {
15+
LL |
16+
LL ~ println!("{}", slice_0);
1717
|
18-
LL | println!("{}", slice_0);
19-
| ~~~~~~~
2018

2119
error: this binding can be a slice pattern to avoid indexing
2220
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:23:17
2321
|
2422
LL | if let Some(slice) = slice {
2523
| ^^^^^
2624
|
27-
help: try using a slice pattern here
25+
help: replace the binding and indexed access with a slice pattern
2826
|
29-
LL | if let Some([slice_0, ..]) = slice {
30-
| ~~~~~~~~~~~~~
31-
help: and replace the index expressions here
27+
LL ~ if let Some([slice_0, ..]) = slice {
28+
LL |
29+
LL ~ println!("{}", slice_0);
3230
|
33-
LL | println!("{}", slice_0);
34-
| ~~~~~~~
3531

3632
error: this binding can be a slice pattern to avoid indexing
3733
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17
3834
|
3935
LL | if let Some(slice) = slice {
4036
| ^^^^^
4137
|
42-
help: try using a slice pattern here
43-
|
44-
LL | if let Some([slice_0, _, slice_2, ..]) = slice {
45-
| ~~~~~~~~~~~~~~~~~~~~~~~~~
46-
help: and replace the index expressions here
38+
help: replace the binding and indexed access with a slice pattern
4739
|
40+
LL ~ if let Some([slice_0, _, slice_2, ..]) = slice {
41+
LL |
4842
LL ~ println!("{}", slice_2);
4943
LL ~ println!("{}", slice_0);
5044
|
@@ -55,104 +49,94 @@ error: this binding can be a slice pattern to avoid indexing
5549
LL | if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
5650
| ^^^^^
5751
|
58-
help: try using a slice pattern here
52+
help: replace the binding and indexed access with a slice pattern
5953
|
60-
LL | if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
61-
| ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
62-
help: and replace the index expressions here
54+
LL ~ if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
55+
LL |
56+
LL ~ println!("{}", slice_0);
6357
|
64-
LL | println!("{}", slice_0);
65-
| ~~~~~~~
6658

6759
error: this binding can be a slice pattern to avoid indexing
6860
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:29
6961
|
7062
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
7163
| ^
7264
|
73-
help: try using a slice pattern here
65+
help: replace the binding and indexed access with a slice pattern
7466
|
75-
LL | if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) {
76-
| ~~~~~~~~~~~~~~~
77-
help: and replace the index expressions here
67+
LL ~ if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) {
68+
LL |
69+
LL |
70+
LL ~ println!("{} -> {}", a_2, b[1]);
7871
|
79-
LL | println!("{} -> {}", a_2, b[1]);
80-
| ~~~
8172

8273
error: this binding can be a slice pattern to avoid indexing
8374
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:38
8475
|
8576
LL | if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
8677
| ^
8778
|
88-
help: try using a slice pattern here
79+
help: replace the binding and indexed access with a slice pattern
8980
|
90-
LL | if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
91-
| ~~~~~~~~~~~~
92-
help: and replace the index expressions here
81+
LL ~ if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
82+
LL |
83+
LL |
84+
LL ~ println!("{} -> {}", a[2], b_1);
9385
|
94-
LL | println!("{} -> {}", a[2], b_1);
95-
| ~~~
9686

9787
error: this binding can be a slice pattern to avoid indexing
9888
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:55:21
9989
|
10090
LL | if let Some(ref slice) = slice {
10191
| ^^^^^
10292
|
103-
help: try using a slice pattern here
93+
help: replace the binding and indexed access with a slice pattern
10494
|
105-
LL | if let Some([_, ref slice_1, ..]) = slice {
106-
| ~~~~~~~~~~~~~~~~~~~~
107-
help: and replace the index expressions here
95+
LL ~ if let Some([_, ref slice_1, ..]) = slice {
96+
LL |
97+
LL ~ println!("{:?}", slice_1);
10898
|
109-
LL | println!("{:?}", slice_1);
110-
| ~~~~~~~
11199

112100
error: this binding can be a slice pattern to avoid indexing
113101
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:64:17
114102
|
115103
LL | if let Some(slice) = &slice {
116104
| ^^^^^
117105
|
118-
help: try using a slice pattern here
106+
help: replace the binding and indexed access with a slice pattern
119107
|
120-
LL | if let Some([slice_0, ..]) = &slice {
121-
| ~~~~~~~~~~~~~
122-
help: and replace the index expressions here
108+
LL ~ if let Some([slice_0, ..]) = &slice {
109+
LL |
110+
LL ~ println!("{:?}", slice_0);
123111
|
124-
LL | println!("{:?}", slice_0);
125-
| ~~~~~~~
126112

127113
error: this binding can be a slice pattern to avoid indexing
128114
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:134:17
129115
|
130116
LL | if let Some(slice) = wrap.inner {
131117
| ^^^^^
132118
|
133-
help: try using a slice pattern here
119+
help: replace the binding and indexed access with a slice pattern
134120
|
135-
LL | if let Some([slice_0, ..]) = wrap.inner {
136-
| ~~~~~~~~~~~~~
137-
help: and replace the index expressions here
121+
LL ~ if let Some([slice_0, ..]) = wrap.inner {
122+
LL |
123+
LL | if wrap.is_awesome {
124+
LL ~ println!("This is awesome! {}", slice_0);
138125
|
139-
LL | println!("This is awesome! {}", slice_0);
140-
| ~~~~~~~
141126

142127
error: this binding can be a slice pattern to avoid indexing
143128
--> tests/ui/index_refutable_slice/if_let_slice_binding.rs:142:17
144129
|
145130
LL | if let Some(slice) = wrap.inner {
146131
| ^^^^^
147132
|
148-
help: try using a slice pattern here
133+
help: replace the binding and indexed access with a slice pattern
149134
|
150-
LL | if let Some([slice_0, ..]) = wrap.inner {
151-
| ~~~~~~~~~~~~~
152-
help: and replace the index expressions here
135+
LL ~ if let Some([slice_0, ..]) = wrap.inner {
136+
LL |
137+
LL | if wrap.is_super_awesome() {
138+
LL ~ println!("This is super awesome! {}", slice_0);
153139
|
154-
LL | println!("This is super awesome! {}", slice_0);
155-
| ~~~~~~~
156140

157141
error: aborting due to 10 previous errors
158142

tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(clippy::index_refutable_slice)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
help: try using a slice pattern here
12+
help: replace the binding and indexed access with a slice pattern
1313
|
14-
LL | if let Some([slice_0, ..]) = slice;
15-
| ~~~~~~~~~~~~~
16-
help: and replace the index expressions here
14+
LL ~ if let Some([slice_0, ..]) = slice;
15+
LL |
16+
LL | then {
17+
LL ~ println!("{}", slice_0);
1718
|
18-
LL | println!("{}", slice_0);
19-
| ~~~~~~~
2019

2120
error: aborting due to 1 previous error
2221

0 commit comments

Comments
 (0)