-
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 #8882 - kyoto7250:get_first, r=llogiq
feat(lint): impl lint about use first() instead of get(0) close #8851 This PR adds new lint about considering replacing .get(0) with .first(). Thank you in advance. changelog: adds new lint [`get_first`] to consider replacing .get(0) with .first()
- Loading branch information
Showing
20 changed files
with
234 additions
and
46 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use clippy_utils::diagnostics::span_lint_and_sugg; | ||
use clippy_utils::source::snippet_with_applicability; | ||
use clippy_utils::{is_slice_of_primitives, match_def_path, paths}; | ||
use if_chain::if_chain; | ||
use rustc_ast::LitKind; | ||
use rustc_errors::Applicability; | ||
use rustc_hir as hir; | ||
use rustc_lint::{LateContext, LateLintPass}; | ||
use rustc_session::{declare_lint_pass, declare_tool_lint}; | ||
use rustc_span::source_map::Spanned; | ||
|
||
declare_clippy_lint! { | ||
/// ### What it does | ||
/// Checks for using `x.get(0)` instead of | ||
/// `x.first()`. | ||
/// | ||
/// ### Why is this bad? | ||
/// Using `x.first()` is easier to read and has the same | ||
/// result. | ||
/// | ||
/// ### Example | ||
/// ```rust | ||
/// // Bad | ||
/// let x = vec![2, 3, 5]; | ||
/// let first_element = x.get(0); | ||
/// ``` | ||
/// Use instead: | ||
/// ```rust | ||
/// // Good | ||
/// let x = vec![2, 3, 5]; | ||
/// let first_element = x.first(); | ||
/// ``` | ||
#[clippy::version = "1.63.0"] | ||
pub GET_FIRST, | ||
style, | ||
"Using `x.get(0)` when `x.first()` is simpler" | ||
} | ||
declare_lint_pass!(GetFirst => [GET_FIRST]); | ||
|
||
impl<'tcx> LateLintPass<'tcx> for GetFirst { | ||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { | ||
if_chain! { | ||
if let hir::ExprKind::MethodCall(_, [struct_calling_on, method_arg], _) = &expr.kind; | ||
if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); | ||
if match_def_path(cx, expr_def_id, &paths::SLICE_GET); | ||
|
||
if let Some(_) = is_slice_of_primitives(cx, struct_calling_on); | ||
if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = method_arg.kind; | ||
|
||
then { | ||
let mut applicability = Applicability::MachineApplicable; | ||
let slice_name = snippet_with_applicability( | ||
cx, | ||
struct_calling_on.span, "..", | ||
&mut applicability, | ||
); | ||
span_lint_and_sugg( | ||
cx, | ||
GET_FIRST, | ||
expr.span, | ||
&format!("accessing first element with `{0}.get(0)`", slice_name), | ||
"try", | ||
format!("{}.first()", slice_name), | ||
applicability, | ||
); | ||
} | ||
} | ||
} | ||
} |
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
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
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,42 @@ | ||
// run-rustfix | ||
#![warn(clippy::get_first)] | ||
use std::collections::BTreeMap; | ||
use std::collections::HashMap; | ||
use std::collections::VecDeque; | ||
|
||
struct Bar { | ||
arr: [u32; 3], | ||
} | ||
|
||
impl Bar { | ||
fn get(&self, pos: usize) -> Option<&u32> { | ||
self.arr.get(pos) | ||
} | ||
} | ||
|
||
fn main() { | ||
let x = vec![2, 3, 5]; | ||
let _ = x.first(); // Use x.first() | ||
let _ = x.get(1); | ||
let _ = x[0]; | ||
|
||
let y = [2, 3, 5]; | ||
let _ = y.first(); // Use y.first() | ||
let _ = y.get(1); | ||
let _ = y[0]; | ||
|
||
let z = &[2, 3, 5]; | ||
let _ = z.first(); // Use z.first() | ||
let _ = z.get(1); | ||
let _ = z[0]; | ||
|
||
let vecdeque: VecDeque<_> = x.iter().cloned().collect(); | ||
let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); | ||
let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); | ||
let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. | ||
let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. | ||
let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. | ||
|
||
let bar = Bar { arr: [0, 1, 2] }; | ||
let _ = bar.get(0); // Do not lint, because Bar is struct. | ||
} |
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,42 @@ | ||
// run-rustfix | ||
#![warn(clippy::get_first)] | ||
use std::collections::BTreeMap; | ||
use std::collections::HashMap; | ||
use std::collections::VecDeque; | ||
|
||
struct Bar { | ||
arr: [u32; 3], | ||
} | ||
|
||
impl Bar { | ||
fn get(&self, pos: usize) -> Option<&u32> { | ||
self.arr.get(pos) | ||
} | ||
} | ||
|
||
fn main() { | ||
let x = vec![2, 3, 5]; | ||
let _ = x.get(0); // Use x.first() | ||
let _ = x.get(1); | ||
let _ = x[0]; | ||
|
||
let y = [2, 3, 5]; | ||
let _ = y.get(0); // Use y.first() | ||
let _ = y.get(1); | ||
let _ = y[0]; | ||
|
||
let z = &[2, 3, 5]; | ||
let _ = z.get(0); // Use z.first() | ||
let _ = z.get(1); | ||
let _ = z[0]; | ||
|
||
let vecdeque: VecDeque<_> = x.iter().cloned().collect(); | ||
let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]); | ||
let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]); | ||
let _ = vecdeque.get(0); // Do not lint, because VecDeque is not slice. | ||
let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice. | ||
let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice. | ||
|
||
let bar = Bar { arr: [0, 1, 2] }; | ||
let _ = bar.get(0); // Do not lint, because Bar is struct. | ||
} |
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,22 @@ | ||
error: accessing first element with `x.get(0)` | ||
--> $DIR/get_first.rs:19:13 | ||
| | ||
LL | let _ = x.get(0); // Use x.first() | ||
| ^^^^^^^^ help: try: `x.first()` | ||
| | ||
= note: `-D clippy::get-first` implied by `-D warnings` | ||
|
||
error: accessing first element with `y.get(0)` | ||
--> $DIR/get_first.rs:24:13 | ||
| | ||
LL | let _ = y.get(0); // Use y.first() | ||
| ^^^^^^^^ help: try: `y.first()` | ||
|
||
error: accessing first element with `z.get(0)` | ||
--> $DIR/get_first.rs:29:13 | ||
| | ||
LL | let _ = z.get(0); // Use z.first() | ||
| ^^^^^^^^ help: try: `z.first()` | ||
|
||
error: aborting due to 3 previous errors | ||
|
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
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
Oops, something went wrong.