1 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
2 use clippy_utils
::source
::snippet_with_applicability
;
3 use clippy_utils
::SpanlessEq
;
4 use rustc_ast
::LitKind
;
5 use rustc_errors
::Applicability
;
6 use rustc_hir
::{BinOpKind, Expr, ExprKind}
;
7 use rustc_lint
::LateContext
;
9 use rustc_span
::source_map
::Spanned
;
12 use super::GET_LAST_WITH_LEN
;
14 pub(super) fn check(cx
: &LateContext
<'_
>, expr
: &Expr
<'_
>, recv
: &Expr
<'_
>, arg
: &Expr
<'_
>) {
15 // Argument to "get" is a subtraction
16 if let ExprKind
::Binary(
18 node
: BinOpKind
::Sub
, ..
24 // LHS of subtraction is "x.len()"
25 && let ExprKind
::MethodCall(lhs_path
, lhs_recv
, [], _
) = &lhs
.kind
26 && lhs_path
.ident
.name
== sym
::len
28 // RHS of subtraction is 1
29 && let ExprKind
::Lit(rhs_lit
) = &rhs
.kind
30 && let LitKind
::Int(1, ..) = rhs_lit
.node
32 // check that recv == lhs_recv `recv.get(lhs_recv.len() - 1)`
33 && SpanlessEq
::new(cx
).eq_expr(recv
, lhs_recv
)
34 && !recv
.can_have_side_effects()
36 let method
= match cx
.typeck_results().expr_ty_adjusted(recv
).peel_refs().kind() {
37 ty
::Adt(def
, _
) if cx
.tcx
.is_diagnostic_item(sym
::VecDeque
, def
.did()) => "back",
38 ty
::Slice(_
) => "last",
42 let mut applicability
= Applicability
::MachineApplicable
;
43 let recv_snippet
= snippet_with_applicability(cx
, recv
.span
, "_", &mut applicability
);
49 &format
!("accessing last element with `{recv_snippet}.get({recv_snippet}.len() - 1)`"),
51 format
!("{recv_snippet}.{method}()"),