Skip to content

Commit 9c9f365

Browse files
committed
add two lints to string module
1 parent 9e0fdb4 commit 9c9f365

File tree

5 files changed

+105
-117
lines changed

5 files changed

+105
-117
lines changed

clippy_lints/src/lib.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,6 @@ mod shadow;
306306
mod single_component_path_imports;
307307
mod slow_vector_initialization;
308308
mod stable_sort_primitive;
309-
mod str_to_string;
310-
mod string_to_string;
311309
mod strings;
312310
mod suspicious_trait_impl;
313311
mod swap;
@@ -829,12 +827,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
829827
&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
830828
&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
831829
&stable_sort_primitive::STABLE_SORT_PRIMITIVE,
832-
&str_to_string::STR_TO_STRING,
833-
&string_to_string::STRING_TO_STRING,
834830
&strings::STRING_ADD,
835831
&strings::STRING_ADD_ASSIGN,
836832
&strings::STRING_FROM_UTF8_AS_BYTES,
837833
&strings::STRING_LIT_AS_BYTES,
834+
&strings::STRING_TO_STRING,
835+
&strings::STR_TO_STRING,
838836
&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
839837
&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
840838
&swap::ALMOST_SWAPPED,
@@ -1169,8 +1167,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11691167
store.register_early_pass(|| box asm_syntax::InlineAsmX86AttSyntax);
11701168
store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
11711169
store.register_late_pass(|| box undropped_manually_drops::UndroppedManuallyDrops);
1172-
store.register_late_pass(|| box str_to_string::StrToString);
1173-
store.register_late_pass(|| box string_to_string::StringToString);
1170+
store.register_late_pass(|| box strings::StrToString);
1171+
store.register_late_pass(|| box strings::StringToString);
11741172

11751173

11761174
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
@@ -1212,9 +1210,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12121210
LintId::of(&pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
12131211
LintId::of(&shadow::SHADOW_REUSE),
12141212
LintId::of(&shadow::SHADOW_SAME),
1215-
LintId::of(&str_to_string::STR_TO_STRING),
1216-
LintId::of(&string_to_string::STRING_TO_STRING),
12171213
LintId::of(&strings::STRING_ADD),
1214+
LintId::of(&strings::STRING_TO_STRING),
1215+
LintId::of(&strings::STR_TO_STRING),
12181216
LintId::of(&types::RC_BUFFER),
12191217
LintId::of(&unwrap_in_result::UNWRAP_IN_RESULT),
12201218
LintId::of(&verbose_file_reads::VERBOSE_FILE_READS),

clippy_lints/src/str_to_string.rs

Lines changed: 0 additions & 53 deletions
This file was deleted.

clippy_lints/src/string_to_string.rs

Lines changed: 0 additions & 53 deletions
This file was deleted.

clippy_lints/src/strings.rs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_errors::Applicability;
22
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, QPath};
33
use rustc_lint::{LateContext, LateLintPass, LintContext};
44
use rustc_middle::lint::in_external_macro;
5+
use rustc_middle::ty;
56
use rustc_session::{declare_lint_pass, declare_tool_lint};
67
use rustc_span::source_map::Spanned;
78
use rustc_span::sym;
@@ -11,7 +12,7 @@ use if_chain::if_chain;
1112
use crate::utils::SpanlessEq;
1213
use crate::utils::{
1314
get_parent_expr, is_allowed, is_type_diagnostic_item, match_function_call, method_calls, paths, span_lint,
14-
span_lint_and_sugg,
15+
span_lint_and_help, span_lint_and_sugg,
1516
};
1617

1718
declare_clippy_lint! {
@@ -289,3 +290,98 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
289290
}
290291
}
291292
}
293+
294+
declare_clippy_lint! {
295+
/// **What it does:** This lint checks for `.to_string()` method calls on values of type `&str`.
296+
///
297+
/// **Why is this bad?** This does a multitude of things to just clone a string. Using `.to_owned()` is more specific.
298+
///
299+
/// **Known problems:** None.
300+
///
301+
/// **Example:**
302+
///
303+
/// ```rust
304+
/// // example code where clippy issues a warning
305+
/// let _ = "str".to_string();
306+
/// ```
307+
/// Use instead:
308+
/// ```rust
309+
/// // example code which does not raise clippy warning
310+
/// let _ = "str".to_owned();
311+
/// ```
312+
pub STR_TO_STRING,
313+
restriction,
314+
"using `to_string()` on a `&str`, which should be `to_owned()`"
315+
}
316+
317+
declare_lint_pass!(StrToString => [STR_TO_STRING]);
318+
319+
impl LateLintPass<'_> for StrToString {
320+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
321+
if_chain! {
322+
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind;
323+
if path.ident.name == sym!(to_string);
324+
let ty = cx.typeck_results().expr_ty(&args[0]);
325+
if let ty::Ref(_, ty, ..) = ty.kind();
326+
if *ty.kind() == ty::Str;
327+
then {
328+
span_lint_and_help(
329+
cx,
330+
STR_TO_STRING,
331+
expr.span,
332+
"`to_string()` does a multitude of things to just clone a `&str`",
333+
None,
334+
"consider using `.to_owned()`",
335+
);
336+
}
337+
}
338+
}
339+
}
340+
341+
declare_clippy_lint! {
342+
/// **What it does:** This lint checks for `.to_string()` method calls on values of type `String`.
343+
///
344+
/// **Why is this bad?** This does a multitude of things to just clone a string. Using `.clone()` is more specific.
345+
///
346+
/// **Known problems:** None.
347+
///
348+
/// **Example:**
349+
///
350+
/// ```rust
351+
/// // example code where clippy issues a warning
352+
/// let msg = String::from("Hello World");
353+
/// let _ = msg.to_string();
354+
/// ```
355+
/// Use instead:
356+
/// ```rust
357+
/// // example code which does not raise clippy warning
358+
/// let msg = String::from("Hello World");
359+
/// let _ = msg.clone();
360+
/// ```
361+
pub STRING_TO_STRING,
362+
restriction,
363+
"using `to_string()` on a `String`, which should be `clone()`"
364+
}
365+
366+
declare_lint_pass!(StringToString => [STRING_TO_STRING]);
367+
368+
impl LateLintPass<'_> for StringToString {
369+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
370+
if_chain! {
371+
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind;
372+
if path.ident.name == sym!(to_string);
373+
let ty = cx.typeck_results().expr_ty(&args[0]);
374+
if is_type_diagnostic_item(cx, ty, sym!(string_type));
375+
then {
376+
span_lint_and_help(
377+
cx,
378+
STRING_TO_STRING,
379+
expr.span,
380+
"`to_string()` does a multitude of things to just clone a `String`",
381+
None,
382+
"consider using `.clone()`",
383+
);
384+
}
385+
}
386+
}
387+
}

src/lintlist/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,7 +2242,7 @@ vec![
22422242
group: "restriction",
22432243
desc: "using `to_string()` on a `&str`, which should be `to_owned()`",
22442244
deprecation: None,
2245-
module: "str_to_string",
2245+
module: "strings",
22462246
},
22472247
Lint {
22482248
name: "string_add",
@@ -2284,7 +2284,7 @@ vec![
22842284
group: "restriction",
22852285
desc: "using `to_string()` on a `String`, which should be `clone()`",
22862286
deprecation: None,
2287-
module: "string_to_string",
2287+
module: "strings",
22882288
},
22892289
Lint {
22902290
name: "struct_excessive_bools",

0 commit comments

Comments
 (0)