Skip to content

Commit 2ade32d

Browse files
committed
move string_extend_chars and clone_on_ref_ptr to their own module
1 parent b5d809a commit 2ade32d

File tree

3 files changed

+82
-68
lines changed

3 files changed

+82
-68
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use crate::utils::{is_type_diagnostic_item, match_type, paths, snippet_with_macro_callsite, span_lint_and_sugg};
2+
use rustc_errors::Applicability;
3+
use rustc_hir as hir;
4+
use rustc_lint::LateContext;
5+
use rustc_middle::ty;
6+
use rustc_span::symbol::sym;
7+
8+
use super::CLONE_ON_REF_PTR;
9+
10+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
11+
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
12+
13+
if let ty::Adt(_, subst) = obj_ty.kind() {
14+
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
15+
"Rc"
16+
} else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
17+
"Arc"
18+
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
19+
"Weak"
20+
} else {
21+
return;
22+
};
23+
24+
let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
25+
26+
span_lint_and_sugg(
27+
cx,
28+
CLONE_ON_REF_PTR,
29+
expr.span,
30+
"using `.clone()` on a ref-counted pointer",
31+
"try this",
32+
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet),
33+
Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
34+
);
35+
}
36+
}

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod bind_instead_of_map;
22
mod bytes_nth;
3+
mod clone_on_ref_ptr;
34
mod expect_used;
45
mod filetype_is_file;
56
mod filter_map_identity;
@@ -20,6 +21,7 @@ mod ok_expect;
2021
mod option_as_ref_deref;
2122
mod option_map_unwrap_or;
2223
mod skip_while_next;
24+
mod string_extend_chars;
2325
mod suspicious_map;
2426
mod uninit_assumed_init;
2527
mod unnecessary_filter_map;
@@ -1707,7 +1709,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
17071709
["is_some", "rposition"] => {
17081710
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
17091711
},
1710-
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
1712+
["extend", ..] => string_extend_chars::check(cx, expr, arg_lists[0]),
17111713
["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"),
17121714
["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"),
17131715
["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"),
@@ -1767,7 +1769,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
17671769
let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
17681770
if args.len() == 1 && method_call.ident.name == sym::clone {
17691771
lint_clone_on_copy(cx, expr, &args[0], self_ty);
1770-
lint_clone_on_ref_ptr(cx, expr, &args[0]);
1772+
clone_on_ref_ptr::check(cx, expr, &args[0]);
17711773
}
17721774
if args.len() == 1 && method_call.ident.name == sym!(to_string) {
17731775
inefficient_to_string::check(cx, expr, &args[0], self_ty);
@@ -2408,72 +2410,6 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp
24082410
}
24092411
}
24102412

2411-
fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
2412-
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
2413-
2414-
if let ty::Adt(_, subst) = obj_ty.kind() {
2415-
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
2416-
"Rc"
2417-
} else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
2418-
"Arc"
2419-
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
2420-
"Weak"
2421-
} else {
2422-
return;
2423-
};
2424-
2425-
let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
2426-
2427-
span_lint_and_sugg(
2428-
cx,
2429-
CLONE_ON_REF_PTR,
2430-
expr.span,
2431-
"using `.clone()` on a ref-counted pointer",
2432-
"try this",
2433-
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet),
2434-
Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
2435-
);
2436-
}
2437-
}
2438-
2439-
fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
2440-
let arg = &args[1];
2441-
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
2442-
let target = &arglists[0][0];
2443-
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
2444-
let ref_str = if *self_ty.kind() == ty::Str {
2445-
""
2446-
} else if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
2447-
"&"
2448-
} else {
2449-
return;
2450-
};
2451-
2452-
let mut applicability = Applicability::MachineApplicable;
2453-
span_lint_and_sugg(
2454-
cx,
2455-
STRING_EXTEND_CHARS,
2456-
expr.span,
2457-
"calling `.extend(_.chars())`",
2458-
"try this",
2459-
format!(
2460-
"{}.push_str({}{})",
2461-
snippet_with_applicability(cx, args[0].span, "..", &mut applicability),
2462-
ref_str,
2463-
snippet_with_applicability(cx, target.span, "..", &mut applicability)
2464-
),
2465-
applicability,
2466-
);
2467-
}
2468-
}
2469-
2470-
fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
2471-
let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
2472-
if is_type_diagnostic_item(cx, obj_ty, sym::string_type) {
2473-
lint_string_extend(cx, expr, args);
2474-
}
2475-
}
2476-
24772413
fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) {
24782414
fn check_fold_with_op(
24792415
cx: &LateContext<'_>,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use crate::utils::{is_type_diagnostic_item, method_chain_args, snippet_with_applicability, span_lint_and_sugg};
2+
use rustc_errors::Applicability;
3+
use rustc_hir as hir;
4+
use rustc_lint::LateContext;
5+
use rustc_middle::ty;
6+
use rustc_span::symbol::sym;
7+
8+
use super::STRING_EXTEND_CHARS;
9+
10+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
11+
let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
12+
if is_type_diagnostic_item(cx, obj_ty, sym::string_type) {
13+
let arg = &args[1];
14+
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
15+
let target = &arglists[0][0];
16+
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
17+
let ref_str = if *self_ty.kind() == ty::Str {
18+
""
19+
} else if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
20+
"&"
21+
} else {
22+
return;
23+
};
24+
25+
let mut applicability = Applicability::MachineApplicable;
26+
span_lint_and_sugg(
27+
cx,
28+
STRING_EXTEND_CHARS,
29+
expr.span,
30+
"calling `.extend(_.chars())`",
31+
"try this",
32+
format!(
33+
"{}.push_str({}{})",
34+
snippet_with_applicability(cx, args[0].span, "..", &mut applicability),
35+
ref_str,
36+
snippet_with_applicability(cx, target.span, "..", &mut applicability)
37+
),
38+
applicability,
39+
);
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)