Skip to content

Commit 422ba88

Browse files
committed
Start writing use_last test
Getting unresolved import error for if_chain.
1 parent 5725726 commit 422ba88

File tree

5 files changed

+95
-1
lines changed

5 files changed

+95
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ All notable changes to this project will be documented in this file.
10161016
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
10171017
[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
10181018
[`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug
1019+
[`use_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_last
10191020
[`use_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_self
10201021
[`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding
10211022
[`useless_asref`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
99

10-
[There are 296 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
10+
[There are 297 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1111

1212
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1313

clippy_lints/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ pub mod unsafe_removed_from_name;
198198
pub mod unused_io_amount;
199199
pub mod unused_label;
200200
pub mod unwrap;
201+
pub mod use_last;
201202
pub mod use_self;
202203
pub mod vec;
203204
pub mod wildcard_dependencies;
@@ -785,6 +786,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
785786
unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
786787
unused_io_amount::UNUSED_IO_AMOUNT,
787788
unused_label::UNUSED_LABEL,
789+
use_last::USE_LAST,
788790
vec::USELESS_VEC,
789791
write::PRINTLN_EMPTY_STRING,
790792
write::PRINT_LITERAL,
@@ -948,6 +950,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
948950
types::UNNECESSARY_CAST,
949951
types::VEC_BOX,
950952
unused_label::UNUSED_LABEL,
953+
use_last::USE_LAST,
951954
zero_div_zero::ZERO_DIVIDED_BY_ZERO,
952955
]);
953956

clippy_lints/src/use_last.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//! lint on using `x.get(x.len() - 1)` instead of `x.last()`
2+
3+
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
4+
use rustc::{declare_tool_lint, lint_array};
5+
use if_chain::if_chain;
6+
// use syntax::ast::*;
7+
use rustc::hir::*;
8+
use crate::utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
9+
use crate::utils::{opt_def_id, sugg};
10+
use if_chain::if_chain;
11+
use rustc::ty::{self, Ty};
12+
use rustc_errors::Applicability;
13+
use std::borrow::Cow;
14+
use syntax::ast;
15+
16+
/// **What it does:** Checks for using `x.get(x.len() - 1)` instead of `x.last()`.
17+
///
18+
/// **Why is this bad?** Using `x.last()` is easier to read and has the same result.
19+
///
20+
/// **Known problems:** None.
21+
///
22+
/// **Example:**
23+
///
24+
/// ```rust
25+
/// // Bad
26+
/// let x = vec![2, 3, 5];
27+
/// let last_element = x.get(x.len() - 1);
28+
///
29+
/// // Good
30+
/// let x = vec![2, 3, 5];
31+
/// let last_element = x.last();
32+
/// ```
33+
34+
declare_clippy_lint! {
35+
pub USE_LAST,
36+
complexity,
37+
"using `x.get(x.len() - 1)` instead of `x.last()`"
38+
}
39+
40+
#[derive(Copy, Clone, Debug)]
41+
pub struct UseLast;
42+
43+
impl LintPass for UseLast {
44+
fn get_lints(&self) -> LintArray {
45+
lint_array!(USE_LAST)
46+
}
47+
48+
fn name(&self) -> &'static str {
49+
"UseLast"
50+
}
51+
}
52+
53+
impl LateLintPass for UseLast {
54+
fn check_expr(&mut self, cx: &LateContext<'_>, mut item: &Expr) {
55+
if_chain! {
56+
if let StmtKind::Local(ref local) = stmt.node;
57+
if let Some(ref init) = local.init
58+
if let ExprKind::MethodCall(ref method_name, ref generics, ref args) = init.node;
59+
// unimplemented: `ExprKind::MethodCall` is not further destructured at the moment
60+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.node;
61+
if name.node.as_str() == "last_element";
62+
then {
63+
// report your lint here
64+
}
65+
}
66+
67+
}
68+
}

tests/ui/use_last.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![warn(clippy::all)]
2+
#![warn(clippy::use_last)]
3+
4+
fn dont_use_last() -> Option<i32> {
5+
let x = vec![2, 3, 5];
6+
#[clippy::author]
7+
let last_element = x.get(x.len() - 1); // ~ERROR Use _.last()
8+
last_element.map(|val| val + 1) // To avoid warnings
9+
}
10+
11+
fn index_into_last() -> i32 {
12+
let x = vec![2, 3, 5];
13+
let last_element = x[x.len() - 1];
14+
last_element + 1 // To avoid warnings
15+
}
16+
17+
fn main() {
18+
// let expected_value: &i32 = &5;
19+
let expected_value: i32 = 5;
20+
assert_eq!(dont_use_last(), Some(expected_value));
21+
assert_eq!(index_into_last(), 5);
22+
}

0 commit comments

Comments
 (0)