Skip to content

Commit 820f242

Browse files
committed
Address review feedback
1 parent dca4f5b commit 820f242

File tree

6 files changed

+26
-30
lines changed

6 files changed

+26
-30
lines changed

clippy_lints/src/index_refutable_slice.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clippy_utils::consts::{constant, Constant};
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::higher::IfLet;
4-
use clippy_utils::ty::implements_trait;
5-
use clippy_utils::{in_macro, is_expn_of, is_lint_allowed, meets_msrv, msrvs, path_to_local};
4+
use clippy_utils::ty::is_copy;
5+
use clippy_utils::{is_expn_of, is_lint_allowed, meets_msrv, msrvs, path_to_local};
66
use if_chain::if_chain;
77
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
88
use rustc_errors::Applicability;
@@ -46,21 +46,22 @@ declare_clippy_lint! {
4646
/// println!("{}", first);
4747
/// }
4848
/// ```
49+
#[clippy::version = "1.58.0"]
4950
pub INDEX_REFUTABLE_SLICE,
5051
nursery,
5152
"avoid indexing on slices which could be destructed"
5253
}
5354

5455
#[derive(Copy, Clone)]
5556
pub struct IndexRefutableSlice {
56-
indexing_limit: u64,
57+
max_suggested_slice: u64,
5758
msrv: Option<RustcVersion>,
5859
}
5960

6061
impl IndexRefutableSlice {
6162
pub fn new(max_suggested_slice_pattern_length: u64, msrv: Option<RustcVersion>) -> Self {
6263
Self {
63-
indexing_limit: max_suggested_slice_pattern_length - 1,
64+
max_suggested_slice: max_suggested_slice_pattern_length,
6465
msrv,
6566
}
6667
}
@@ -71,14 +72,14 @@ impl_lint_pass!(IndexRefutableSlice => [INDEX_REFUTABLE_SLICE]);
7172
impl LateLintPass<'_> for IndexRefutableSlice {
7273
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
7374
if_chain! {
74-
if !in_macro(expr.span) || is_expn_of(expr.span, "if_chain").is_some();
75+
if !expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some();
7576
if let Some(IfLet {let_pat, if_then, ..}) = IfLet::hir(cx, expr);
7677
if !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id);
7778
if meets_msrv(self.msrv.as_ref(), &msrvs::SLICE_PATTERNS);
7879

7980
let found_slices = find_slice_values(cx, let_pat);
8081
if !found_slices.is_empty();
81-
let filtered_slices = filter_lintable_slices(cx, found_slices, self.indexing_limit, if_then);
82+
let filtered_slices = filter_lintable_slices(cx, found_slices, self.max_suggested_slice, if_then);
8283
if !filtered_slices.is_empty();
8384
then {
8485
for slice in filtered_slices.values() {
@@ -117,12 +118,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxHashMap<hir:
117118
// The values need to use the `ref` keyword if they can't be copied.
118119
// This will need to be adjusted if the lint want to support multable access in the future
119120
let src_is_ref = bound_ty.is_ref() && binding != hir::BindingAnnotation::Ref;
120-
let is_copy = cx
121-
.tcx
122-
.lang_items()
123-
.copy_trait()
124-
.map_or(false, |trait_id| implements_trait(cx, inner_ty, trait_id, &[]));
125-
let needs_ref = !(src_is_ref || is_copy);
121+
let needs_ref = !(src_is_ref || is_copy(cx, inner_ty));
126122

127123
let slice_info = slices
128124
.entry(value_hir_id)
@@ -183,10 +179,9 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
183179
Applicability::MaybeIncorrect,
184180
);
185181

186-
// I thought about adding a note to the lint message to inform the user that these
187-
// refactorings will remove the index expression. However, I decided against this,
188-
// as `filter_lintable_slices` will only return slices where all access indices are
189-
// known at compile time. The removal should therefore not have any side effects.
182+
// The lint message doesn't contain a warning about the removed index expression,
183+
// since `filter_lintable_slices` will only return slices where all access indices
184+
// are known at compile time. Therefore, they can be removed without side effects.
190185
},
191186
);
192187
}
@@ -214,13 +209,13 @@ impl SliceLintInformation {
214209
fn filter_lintable_slices<'a, 'tcx>(
215210
cx: &'a LateContext<'tcx>,
216211
slice_lint_info: FxHashMap<hir::HirId, SliceLintInformation>,
217-
index_limit: u64,
212+
max_suggested_slice: u64,
218213
scope: &'tcx hir::Expr<'tcx>,
219214
) -> FxHashMap<hir::HirId, SliceLintInformation> {
220215
let mut visitor = SliceIndexLintingVisitor {
221216
cx,
222217
slice_lint_info,
223-
index_limit,
218+
max_suggested_slice,
224219
};
225220

226221
intravisit::walk_expr(&mut visitor, scope);
@@ -234,7 +229,7 @@ fn filter_lintable_slices<'a, 'tcx>(
234229
struct SliceIndexLintingVisitor<'a, 'tcx> {
235230
cx: &'a LateContext<'tcx>,
236231
slice_lint_info: FxHashMap<hir::HirId, SliceLintInformation>,
237-
index_limit: u64,
232+
max_suggested_slice: u64,
238233
}
239234

240235
impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
@@ -249,7 +244,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
249244
let Self {
250245
cx,
251246
ref mut slice_lint_info,
252-
index_limit,
247+
max_suggested_slice,
253248
} = *self;
254249

255250
if_chain! {
@@ -264,7 +259,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
264259
if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind;
265260
if let Some((Constant::Int(index_value), _)) = constant(cx, cx.typeck_results(), index_expr);
266261
if let Ok(index_value) = index_value.try_into();
267-
if index_value <= index_limit;
262+
if index_value < max_suggested_slice;
268263

269264
// Make sure that this slice index is read only
270265
let maybe_addrof_id = map.get_parent_node(parent_id);

clippy_lints/src/utils/conf.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ define_Conf! {
298298
(enable_raw_pointer_heuristic_for_send: bool = true),
299299
/// Lint: INDEX_REFUTABLE_SLICE.
300300
///
301-
/// The limit after which slice indexing will not be linted.
302-
///
303-
/// As an example, the default limit of `3` would allow `slice[3]` but lint `slice[2]`.
301+
/// When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
302+
/// the slice pattern that is suggested. If more elements would be necessary, the lint is suppressed.
303+
/// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
304304
(max_suggested_slice_pattern_length: u64 = 3),
305305
}
306306

clippy_utils/src/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_trait_selection::traits::query::normalize::AtExt;
1919

2020
use crate::{match_def_path, must_use_attr};
2121

22+
// Checks if the given type implements copy.
2223
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
2324
ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env)
2425
}

tests/ui-toml/max_suggested_slice_pattern_length/avoidable_slice_indexing_limit.rs renamed to tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn below_limit() {
44
let slice: Option<&[u32]> = Some(&[1, 2, 3]);
55
if let Some(slice) = slice {
66
// This would usually not be linted but is included now due to the
7-
// index limit in the config gile
7+
// index limit in the config file
88
println!("{}", slice[7]);
99
}
1010
}

tests/ui-toml/max_suggested_slice_pattern_length/avoidable_slice_indexing_limit.stderr renamed to tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: this binding can be a slice pattern to avoid indexing
2-
--> $DIR/avoidable_slice_indexing_limit.rs:5:17
2+
--> $DIR/index_refutable_slice.rs:5:17
33
|
44
LL | if let Some(slice) = slice {
55
| ^^^^^
66
|
77
note: the lint level is defined here
8-
--> $DIR/avoidable_slice_indexing_limit.rs:1:9
8+
--> $DIR/index_refutable_slice.rs:1:9
99
|
1010
LL | #![deny(clippy::index_refutable_slice)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui-toml/min_rust_version/min_rust_version.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ fn manual_strip_msrv() {
5959
}
6060
}
6161

62-
fn check_avoidable_slice_indexing() {
63-
// This shouldn't trigger `clippy::avoidable_slice_indexing` as the suggestion
62+
fn check_index_refutable_slice() {
63+
// This shouldn't trigger `clippy::index_refutable_slice` as the suggestion
6464
// would only be valid from 1.42.0 onward
6565
let slice: Option<&[u32]> = Some(&[1]);
6666
if let Some(slice) = slice {
@@ -74,5 +74,5 @@ fn main() {
7474
match_same_arms();
7575
match_same_arms2();
7676
manual_strip_msrv();
77-
check_avoidable_slice_indexing();
77+
check_index_refutable_slice();
7878
}

0 commit comments

Comments
 (0)