move string_extend_chars and clone_on_ref_ptr to their own module
This commit is contained in:
parent
b5d809a660
commit
2ade32ddf2
3 changed files with 82 additions and 68 deletions
36
clippy_lints/src/methods/clone_on_ref_ptr.rs
Normal file
36
clippy_lints/src/methods/clone_on_ref_ptr.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::utils::{is_type_diagnostic_item, match_type, paths, snippet_with_macro_callsite, span_lint_and_sugg};
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_middle::ty;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
|
use super::CLONE_ON_REF_PTR;
|
||||||
|
|
||||||
|
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
|
||||||
|
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
|
||||||
|
|
||||||
|
if let ty::Adt(_, subst) = obj_ty.kind() {
|
||||||
|
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
|
||||||
|
"Rc"
|
||||||
|
} else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
|
||||||
|
"Arc"
|
||||||
|
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
|
||||||
|
"Weak"
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
|
||||||
|
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
CLONE_ON_REF_PTR,
|
||||||
|
expr.span,
|
||||||
|
"using `.clone()` on a ref-counted pointer",
|
||||||
|
"try this",
|
||||||
|
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet),
|
||||||
|
Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
mod bind_instead_of_map;
|
mod bind_instead_of_map;
|
||||||
mod bytes_nth;
|
mod bytes_nth;
|
||||||
|
mod clone_on_ref_ptr;
|
||||||
mod expect_used;
|
mod expect_used;
|
||||||
mod filetype_is_file;
|
mod filetype_is_file;
|
||||||
mod filter_map_identity;
|
mod filter_map_identity;
|
||||||
|
@ -20,6 +21,7 @@ mod ok_expect;
|
||||||
mod option_as_ref_deref;
|
mod option_as_ref_deref;
|
||||||
mod option_map_unwrap_or;
|
mod option_map_unwrap_or;
|
||||||
mod skip_while_next;
|
mod skip_while_next;
|
||||||
|
mod string_extend_chars;
|
||||||
mod suspicious_map;
|
mod suspicious_map;
|
||||||
mod uninit_assumed_init;
|
mod uninit_assumed_init;
|
||||||
mod unnecessary_filter_map;
|
mod unnecessary_filter_map;
|
||||||
|
@ -1707,7 +1709,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
["is_some", "rposition"] => {
|
["is_some", "rposition"] => {
|
||||||
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
|
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
|
||||||
},
|
},
|
||||||
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
|
["extend", ..] => string_extend_chars::check(cx, expr, arg_lists[0]),
|
||||||
["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"),
|
["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"),
|
||||||
["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"),
|
["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"),
|
||||||
["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"),
|
["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"),
|
||||||
|
@ -1767,7 +1769,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||||
let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
|
let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
|
||||||
if args.len() == 1 && method_call.ident.name == sym::clone {
|
if args.len() == 1 && method_call.ident.name == sym::clone {
|
||||||
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
||||||
lint_clone_on_ref_ptr(cx, expr, &args[0]);
|
clone_on_ref_ptr::check(cx, expr, &args[0]);
|
||||||
}
|
}
|
||||||
if args.len() == 1 && method_call.ident.name == sym!(to_string) {
|
if args.len() == 1 && method_call.ident.name == sym!(to_string) {
|
||||||
inefficient_to_string::check(cx, expr, &args[0], self_ty);
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lint_clone_on_ref_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
|
|
||||||
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
|
|
||||||
|
|
||||||
if let ty::Adt(_, subst) = obj_ty.kind() {
|
|
||||||
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
|
|
||||||
"Rc"
|
|
||||||
} else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
|
|
||||||
"Arc"
|
|
||||||
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
|
|
||||||
"Weak"
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
|
|
||||||
|
|
||||||
span_lint_and_sugg(
|
|
||||||
cx,
|
|
||||||
CLONE_ON_REF_PTR,
|
|
||||||
expr.span,
|
|
||||||
"using `.clone()` on a ref-counted pointer",
|
|
||||||
"try this",
|
|
||||||
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet),
|
|
||||||
Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lint_string_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
|
|
||||||
let arg = &args[1];
|
|
||||||
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
|
|
||||||
let target = &arglists[0][0];
|
|
||||||
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
|
|
||||||
let ref_str = if *self_ty.kind() == ty::Str {
|
|
||||||
""
|
|
||||||
} else if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
|
|
||||||
"&"
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
|
||||||
span_lint_and_sugg(
|
|
||||||
cx,
|
|
||||||
STRING_EXTEND_CHARS,
|
|
||||||
expr.span,
|
|
||||||
"calling `.extend(_.chars())`",
|
|
||||||
"try this",
|
|
||||||
format!(
|
|
||||||
"{}.push_str({}{})",
|
|
||||||
snippet_with_applicability(cx, args[0].span, "..", &mut applicability),
|
|
||||||
ref_str,
|
|
||||||
snippet_with_applicability(cx, target.span, "..", &mut applicability)
|
|
||||||
),
|
|
||||||
applicability,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
|
|
||||||
let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
|
|
||||||
if is_type_diagnostic_item(cx, obj_ty, sym::string_type) {
|
|
||||||
lint_string_extend(cx, expr, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) {
|
fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args: &[hir::Expr<'_>], fold_span: Span) {
|
||||||
fn check_fold_with_op(
|
fn check_fold_with_op(
|
||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
|
|
42
clippy_lints/src/methods/string_extend_chars.rs
Normal file
42
clippy_lints/src/methods/string_extend_chars.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use crate::utils::{is_type_diagnostic_item, method_chain_args, snippet_with_applicability, span_lint_and_sugg};
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_middle::ty;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
|
use super::STRING_EXTEND_CHARS;
|
||||||
|
|
||||||
|
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
|
||||||
|
let obj_ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
|
||||||
|
if is_type_diagnostic_item(cx, obj_ty, sym::string_type) {
|
||||||
|
let arg = &args[1];
|
||||||
|
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
|
||||||
|
let target = &arglists[0][0];
|
||||||
|
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
|
||||||
|
let ref_str = if *self_ty.kind() == ty::Str {
|
||||||
|
""
|
||||||
|
} else if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
|
||||||
|
"&"
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
STRING_EXTEND_CHARS,
|
||||||
|
expr.span,
|
||||||
|
"calling `.extend(_.chars())`",
|
||||||
|
"try this",
|
||||||
|
format!(
|
||||||
|
"{}.push_str({}{})",
|
||||||
|
snippet_with_applicability(cx, args[0].span, "..", &mut applicability),
|
||||||
|
ref_str,
|
||||||
|
snippet_with_applicability(cx, target.span, "..", &mut applicability)
|
||||||
|
),
|
||||||
|
applicability,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue