-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #6528 - Jarcho:redundant_slicing, r=flip1995
New lint: redundant_slicing changelog: Added lint: `redundant_slicing` fixes #6519 This will trigger on any type which implements `Index<RangeFull>` that returns the input type. This would be a false positive if the implementation does something other than return itself, but I'm not sure why you would ever want to do that.
- Loading branch information
Showing
6 changed files
with
101 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use if_chain::if_chain; | ||
use rustc_errors::Applicability; | ||
use rustc_hir::{Expr, ExprKind, LangItem}; | ||
use rustc_lint::{LateContext, LateLintPass, LintContext}; | ||
use rustc_middle::{lint::in_external_macro, ty::TyS}; | ||
use rustc_session::{declare_lint_pass, declare_tool_lint}; | ||
|
||
use crate::utils::{is_type_lang_item, snippet_with_applicability, span_lint_and_sugg}; | ||
|
||
declare_clippy_lint! { | ||
/// **What it does:** Checks for redundant slicing expressions which use the full range, and | ||
/// do not change the type. | ||
/// | ||
/// **Why is this bad?** It unnecessarily adds complexity to the expression. | ||
/// | ||
/// **Known problems:** If the type being sliced has an implementation of `Index<RangeFull>` | ||
/// that actually changes anything then it can't be removed. However, this would be surprising | ||
/// to people reading the code and should have a note with it. | ||
/// | ||
/// **Example:** | ||
/// | ||
/// ```ignore | ||
/// fn get_slice(x: &[u32]) -> &[u32] { | ||
/// &x[..] | ||
/// } | ||
/// ``` | ||
/// Use instead: | ||
/// ```ignore | ||
/// fn get_slice(x: &[u32]) -> &[u32] { | ||
/// x | ||
/// } | ||
/// ``` | ||
pub REDUNDANT_SLICING, | ||
complexity, | ||
"redundant slicing of the whole range of a type" | ||
} | ||
|
||
declare_lint_pass!(RedundantSlicing => [REDUNDANT_SLICING]); | ||
|
||
impl LateLintPass<'_> for RedundantSlicing { | ||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { | ||
if in_external_macro(cx.sess(), expr.span) { | ||
return; | ||
} | ||
|
||
if_chain! { | ||
if let ExprKind::AddrOf(_, _, addressee) = expr.kind; | ||
if let ExprKind::Index(indexed, range) = addressee.kind; | ||
if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull); | ||
if TyS::same_type(cx.typeck_results().expr_ty(expr), cx.typeck_results().expr_ty(indexed)); | ||
then { | ||
let mut app = Applicability::MachineApplicable; | ||
let hint = snippet_with_applicability(cx, indexed.span, "..", &mut app).into_owned(); | ||
|
||
span_lint_and_sugg( | ||
cx, | ||
REDUNDANT_SLICING, | ||
expr.span, | ||
"redundant slicing of the whole range", | ||
"use the original slice instead", | ||
hint, | ||
app, | ||
); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#![allow(unused)] | ||
#![warn(clippy::redundant_slicing)] | ||
|
||
fn main() { | ||
let x: &[u32] = &[0]; | ||
let err = &x[..]; | ||
|
||
let v = vec![0]; | ||
let ok = &v[..]; | ||
let err = &(&v[..])[..]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
error: redundant slicing of the whole range | ||
--> $DIR/redundant_slicing.rs:6:15 | ||
| | ||
LL | let err = &x[..]; | ||
| ^^^^^^ help: use the original slice instead: `x` | ||
| | ||
= note: `-D clippy::redundant-slicing` implied by `-D warnings` | ||
|
||
error: redundant slicing of the whole range | ||
--> $DIR/redundant_slicing.rs:10:15 | ||
| | ||
LL | let err = &(&v[..])[..]; | ||
| ^^^^^^^^^^^^^ help: use the original slice instead: `(&v[..])` | ||
|
||
error: aborting due to 2 previous errors | ||
|