Skip to content

Commit 837bc99

Browse files
committed
Initial implementation of redundant_slicing lint
1 parent 3577cf7 commit 837bc99

File tree

5 files changed

+89
-0
lines changed

5 files changed

+89
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,7 @@ Released 2018-09-13
21622162
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
21632163
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
21642164
[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate
2165+
[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing
21652166
[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
21662167
[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
21672168
[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref

clippy_lints/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ mod redundant_closure_call;
301301
mod redundant_else;
302302
mod redundant_field_names;
303303
mod redundant_pub_crate;
304+
mod redundant_slicing;
304305
mod redundant_static_lifetimes;
305306
mod ref_option_ref;
306307
mod reference;
@@ -849,6 +850,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
849850
&redundant_else::REDUNDANT_ELSE,
850851
&redundant_field_names::REDUNDANT_FIELD_NAMES,
851852
&redundant_pub_crate::REDUNDANT_PUB_CRATE,
853+
&redundant_slicing::REDUNDANT_SLICING,
852854
&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
853855
&ref_option_ref::REF_OPTION_REF,
854856
&reference::DEREF_ADDROF,
@@ -1229,6 +1231,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12291231
store.register_late_pass(|| box vec_init_then_push::VecInitThenPush::default());
12301232
store.register_late_pass(move || box types::PtrAsPtr::new(msrv));
12311233
store.register_late_pass(|| box case_sensitive_file_extension_comparisons::CaseSensitiveFileExtensionComparisons);
1234+
store.register_late_pass(|| box redundant_slicing::RedundantSlicing);
12321235

12331236
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
12341237
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1591,6 +1594,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15911594
LintId::of(&redundant_clone::REDUNDANT_CLONE),
15921595
LintId::of(&redundant_closure_call::REDUNDANT_CLOSURE_CALL),
15931596
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
1597+
LintId::of(&redundant_slicing::REDUNDANT_SLICING),
15941598
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
15951599
LintId::of(&reference::DEREF_ADDROF),
15961600
LintId::of(&reference::REF_IN_DEREF),
@@ -1835,6 +1839,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
18351839
LintId::of(&ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
18361840
LintId::of(&ranges::RANGE_ZIP_WITH_LEN),
18371841
LintId::of(&redundant_closure_call::REDUNDANT_CLOSURE_CALL),
1842+
LintId::of(&redundant_slicing::REDUNDANT_SLICING),
18381843
LintId::of(&reference::DEREF_ADDROF),
18391844
LintId::of(&reference::REF_IN_DEREF),
18401845
LintId::of(&repeat_once::REPEAT_ONCE),

clippy_lints/src/redundant_slicing.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use if_chain::if_chain;
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{Expr, ExprKind, LangItem};
4+
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_middle::ty::TyS;
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
use crate::utils::{is_type_lang_item, snippet_with_applicability, span_lint_and_sugg};
9+
10+
declare_clippy_lint! {
11+
/// **What it does:** Checks for redundant slicing expressions which use the full range, and
12+
/// do not change the type.
13+
///
14+
/// **Why is this bad?** It unnecessarily adds complexity to the expression.
15+
///
16+
/// **Known problems:** If the type being sliced has an implementation of `Index<RangeFull>`
17+
/// that actually changes anything then it can't be removed. However, this would be surprising
18+
/// to people reading the code and should have a note with it.
19+
///
20+
/// **Example:**
21+
///
22+
/// ```ignore
23+
/// fn get_slice(x: &[u32]) -> &[u32] {
24+
/// &x[..]
25+
/// }
26+
/// ```
27+
/// Use instead:
28+
/// ```ignore
29+
/// fn get_slice(x: &[u32]) -> &[u32] {
30+
/// x
31+
/// }
32+
/// ```
33+
pub REDUNDANT_SLICING,
34+
complexity,
35+
"redundant slicing of the whole range of a type"
36+
}
37+
38+
declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING]);
39+
40+
impl LateLintPass<'_> for RedundantSlicing {
41+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
42+
if_chain! {
43+
if let ExprKind::AddrOf(_, _, addressee) = expr.kind;
44+
if let ExprKind::Index(indexed, range) = addressee.kind;
45+
if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
46+
if TyS::same_type(cx.typeck_results().expr_ty(expr), cx.typeck_results().expr_ty(indexed));
47+
then {
48+
let mut app = Applicability::MachineApplicable;
49+
let hint = snippet_with_applicability(cx, indexed.span, "..", &mut app).into_owned();
50+
51+
span_lint_and_sugg(cx, REDUNDANT_SLICING, expr.span, "redundant slicing of the whole range",
52+
"use the original slice instead", hint, app);
53+
}
54+
}
55+
}
56+
}

tests/ui/redundant_slicing.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(unused)]
2+
#![warn(clippy::redundant_slicing)]
3+
4+
fn main() {
5+
let x: &[u32] = &[0];
6+
let err = &x[..];
7+
8+
let v = vec![0];
9+
let ok = &v[..];
10+
let err = &(&v[..])[..];
11+
}

tests/ui/redundant_slicing.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: redundant slicing of the whole range
2+
--> $DIR/redundant_slicing.rs:6:15
3+
|
4+
LL | let err = &x[..];
5+
| ^^^^^^ help: use the original slice instead: `x`
6+
|
7+
= note: `-D clippy::redundant-slicing` implied by `-D warnings`
8+
9+
error: redundant slicing of the whole range
10+
--> $DIR/redundant_slicing.rs:10:15
11+
|
12+
LL | let err = &(&v[..])[..];
13+
| ^^^^^^^^^^^^^ help: use the original slice instead: `(&v[..])`
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)