Skip to content

Commit 029777f

Browse files
committed
Auto merge of #6896 - TaKO8Ki:refactor-lints-in-methods-module, r=phansch
Refactor lints in methods module This PR refactors methods lints other than the lints I refactored in #6826 and moves some functions to methods/utils.rs. Basically, I follow the instruction described in #6680. **For ease of review, I refactored step by step, keeping each commit small.** closes #6886 cc: `@phansch,` `@flip1995,` `@Y-Nak` changelog: Move lints in methods module to their own modules and some function to methods/utils.rs.
2 parents aca95aa + b6a2757 commit 029777f

27 files changed

+388
-333
lines changed

clippy_lints/src/methods/chars_cmp.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::{method_chain_args, single_segment_path};
4+
use if_chain::if_chain;
5+
use rustc_errors::Applicability;
6+
use rustc_hir as hir;
7+
use rustc_lint::LateContext;
8+
use rustc_lint::Lint;
9+
use rustc_middle::ty;
10+
use rustc_span::sym;
11+
12+
/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints.
13+
pub(super) fn check(
14+
cx: &LateContext<'_>,
15+
info: &crate::methods::BinaryExprInfo<'_>,
16+
chain_methods: &[&str],
17+
lint: &'static Lint,
18+
suggest: &str,
19+
) -> bool {
20+
if_chain! {
21+
if let Some(args) = method_chain_args(info.chain, chain_methods);
22+
if let hir::ExprKind::Call(ref fun, ref arg_char) = info.other.kind;
23+
if arg_char.len() == 1;
24+
if let hir::ExprKind::Path(ref qpath) = fun.kind;
25+
if let Some(segment) = single_segment_path(qpath);
26+
if segment.ident.name == sym::Some;
27+
then {
28+
let mut applicability = Applicability::MachineApplicable;
29+
let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0][0]).peel_refs();
30+
31+
if *self_ty.kind() != ty::Str {
32+
return false;
33+
}
34+
35+
span_lint_and_sugg(
36+
cx,
37+
lint,
38+
info.expr.span,
39+
&format!("you should use the `{}` method", suggest),
40+
"like this",
41+
format!("{}{}.{}({})",
42+
if info.eq { "" } else { "!" },
43+
snippet_with_applicability(cx, args[0][0].span, "..", &mut applicability),
44+
suggest,
45+
snippet_with_applicability(cx, arg_char[0].span, "..", &mut applicability)),
46+
applicability,
47+
);
48+
49+
return true;
50+
}
51+
}
52+
53+
false
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::method_chain_args;
3+
use clippy_utils::source::snippet_with_applicability;
4+
use if_chain::if_chain;
5+
use rustc_ast::ast;
6+
use rustc_errors::Applicability;
7+
use rustc_hir as hir;
8+
use rustc_lint::LateContext;
9+
use rustc_lint::Lint;
10+
11+
/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.
12+
pub(super) fn check<'tcx>(
13+
cx: &LateContext<'tcx>,
14+
info: &crate::methods::BinaryExprInfo<'_>,
15+
chain_methods: &[&str],
16+
lint: &'static Lint,
17+
suggest: &str,
18+
) -> bool {
19+
if_chain! {
20+
if let Some(args) = method_chain_args(info.chain, chain_methods);
21+
if let hir::ExprKind::Lit(ref lit) = info.other.kind;
22+
if let ast::LitKind::Char(c) = lit.node;
23+
then {
24+
let mut applicability = Applicability::MachineApplicable;
25+
span_lint_and_sugg(
26+
cx,
27+
lint,
28+
info.expr.span,
29+
&format!("you should use the `{}` method", suggest),
30+
"like this",
31+
format!("{}{}.{}('{}')",
32+
if info.eq { "" } else { "!" },
33+
snippet_with_applicability(cx, args[0][0].span, "..", &mut applicability),
34+
suggest,
35+
c),
36+
applicability,
37+
);
38+
39+
true
40+
} else {
41+
false
42+
}
43+
}
44+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::methods::chars_cmp;
2+
use rustc_lint::LateContext;
3+
4+
use super::CHARS_LAST_CMP;
5+
6+
/// Checks for the `CHARS_LAST_CMP` lint.
7+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
8+
if chars_cmp::check(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
9+
true
10+
} else {
11+
chars_cmp::check(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with")
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::methods::chars_cmp_with_unwrap;
2+
use rustc_lint::LateContext;
3+
4+
use super::CHARS_LAST_CMP;
5+
6+
/// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`.
7+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
8+
if chars_cmp_with_unwrap::check(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") {
9+
true
10+
} else {
11+
chars_cmp_with_unwrap::check(cx, info, &["chars", "next_back", "unwrap"], CHARS_LAST_CMP, "ends_with")
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use rustc_lint::LateContext;
2+
3+
use super::CHARS_NEXT_CMP;
4+
5+
/// Checks for the `CHARS_NEXT_CMP` lint.
6+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
7+
crate::methods::chars_cmp::check(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with")
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use rustc_lint::LateContext;
2+
3+
use super::CHARS_NEXT_CMP;
4+
5+
/// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`.
6+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
7+
crate::methods::chars_cmp_with_unwrap::check(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with")
8+
}

clippy_lints/src/methods/clone_on_copy.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ use clippy_utils::ty::is_copy;
44
use rustc_errors::Applicability;
55
use rustc_hir as hir;
66
use rustc_lint::LateContext;
7-
use rustc_middle::ty::{self, Ty};
7+
use rustc_middle::ty;
8+
use rustc_span::symbol::{sym, Symbol};
89
use std::iter;
910

1011
use super::CLONE_DOUBLE_REF;
1112
use super::CLONE_ON_COPY;
1213

1314
/// Checks for the `CLONE_ON_COPY` lint.
14-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'_>) {
15+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
16+
if !(args.len() == 1 && method_name == sym::clone) {
17+
return;
18+
}
19+
let arg = &args[0];
20+
let arg_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
1521
let ty = cx.typeck_results().expr_ty(expr);
1622
if let ty::Ref(_, inner, _) = arg_ty.kind() {
1723
if let ty::Ref(_, innermost, _) = inner.kind() {

clippy_lints/src/methods/clone_on_ref_ptr.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_lint::LateContext;
88
use rustc_middle::ty;
9-
use rustc_span::symbol::sym;
9+
use rustc_span::symbol::{sym, Symbol};
1010

1111
use super::CLONE_ON_REF_PTR;
1212

13-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
13+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
14+
if !(args.len() == 1 && method_name == sym::clone) {
15+
return;
16+
}
17+
let arg = &args[0];
1418
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
1519

1620
if let ty::Adt(_, subst) = obj_ty.kind() {

clippy_lints/src/methods/filter_flat_map.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ use rustc_span::sym;
77
use super::FILTER_MAP;
88

99
/// lint use of `filter().flat_map()` for `Iterators`
10-
pub(super) fn check<'tcx>(
11-
cx: &LateContext<'tcx>,
12-
expr: &'tcx hir::Expr<'_>,
13-
_filter_args: &'tcx [hir::Expr<'_>],
14-
_map_args: &'tcx [hir::Expr<'_>],
15-
) {
10+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
1611
// lint if caller of `.filter().flat_map()` is an Iterator
1712
if is_trait_method(cx, expr, sym::Iterator) {
1813
let msg = "called `filter(..).flat_map(..)` on an `Iterator`";

clippy_lints/src/methods/filter_map_flat_map.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ use rustc_span::sym;
77
use super::FILTER_MAP;
88

99
/// lint use of `filter_map().flat_map()` for `Iterators`
10-
pub(super) fn check<'tcx>(
11-
cx: &LateContext<'tcx>,
12-
expr: &'tcx hir::Expr<'_>,
13-
_filter_args: &'tcx [hir::Expr<'_>],
14-
_map_args: &'tcx [hir::Expr<'_>],
15-
) {
10+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
1611
// lint if caller of `.filter_map().flat_map()` is an Iterator
1712
if is_trait_method(cx, expr, sym::Iterator) {
1813
let msg = "called `filter_map(..).flat_map(..)` on an `Iterator`";

clippy_lints/src/methods/filter_map_map.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ use rustc_span::sym;
77
use super::FILTER_MAP;
88

99
/// lint use of `filter_map().map()` for `Iterators`
10-
pub(super) fn check<'tcx>(
11-
cx: &LateContext<'tcx>,
12-
expr: &'tcx hir::Expr<'_>,
13-
_filter_args: &'tcx [hir::Expr<'_>],
14-
_map_args: &'tcx [hir::Expr<'_>],
15-
) {
10+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
1611
// lint if caller of `.filter_map().map()` is an Iterator
1712
if is_trait_method(cx, expr, sym::Iterator) {
1813
let msg = "called `filter_map(..).map(..)` on an `Iterator`";

clippy_lints/src/methods/from_iter_instead_of_collect.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::ty::implements_trait;
3-
use clippy_utils::{get_trait_def_id, paths, sugg};
3+
use clippy_utils::{get_trait_def_id, match_qpath, paths, sugg};
44
use if_chain::if_chain;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
7+
use rustc_hir::ExprKind;
78
use rustc_lint::{LateContext, LintContext};
89
use rustc_middle::ty::Ty;
910
use rustc_span::sym;
1011

1112
use super::FROM_ITER_INSTEAD_OF_COLLECT;
1213

13-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
14-
let ty = cx.typeck_results().expr_ty(expr);
15-
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
16-
14+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func_kind: &ExprKind<'_>) {
1715
if_chain! {
16+
if let hir::ExprKind::Path(path) = func_kind;
17+
if match_qpath(path, &["from_iter"]);
18+
let ty = cx.typeck_results().expr_ty(expr);
19+
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
1820
if let Some(from_iter_id) = get_trait_def_id(cx, &paths::FROM_ITERATOR);
1921
if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
2022

clippy_lints/src/methods/get_unwrap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::methods::derefs_to_slice;
1+
use super::utils::derefs_to_slice;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::ty::{is_type_diagnostic_item, match_type};

clippy_lints/src/methods/inefficient_to_string.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::INEFFICIENT_TO_STRING;
21
use clippy_utils::diagnostics::span_lint_and_then;
32
use clippy_utils::source::snippet_with_applicability;
43
use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth};
@@ -8,14 +7,18 @@ use rustc_errors::Applicability;
87
use rustc_hir as hir;
98
use rustc_lint::LateContext;
109
use rustc_middle::ty::{self, Ty};
11-
use rustc_span::sym;
10+
use rustc_span::symbol::{sym, Symbol};
11+
12+
use super::INEFFICIENT_TO_STRING;
1213

1314
/// Checks for the `INEFFICIENT_TO_STRING` lint
14-
pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>, arg_ty: Ty<'tcx>) {
15+
pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Symbol, args: &[hir::Expr<'_>]) {
1516
if_chain! {
17+
if args.len() == 1 && method_name == sym!(to_string);
1618
if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
1719
if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD);
1820
if let Some(substs) = cx.typeck_results().node_substs_opt(expr.hir_id);
21+
let arg_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
1922
let self_ty = substs.type_at(0);
2023
let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty);
2124
if deref_count >= 1;
@@ -32,7 +35,7 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &hir::Expr
3235
self_ty, deref_self_ty
3336
));
3437
let mut applicability = Applicability::MachineApplicable;
35-
let arg_snippet = snippet_with_applicability(cx, arg.span, "..", &mut applicability);
38+
let arg_snippet = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);
3639
diag.span_suggestion(
3740
expr.span,
3841
"try dereferencing the receiver",

clippy_lints/src/methods/into_iter_on_ref.rs

+30-19
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,43 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::is_trait_method;
23
use clippy_utils::ty::has_iter_method;
3-
use clippy_utils::{match_trait_method, paths};
4+
use if_chain::if_chain;
45
use rustc_errors::Applicability;
56
use rustc_hir as hir;
67
use rustc_lint::LateContext;
78
use rustc_middle::ty::{self, Ty};
89
use rustc_span::source_map::Span;
9-
use rustc_span::symbol::Symbol;
10+
use rustc_span::symbol::{sym, Symbol};
1011

1112
use super::INTO_ITER_ON_REF;
1213

13-
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, self_ref_ty: Ty<'_>, method_span: Span) {
14-
if !match_trait_method(cx, expr, &paths::INTO_ITERATOR) {
15-
return;
16-
}
17-
if let Some((kind, method_name)) = ty_has_iter_method(cx, self_ref_ty) {
18-
span_lint_and_sugg(
19-
cx,
20-
INTO_ITER_ON_REF,
21-
method_span,
22-
&format!(
23-
"this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`",
24-
method_name, kind,
25-
),
26-
"call directly",
27-
method_name.to_string(),
28-
Applicability::MachineApplicable,
29-
);
14+
pub(super) fn check(
15+
cx: &LateContext<'_>,
16+
expr: &hir::Expr<'_>,
17+
method_span: Span,
18+
method_name: Symbol,
19+
args: &[hir::Expr<'_>],
20+
) {
21+
let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
22+
if_chain! {
23+
if let ty::Ref(..) = self_ty.kind();
24+
if method_name == sym::into_iter;
25+
if is_trait_method(cx, expr, sym::IntoIterator);
26+
if let Some((kind, method_name)) = ty_has_iter_method(cx, self_ty);
27+
then {
28+
span_lint_and_sugg(
29+
cx,
30+
INTO_ITER_ON_REF,
31+
method_span,
32+
&format!(
33+
"this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`",
34+
method_name, kind,
35+
),
36+
"call directly",
37+
method_name.to_string(),
38+
Applicability::MachineApplicable,
39+
);
40+
}
3041
}
3142
}
3243

clippy_lints/src/methods/iter_cloned_collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::methods::derefs_to_slice;
1+
use crate::methods::utils::derefs_to_slice;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::ty::is_type_diagnostic_item;
44
use if_chain::if_chain;

clippy_lints/src/methods/iter_count.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::methods::derefs_to_slice;
1+
use super::utils::derefs_to_slice;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::paths;
44
use clippy_utils::source::snippet_with_applicability;

0 commit comments

Comments
 (0)