Skip to content

Commit 5b68642

Browse files
committed
Merged
2 parents 487feba + 284b784 commit 5b68642

File tree

4 files changed

+53
-74
lines changed

4 files changed

+53
-74
lines changed

clippy_lints/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
#![feature(slice_patterns)]
77
#![feature(stmt_expr_attributes)]
88
#![allow(clippy::missing_docs_in_private_items)]
9-
// #![recursion_limit = "256"]
10-
#![recursion_limit = "512"]
9+
#![recursion_limit = "256"]
1110
#![warn(rust_2018_idioms, trivial_casts, trivial_numeric_casts)]
1211
#![deny(internal)]
1312
#![feature(crate_visibility_modifier)]

clippy_lints/src/use_last.rs

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,46 @@
11
//! lint on using `x.get(x.len() - 1)` instead of `x.last()`
22
3-
use crate::utils::{match_type, paths, span_lint_and_sugg, snippet_with_applicability};
4-
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
5-
use rustc::{declare_tool_lint, lint_array};
3+
use crate::utils::{match_type, paths, snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
4+
use if_chain::if_chain;
65
use rustc::hir::{Expr, ExprKind};
6+
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
7+
use rustc::{declare_lint_pass, declare_tool_lint};
78
use rustc_errors::Applicability;
8-
use syntax::ast::{LitKind};
9-
use if_chain::if_chain;
10-
11-
/// **What it does:** Checks for using `x.get(x.len() - 1)` instead of `x.last()`.
12-
///
13-
/// **Why is this bad?** Using `x.last()` is easier to read and has the same result.
14-
///
15-
/// Note that using `x[x.len() - 1]` is semantically different from `x.last()`.
16-
/// Indexing into the array will panic on out-of-bounds accesses, while
17-
/// `x.get()` and `x.last()` will return `None`.
18-
///
19-
/// There is another lint (get_unwrap) that covers the case of using
20-
/// `x.get(index).unwrap()` instead of `x[index]`.
21-
///
22-
/// **Known problems:** None.
23-
///
24-
/// **Example:**
25-
///
26-
/// ```rust
27-
/// // Bad
28-
/// let x = vec![2, 3, 5];
29-
/// let last_element = x.get(x.len() - 1);
30-
///
31-
/// // Good
32-
/// let x = vec![2, 3, 5];
33-
/// let last_element = x.last();
34-
/// ```
9+
use syntax::ast::LitKind;
3510

3611
declare_clippy_lint! {
12+
/// **What it does:** Checks for using `x.get(x.len() - 1)` instead of
13+
/// `x.last()`.
14+
///
15+
/// **Why is this bad?** Using `x.last()` is easier to read and has the same
16+
/// result.
17+
///
18+
/// Note that using `x[x.len() - 1]` is semantically different from
19+
/// `x.last()`. Indexing into the array will panic on out-of-bounds
20+
/// accesses, while `x.get()` and `x.last()` will return `None`.
21+
///
22+
/// There is another lint (get_unwrap) that covers the case of using
23+
/// `x.get(index).unwrap()` instead of `x[index]`.
24+
///
25+
/// **Known problems:** None.
26+
///
27+
/// **Example:**
28+
///
29+
/// ```rust
30+
/// // Bad
31+
/// let x = vec![2, 3, 5];
32+
/// let last_element = x.get(x.len() - 1);
33+
///
34+
/// // Good
35+
/// let x = vec![2, 3, 5];
36+
/// let last_element = x.last();
37+
/// ```
3738
pub USE_LAST,
3839
complexity,
39-
"using `x.get(x.len() - 1)` instead of `x.last()`"
40+
"Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler"
4041
}
4142

42-
#[derive(Copy, Clone, Debug)]
43-
pub struct UseLast;
44-
45-
impl LintPass for UseLast {
46-
fn get_lints(&self) -> LintArray {
47-
lint_array!(USE_LAST)
48-
}
49-
50-
fn name(&self) -> &'static str {
51-
"UseLast"
52-
}
53-
}
43+
declare_lint_pass!(UseLast => [USE_LAST]);
5444

5545
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseLast {
5646
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
@@ -78,10 +68,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseLast {
7868
if arg_lhs_path.ident.name == "len";
7969
if let Some(arg_lhs_struct) = lhs_args.get(0);
8070

81-
// TODO: Is this a valid way to check if they reference the same vector?
82-
if let ExprKind::Path(arg_lhs_struct_path) = arg_lhs_struct.node;
83-
if let ExprKind::Path(struct_calling_on_path) = struct_calling_on.nod
84-
if arg_lhs_struct_path == struct_calling_on_path;
71+
if SpanlessEq::new(cx).eq_expr(struct_calling_on, arg_lhs_struct);
8572

8673
// RHS of subtraction is 1
8774
if let ExprKind::Lit(ref rhs_lit) = rhs.node;

tests/ui/use_last.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,29 @@
11
#![warn(clippy::use_last)]
22

3-
fn dont_use_last() -> Option<i32> {
3+
fn dont_use_last() {
44
let x = vec![2, 3, 5];
5-
let last_element = x.get(x.len() - 1); // ~ERROR Use x.last()
6-
last_element.map(|val| val + 1) // To avoid warnings
5+
let _ = x.get(x.len() - 1); // ~ERROR Use x.last()
76
}
87

9-
fn indexing_two_from_end() -> Option<i32> {
8+
fn indexing_two_from_end() {
109
let x = vec![2, 3, 5];
11-
let last_element = x.get(x.len() - 2);
12-
last_element.map(|val| val + 3) // To avoid warnings
10+
let _ = x.get(x.len() - 2);
1311
}
1412

15-
fn index_into_last() -> i32 {
13+
fn index_into_last() {
1614
let x = vec![2, 3, 5];
17-
let last_element = x[x.len() - 1];
18-
last_element + 1 // To avoid warnings
15+
let _ = x[x.len() - 1];
1916
}
2017

21-
// False positive test (currently failing)
22-
// fn use_last_with_different_vec_length() -> Option<i32> {
23-
// let x = vec![2, 3, 5];
24-
// let y = vec!['a', 'b', 'c'];
25-
// let last_element = x.get(y.len() - 1);
26-
// last_element.map(|val| val + 1)
27-
// }
18+
fn use_last_with_different_vec_length() {
19+
let x = vec![2, 3, 5];
20+
let y = vec!['a', 'b', 'c'];
21+
let _ = x.get(y.len() - 1);
22+
}
2823

2924
fn main() {
30-
let expected_value: i32 = 6;
31-
println!("Working...");
32-
assert_eq!(dont_use_last(), Some(expected_value));
33-
assert_eq!(indexing_two_from_end(), Some(expected_value));
34-
assert_eq!(index_into_last(), expected_value);
35-
// assert_eq!(use_last_with_different_vec_length(), Some(expected_value));
25+
dont_use_last();
26+
indexing_two_from_end();
27+
index_into_last();
28+
use_last_with_different_vec_length();
3629
}

tests/ui/use_last.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: Use `x.last()` instead of `x.get(x.len() - 1)`
2-
--> $DIR/use_last.rs:5:24
2+
--> $DIR/use_last.rs:5:13
33
|
4-
LL | let last_element = x.get(x.len() - 1); // ~ERROR Use x.last()
5-
| ^^^^^^^^^^^^^^^^^^ help: try: `x.last()`
4+
LL | let _ = x.get(x.len() - 1); // ~ERROR Use x.last()
5+
| ^^^^^^^^^^^^^^^^^^ help: try: `x.last()`
66
|
77
= note: `-D clippy::use-last` implied by `-D warnings`
88

0 commit comments

Comments
 (0)