Skip to content

Commit ac60941

Browse files
committed
Register use_last, fix bugs, and add (commented) printlns
1 parent 864dfbd commit ac60941

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

clippy_lints/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#![feature(stmt_expr_attributes)]
77
#![feature(range_contains)]
88
#![allow(clippy::missing_docs_in_private_items)]
9-
#![recursion_limit = "256"]
9+
// #![recursion_limit = "256"]
10+
#![recursion_limit = "512"]
1011
#![warn(rust_2018_idioms, trivial_casts, trivial_numeric_casts)]
1112
#![feature(crate_visibility_modifier)]
1213

@@ -551,6 +552,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
551552
reg.register_late_lint_pass(box types::RefToMut);
552553
reg.register_late_lint_pass(box assertions_on_constants::AssertionsOnConstants);
553554
reg.register_late_lint_pass(box missing_const_for_fn::MissingConstForFn);
555+
reg.register_late_lint_pass(box use_last::UseLast);
554556

555557
reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
556558
arithmetic::FLOAT_ARITHMETIC,

clippy_lints/src/use_last.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,38 +51,62 @@ impl LintPass for UseLast {
5151
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseLast {
5252
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
5353
if_chain! {
54+
// let _ = println!("Starting UseLast");
5455
// Is a method call
5556
if let ExprKind::MethodCall(ref path, _, ref args) = expr.node;
57+
// let _ = println!("It is a MethodCall");
5658

5759
// Method name is "get"
5860
if path.ident.name == "get";
61+
// let _ = println!("The name is get");
5962

6063
// Argument 0 (the struct we're calling the method on) is a vector
6164
if let Some(struct_calling_on) = args.get(0);
65+
// let _ = println!("It had an argument");
6266
let struct_ty = cx.tables.expr_ty(struct_calling_on);
6367
if match_type(cx, struct_ty, &paths::VEC);
68+
// let _ = println!("It was a vector");
6469

6570
// Argument to "get" is a binary operation
6671
if let Some(get_index_arg) = args.get(1);
72+
// let _ = println!("It had an argument");
6773
if let rustc::hir::ExprKind::Binary(ref op, ref lhs, ref rhs) = get_index_arg.node;
74+
// let _ = println!("It was a vector");
6875

6976
// Binary operation is a subtraction
7077
if op.node == rustc::hir::BinOpKind::Sub;
78+
// let _ = println!("It was a subtraction");
7179

7280
// LHS of subtraction is "x.len()"
7381
if let ExprKind::MethodCall(ref arg_lhs_path, _, ref lhs_args) = lhs.node;
82+
// let _ = println!("LHS of sub is a method call");
7483
if arg_lhs_path.ident.name == "len";
75-
if let Some(arg_lhs_struct) = lhs_args.get(0);
84+
// let _ = println!("LHS of sub was method named len");
85+
// if let Some(arg_lhs_struct) = lhs_args.get(0);
86+
// let _ = println!("LHS of sub method has an arg");
7687
// TODO: Is this a valid way to check if they reference the same vector?
77-
if arg_lhs_struct.hir_id == struct_calling_on.hir_id;
88+
// if arg_lhs_struct.hir_id == struct_calling_on.hir_id;
89+
// let _ = println!("The vector in .get and .len were the same");
7890

7991
// RHS of subtraction is 1
8092
if let ExprKind::Lit(ref rhs_lit) = rhs.node;
93+
// let _ = println!("RHS of sub was literal");
8194
if let LitKind::Int(rhs_value, ..) = rhs_lit.node;
95+
// let _ = println!("RHS of sub was int");
8296
if rhs_value == 1;
97+
// let _ = println!("RHS of sub was 1");
8398

8499
// TODO: Figure out how to get name of variable for lint message
100+
// Can't do this (cannot move out of borrowed content (context?))
101+
// if let ExprKind::Struct(ref struct_calling_on_path, _, _) = struct_calling_on.node;
102+
// let _ = println!("It was a struct");
103+
// let vec_name = match struct_calling_on_path.into_inner() {
104+
// rustc::hir::QPath::Resolved(_, path) =>
105+
// path.segments.last().map(|path_seg| path_seg.ident.name.as_str().get()).unwrap_or("x"),
106+
// rustc::hir::QPath::TypeRelative(_, path_seg) => path_seg.ident.name.as_str().get(),
107+
// };
85108
let vec_name = "x";
109+
// let _ = println!("About to span_lint on \"{}\"", vec_name);
86110

87111
then {
88112
span_lint(cx,

tests/ui/use_last.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn index_into_last() -> i32 {
1414

1515
fn main() {
1616
let expected_value: i32 = 5;
17+
println!("Working...");
1718
assert_eq!(dont_use_last(), Some(expected_value));
1819
assert_eq!(index_into_last(), expected_value);
1920
}

tests/ui/use_last.stderr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
error: there should be some output to this lint but there wasn't
1+
error: Use `x.last()` instead of `x.get(x.len() - 1)`
2+
--> $DIR/use_last.rs:5:24
3+
|
4+
LL | let last_element = x.get(x.len() - 1); // ~ERROR Use _.last()
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::use-last` implied by `-D warnings`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)