Skip to content

Commit 2108387

Browse files
committed
Destructure args in methods module
1 parent 775ef47 commit 2108387

37 files changed

+412
-375
lines changed

clippy_lints/src/methods/bind_instead_of_map.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub(crate) trait BindInsteadOfMap {
8080
fn lint_closure_autofixable(
8181
cx: &LateContext<'_>,
8282
expr: &hir::Expr<'_>,
83-
args: &[hir::Expr<'_>],
83+
recv: &hir::Expr<'_>,
8484
closure_expr: &hir::Expr<'_>,
8585
closure_args_span: Span,
8686
) -> bool {
@@ -103,7 +103,7 @@ pub(crate) trait BindInsteadOfMap {
103103
};
104104

105105
let closure_args_snip = snippet(cx, closure_args_span, "..");
106-
let option_snip = snippet(cx, args[0].span, "..");
106+
let option_snip = snippet(cx, recv.span, "..");
107107
let note = format!("{}.{}({} {})", option_snip, Self::GOOD_METHOD_NAME, closure_args_snip, some_inner_snip);
108108
span_lint_and_sugg(
109109
cx,
@@ -158,17 +158,17 @@ pub(crate) trait BindInsteadOfMap {
158158
}
159159

160160
/// Lint use of `_.and_then(|x| Some(y))` for `Option`s
161-
fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) -> bool {
162-
if !match_type(cx, cx.typeck_results().expr_ty(&args[0]), Self::TYPE_QPATH) {
161+
fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
162+
if !match_type(cx, cx.typeck_results().expr_ty(recv), Self::TYPE_QPATH) {
163163
return false;
164164
}
165165

166-
match args[1].kind {
166+
match arg.kind {
167167
hir::ExprKind::Closure(_, _, body_id, closure_args_span, _) => {
168168
let closure_body = cx.tcx.hir().body(body_id);
169169
let closure_expr = remove_blocks(&closure_body.value);
170170

171-
if Self::lint_closure_autofixable(cx, expr, args, closure_expr, closure_args_span) {
171+
if Self::lint_closure_autofixable(cx, expr, recv, closure_expr, closure_args_span) {
172172
true
173173
} else {
174174
Self::lint_closure(cx, expr, closure_expr)
@@ -182,7 +182,7 @@ pub(crate) trait BindInsteadOfMap {
182182
expr.span,
183183
Self::no_op_msg().as_ref(),
184184
"use the expression directly",
185-
snippet(cx, args[0].span, "..").into(),
185+
snippet(cx, recv.span, "..").into(),
186186
Applicability::MachineApplicable,
187187
);
188188
true

clippy_lints/src/methods/bytes_nth.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::ty::is_type_diagnostic_item;
44
use if_chain::if_chain;
55
use rustc_errors::Applicability;
6-
use rustc_hir::{Expr, ExprKind};
6+
use rustc_hir::Expr;
77
use rustc_lint::LateContext;
88
use rustc_span::sym;
99

1010
use super::BYTES_NTH;
1111

12-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>]) {
12+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, n_arg: &'tcx Expr<'tcx>) {
1313
if_chain! {
14-
if let ExprKind::MethodCall(_, _, ref args, _) = expr.kind;
15-
let ty = cx.typeck_results().expr_ty(&iter_args[0]).peel_refs();
14+
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
1615
let caller_type = if is_type_diagnostic_item(cx, ty, sym::string_type) {
1716
Some("String")
1817
} else if ty.is_str() {
@@ -31,8 +30,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'
3130
"try",
3231
format!(
3332
"{}.as_bytes().get({})",
34-
snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability),
35-
snippet_with_applicability(cx, args[1].span, "..", &mut applicability)
33+
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
34+
snippet_with_applicability(cx, n_arg.span, "..", &mut applicability)
3635
),
3736
applicability,
3837
);

clippy_lints/src/methods/expect_used.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use rustc_span::sym;
77
use super::EXPECT_USED;
88

99
/// lint use of `expect()` for `Option`s and `Result`s
10-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
11-
let obj_ty = cx.typeck_results().expr_ty(&expect_args[0]).peel_refs();
10+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
11+
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
1212

1313
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) {
1414
Some((EXPECT_USED, "an Option", "None"))

clippy_lints/src/methods/filetype_is_file.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use rustc_span::source_map::Span;
88

99
use super::FILETYPE_IS_FILE;
1010

11-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
12-
let ty = cx.typeck_results().expr_ty(&args[0]);
11+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
12+
let ty = cx.typeck_results().expr_ty(recv);
1313

1414
if !match_type(cx, ty, &paths::FILE_TYPE) {
1515
return;

clippy_lints/src/methods/filter_map.rs

+29-21
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,17 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
4646
}
4747
}
4848

49-
fn is_option_filter_map<'tcx>(
50-
cx: &LateContext<'tcx>,
51-
filter_arg: &'tcx hir::Expr<'_>,
52-
map_arg: &'tcx hir::Expr<'_>,
53-
) -> bool {
49+
fn is_option_filter_map<'tcx>(cx: &LateContext<'tcx>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
5450
is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
5551
}
5652

5753
/// lint use of `filter().map()` for `Iterators`
58-
fn lint_filter_some_map_unwrap<'tcx>(
59-
cx: &LateContext<'tcx>,
60-
expr: &'tcx hir::Expr<'_>,
61-
filter_recv: &'tcx hir::Expr<'_>,
62-
filter_arg: &'tcx hir::Expr<'_>,
63-
map_arg: &'tcx hir::Expr<'_>,
54+
fn lint_filter_some_map_unwrap(
55+
cx: &LateContext<'_>,
56+
expr: &hir::Expr<'_>,
57+
filter_recv: &hir::Expr<'_>,
58+
filter_arg: &hir::Expr<'_>,
59+
map_arg: &hir::Expr<'_>,
6460
target_span: Span,
6561
methods_span: Span,
6662
) {
@@ -86,14 +82,28 @@ fn lint_filter_some_map_unwrap<'tcx>(
8682
}
8783

8884
/// lint use of `filter().map()` or `find().map()` for `Iterators`
89-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_find: bool, target_span: Span) {
85+
#[allow(clippy::too_many_arguments)]
86+
pub(super) fn check<'tcx>(
87+
cx: &LateContext<'tcx>,
88+
expr: &hir::Expr<'_>,
89+
filter_recv: &hir::Expr<'_>,
90+
filter_arg: &hir::Expr<'_>,
91+
filter_span: Span,
92+
map_recv: &hir::Expr<'_>,
93+
map_arg: &hir::Expr<'_>,
94+
map_span: Span,
95+
is_find: bool,
96+
) {
97+
lint_filter_some_map_unwrap(
98+
cx,
99+
expr,
100+
filter_recv,
101+
filter_arg,
102+
map_arg,
103+
map_span,
104+
filter_span.with_hi(expr.span.hi()),
105+
);
90106
if_chain! {
91-
if let ExprKind::MethodCall(_, _, [map_recv, map_arg], map_span) = expr.kind;
92-
if let ExprKind::MethodCall(_, _, [filter_recv, filter_arg], filter_span) = map_recv.kind;
93-
then {
94-
lint_filter_some_map_unwrap(cx, expr, filter_recv, filter_arg,
95-
map_arg, target_span, filter_span.to(map_span));
96-
if_chain! {
97107
if is_trait_method(cx, map_recv, sym::Iterator);
98108

99109
// filter(|x| ...is_some())...
@@ -148,7 +158,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_
148158
};
149159
if SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(filter_arg, map_arg);
150160
then {
151-
let span = filter_span.to(map_span);
161+
let span = filter_span.with_hi(expr.span.hi());
152162
let (filter_name, lint) = if is_find {
153163
("find", MANUAL_FIND_MAP)
154164
} else {
@@ -160,7 +170,5 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, is_
160170
snippet(cx, map_arg.span, ".."), to_opt);
161171
span_lint_and_sugg(cx, lint, span, &msg, "try", sugg, Applicability::MachineApplicable);
162172
}
163-
}
164-
}
165173
}
166174
}

clippy_lints/src/methods/filter_map_identity.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,8 @@ use rustc_span::{source_map::Span, sym};
88

99
use super::FILTER_MAP_IDENTITY;
1010

11-
pub(super) fn check(
12-
cx: &LateContext<'_>,
13-
expr: &hir::Expr<'_>,
14-
filter_map_args: &[hir::Expr<'_>],
15-
filter_map_span: Span,
16-
) {
11+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {
1712
if is_trait_method(cx, expr, sym::Iterator) {
18-
let arg_node = &filter_map_args[1].kind;
19-
2013
let apply_lint = |message: &str| {
2114
span_lint_and_sugg(
2215
cx,
@@ -30,8 +23,8 @@ pub(super) fn check(
3023
};
3124

3225
if_chain! {
33-
if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
34-
let body = cx.tcx.hir().body(*body_id);
26+
if let hir::ExprKind::Closure(_, _, body_id, _, _) = filter_map_arg.kind;
27+
let body = cx.tcx.hir().body(body_id);
3528

3629
if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
3730
if path_to_local_id(&body.value, binding_id);
@@ -41,7 +34,7 @@ pub(super) fn check(
4134
}
4235

4336
if_chain! {
44-
if let hir::ExprKind::Path(ref qpath) = arg_node;
37+
if let hir::ExprKind::Path(ref qpath) = filter_map_arg.kind;
4538

4639
if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
4740

clippy_lints/src/methods/filter_map_next.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0);
1414
pub(super) fn check<'tcx>(
1515
cx: &LateContext<'tcx>,
1616
expr: &'tcx hir::Expr<'_>,
17-
filter_args: &'tcx [hir::Expr<'_>],
17+
recv: &'tcx hir::Expr<'_>,
18+
arg: &'tcx hir::Expr<'_>,
1819
msrv: Option<&RustcVersion>,
1920
) {
2021
if is_trait_method(cx, expr, sym::Iterator) {
@@ -24,9 +25,9 @@ pub(super) fn check<'tcx>(
2425

2526
let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
2627
`.find_map(..)` instead";
27-
let filter_snippet = snippet(cx, filter_args[1].span, "..");
28+
let filter_snippet = snippet(cx, arg.span, "..");
2829
if filter_snippet.lines().count() <= 1 {
29-
let iter_snippet = snippet(cx, filter_args[0].span, "..");
30+
let iter_snippet = snippet(cx, recv.span, "..");
3031
span_lint_and_sugg(
3132
cx,
3233
FILTER_MAP_NEXT,

clippy_lints/src/methods/filter_next.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ use rustc_span::sym;
99
use super::FILTER_NEXT;
1010

1111
/// lint use of `filter().next()` for `Iterators`
12-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) {
12+
pub(super) fn check<'tcx>(
13+
cx: &LateContext<'tcx>,
14+
expr: &'tcx hir::Expr<'_>,
15+
recv: &'tcx hir::Expr<'_>,
16+
filter_arg: &'tcx hir::Expr<'_>,
17+
) {
1318
// lint if caller of `.filter().next()` is an Iterator
1419
if is_trait_method(cx, expr, sym::Iterator) {
1520
let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
1621
`.find(..)` instead";
17-
let filter_snippet = snippet(cx, filter_args[1].span, "..");
22+
let filter_snippet = snippet(cx, filter_arg.span, "..");
1823
if filter_snippet.lines().count() <= 1 {
19-
let iter_snippet = snippet(cx, filter_args[0].span, "..");
24+
let iter_snippet = snippet(cx, recv.span, "..");
2025
// add note if not multi-line
2126
span_lint_and_sugg(
2227
cx,

clippy_lints/src/methods/flat_map_identity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use super::FLAT_MAP_IDENTITY;
1212
pub(super) fn check<'tcx>(
1313
cx: &LateContext<'tcx>,
1414
expr: &'tcx hir::Expr<'_>,
15-
flat_map_args: &'tcx [hir::Expr<'_>],
15+
flat_map_arg: &'tcx hir::Expr<'_>,
1616
flat_map_span: Span,
1717
) {
1818
if is_trait_method(cx, expr, sym::Iterator) {
19-
let arg_node = &flat_map_args[1].kind;
19+
let arg_node = &flat_map_arg.kind;
2020

2121
let apply_lint = |message: &str| {
2222
span_lint_and_sugg(

clippy_lints/src/methods/get_unwrap.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ use rustc_span::sym;
1111

1212
use super::GET_UNWRAP;
1313

14-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args: &'tcx [hir::Expr<'_>], is_mut: bool) {
14+
pub(super) fn check<'tcx>(
15+
cx: &LateContext<'tcx>,
16+
expr: &hir::Expr<'_>,
17+
recv: &'tcx hir::Expr<'tcx>,
18+
get_arg: &'tcx hir::Expr<'_>,
19+
is_mut: bool,
20+
) {
1521
// Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`,
1622
// because they do not implement `IndexMut`
1723
let mut applicability = Applicability::MachineApplicable;
18-
let expr_ty = cx.typeck_results().expr_ty(&get_args[0]);
19-
let get_args_str = if get_args.len() > 1 {
20-
snippet_with_applicability(cx, get_args[1].span, "..", &mut applicability)
21-
} else {
22-
return; // not linting on a .get().unwrap() chain or variant
23-
};
24+
let expr_ty = cx.typeck_results().expr_ty(recv);
25+
let get_args_str = snippet_with_applicability(cx, get_arg.span, "..", &mut applicability);
2426
let mut needs_ref;
25-
let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
27+
let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() {
2628
needs_ref = get_args_str.parse::<usize>().is_ok();
2729
"slice"
2830
} else if is_type_diagnostic_item(cx, expr_ty, sym::vec_type) {
@@ -77,7 +79,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args
7779
format!(
7880
"{}{}[{}]",
7981
borrow_str,
80-
snippet_with_applicability(cx, get_args[0].span, "..", &mut applicability),
82+
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
8183
get_args_str
8284
),
8385
applicability,

clippy_lints/src/methods/iter_cloned_collect.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use rustc_span::sym;
99

1010
use super::ITER_CLONED_COLLECT;
1111

12-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
12+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, recv: &'tcx hir::Expr<'_>) {
1313
if_chain! {
1414
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym::vec_type);
15-
if let Some(slice) = derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0]));
15+
if let Some(slice) = derefs_to_slice(cx, recv, cx.typeck_results().expr_ty(recv));
1616
if let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite());
1717

1818
then {

clippy_lints/src/methods/iter_count.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use rustc_span::sym;
1010

1111
use super::ITER_COUNT;
1212

13-
pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], iter_method: &str) {
14-
let ty = cx.typeck_results().expr_ty(&iter_args[0]);
15-
let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() {
13+
pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: &str) {
14+
let ty = cx.typeck_results().expr_ty(recv);
15+
let caller_type = if derefs_to_slice(cx, recv, ty).is_some() {
1616
"slice"
1717
} else if is_type_diagnostic_item(cx, ty, sym::vec_type) {
1818
"Vec"
@@ -42,7 +42,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'
4242
"try",
4343
format!(
4444
"{}.len()",
45-
snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability),
45+
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
4646
),
4747
applicability,
4848
);

clippy_lints/src/methods/iter_next_slice.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use rustc_span::symbol::sym;
1313

1414
use super::ITER_NEXT_SLICE;
1515

16-
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
17-
let caller_expr = &iter_args[0];
18-
16+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, caller_expr: &'tcx hir::Expr<'_>) {
1917
// Skip lint if the `iter().next()` expression is a for loop argument,
2018
// since it is already covered by `&loops::ITER_NEXT_LOOP`
2119
let mut parent_expr_opt = get_parent_expr(cx, expr);

clippy_lints/src/methods/iter_nth.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ use super::ITER_NTH;
1111
pub(super) fn check<'tcx>(
1212
cx: &LateContext<'tcx>,
1313
expr: &hir::Expr<'_>,
14-
nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]],
14+
iter_recv: &'tcx hir::Expr<'tcx>,
15+
nth_recv: &hir::Expr<'_>,
16+
nth_arg: &hir::Expr<'_>,
1517
is_mut: bool,
1618
) {
17-
let iter_args = nth_and_iter_args[1];
1819
let mut_str = if is_mut { "_mut" } else { "" };
19-
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() {
20+
let caller_type = if derefs_to_slice(cx, iter_recv, cx.typeck_results().expr_ty(iter_recv)).is_some() {
2021
"slice"
21-
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) {
22+
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::vec_type) {
2223
"Vec"
23-
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) {
24+
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::vecdeque_type) {
2425
"VecDeque"
2526
} else {
26-
let nth_args = nth_and_iter_args[0];
27-
iter_nth_zero::check(cx, expr, &nth_args);
27+
iter_nth_zero::check(cx, expr, nth_recv, nth_arg);
2828
return; // caller is not a type that we want to lint
2929
};
3030

0 commit comments

Comments
 (0)