Skip to content

Commit aa66f76

Browse files
Destructure mem:replace arguments
1 parent 78b4dfc commit aa66f76

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

clippy_lints/src/mem_replace.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use crate::utils::{
33
};
44
use if_chain::if_chain;
55
use rustc::declare_lint_pass;
6-
use rustc::hir::{BorrowKind, Expr, ExprKind, HirVec, Mutability, QPath};
6+
use rustc::hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
77
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintPass};
88
use rustc_errors::Applicability;
99
use rustc_session::declare_tool_lint;
10+
use syntax::source_map::Span;
1011

1112
declare_clippy_lint! {
1213
/// **What it does:** Checks for `mem::replace()` on an `Option` with
@@ -94,16 +95,16 @@ declare_clippy_lint! {
9495
declare_lint_pass!(MemReplace =>
9596
[MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
9697

97-
fn check_replace_option_with_none(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &HirVec<Expr>) {
98-
if let ExprKind::Path(ref replacement_qpath) = args[1].kind {
98+
fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr, dest: &Expr, expr_span: Span) {
99+
if let ExprKind::Path(ref replacement_qpath) = src.kind {
99100
// Check that second argument is `Option::None`
100101
if match_qpath(replacement_qpath, &paths::OPTION_NONE) {
101102
// Since this is a late pass (already type-checked),
102103
// and we already know that the second argument is an
103104
// `Option`, we do not need to check the first
104105
// argument's type. All that's left is to get
105106
// replacee's path.
106-
let replaced_path = match args[0].kind {
107+
let replaced_path = match dest.kind {
107108
ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref replaced) => {
108109
if let ExprKind::Path(QPath::Resolved(None, ref replaced_path)) = replaced.kind {
109110
replaced_path
@@ -119,7 +120,7 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, expr: &'_ Expr, args
119120
span_lint_and_sugg(
120121
cx,
121122
MEM_REPLACE_OPTION_WITH_NONE,
122-
expr.span,
123+
expr_span,
123124
"replacing an `Option` with `None`",
124125
"consider `Option::take()` instead",
125126
format!(
@@ -132,8 +133,8 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, expr: &'_ Expr, args
132133
}
133134
}
134135

135-
fn check_replace_with_uninit(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &HirVec<Expr>) {
136-
if let ExprKind::Call(ref repl_func, ref repl_args) = args[1].kind {
136+
fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr, expr_span: Span) {
137+
if let ExprKind::Call(ref repl_func, ref repl_args) = src.kind {
137138
if_chain! {
138139
if repl_args.is_empty();
139140
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
@@ -143,16 +144,16 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &Hi
143144
span_help_and_lint(
144145
cx,
145146
MEM_REPLACE_WITH_UNINIT,
146-
expr.span,
147+
expr_span,
147148
"replacing with `mem::uninitialized()`",
148149
"consider using the `take_mut` crate instead",
149150
);
150151
} else if match_def_path(cx, repl_def_id, &paths::MEM_ZEROED) &&
151-
!cx.tables.expr_ty(&args[1]).is_primitive() {
152+
!cx.tables.expr_ty(src).is_primitive() {
152153
span_help_and_lint(
153154
cx,
154155
MEM_REPLACE_WITH_UNINIT,
155-
expr.span,
156+
expr_span,
156157
"replacing with `mem::zeroed()`",
157158
"consider using a default value or the `take_mut` crate instead",
158159
);
@@ -162,10 +163,10 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &Hi
162163
}
163164
}
164165

165-
fn check_replace_with_default(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &HirVec<Expr>) {
166-
if let ExprKind::Call(ref repl_func, _) = args[1].kind {
166+
fn check_replace_with_default(cx: &LateContext<'_, '_>, src: &Expr, dest: &Expr, expr_span: Span) {
167+
if let ExprKind::Call(ref repl_func, _) = src.kind {
167168
if_chain! {
168-
if !in_macro(expr.span) && !in_external_macro(cx.tcx.sess, expr.span);
169+
if !in_macro(expr_span) && !in_external_macro(cx.tcx.sess, expr_span);
169170
if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
170171
if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
171172
if match_def_path(cx, repl_def_id, &paths::DEFAULT_TRAIT_METHOD);
@@ -175,12 +176,12 @@ fn check_replace_with_default(cx: &LateContext<'_, '_>, expr: &'_ Expr, args: &H
175176
span_lint_and_sugg(
176177
cx,
177178
MEM_REPLACE_WITH_DEFAULT,
178-
expr.span,
179+
expr_span,
179180
"replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`",
180181
"consider using",
181182
format!(
182183
"std::mem::take({})",
183-
snippet_with_applicability(cx, args[0].span, "", &mut applicability)
184+
snippet_with_applicability(cx, dest.span, "", &mut applicability)
184185
),
185186
applicability,
186187
);
@@ -194,15 +195,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
194195
if_chain! {
195196
// Check that `expr` is a call to `mem::replace()`
196197
if let ExprKind::Call(ref func, ref func_args) = expr.kind;
197-
if func_args.len() == 2;
198198
if let ExprKind::Path(ref func_qpath) = func.kind;
199199
if let Some(def_id) = cx.tables.qpath_res(func_qpath, func.hir_id).opt_def_id();
200200
if match_def_path(cx, def_id, &paths::MEM_REPLACE);
201-
201+
if let [dest, src] = &**func_args;
202202
then {
203-
check_replace_option_with_none(cx, expr, &func_args);
204-
check_replace_with_uninit(cx, expr, &func_args);
205-
check_replace_with_default(cx, expr, &func_args);
203+
check_replace_option_with_none(cx, src, dest, expr.span);
204+
check_replace_with_uninit(cx, src, expr.span);
205+
check_replace_with_default(cx, src, dest, expr.span);
206206
}
207207
}
208208
}

0 commit comments

Comments
 (0)