about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-25 16:02:42 +0000
committerbors <bors@rust-lang.org>2020-11-25 16:02:42 +0000
commitae57785966e4bd1d80ade0bc239076d40e72ccee (patch)
treee0390dba94781e9c2c4186ec1ad29a471cf5a8b3
parent32c51d2c58c36df312d61a49a3512beb29c19636 (diff)
parent2345ef5b1f89d9cac7a6697de08c36bfb771fe12 (diff)
downloadrust-ae57785966e4bd1d80ade0bc239076d40e72ccee.tar.gz
rust-ae57785966e4bd1d80ade0bc239076d40e72ccee.zip
Auto merge of #6333 - PunitLodha:master, r=flip1995
Added lint str_to_string

*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: un-deprecate [`str_to_string`] and [`string_to_string`] and introduce them as `restriction` lints again.
Fixes #5610
Added new lint:- str_to_string
r? `@flip1995`
-rw-r--r--clippy_lints/src/deprecated_lints.rs20
-rw-r--r--clippy_lints/src/lib.rs22
-rw-r--r--clippy_lints/src/strings.rs100
-rw-r--r--src/lintlist/mod.rs14
-rw-r--r--tests/ui/deprecated.rs2
-rw-r--r--tests/ui/deprecated.stderr46
-rw-r--r--tests/ui/deprecated_old.rs2
-rw-r--r--tests/ui/deprecated_old.stderr30
-rw-r--r--tests/ui/str_to_string.rs7
-rw-r--r--tests/ui/str_to_string.stderr19
-rw-r--r--tests/ui/string_to_string.rs7
-rw-r--r--tests/ui/string_to_string.stderr11
12 files changed, 189 insertions, 91 deletions
diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs
index 1c3285ed701..bec0c9f93a0 100644
--- a/clippy_lints/src/deprecated_lints.rs
+++ b/clippy_lints/src/deprecated_lints.rs
@@ -54,26 +54,6 @@ declare_deprecated_lint! {
 declare_deprecated_lint! {
     /// **What it does:** Nothing. This lint has been deprecated.
     ///
-    /// **Deprecation reason:** This used to check for `.to_string()` method calls on values
-    /// of type `&str`. This is not unidiomatic and with specialization coming, `to_string` could be
-    /// specialized to be as efficient as `to_owned`.
-    pub STR_TO_STRING,
-    "using `str::to_string` is common even today and specialization will likely happen soon"
-}
-
-declare_deprecated_lint! {
-    /// **What it does:** Nothing. This lint has been deprecated.
-    ///
-    /// **Deprecation reason:** This used to check for `.to_string()` method calls on values
-    /// of type `String`. This is not unidiomatic and with specialization coming, `to_string` could be
-    /// specialized to be as efficient as `clone`.
-    pub STRING_TO_STRING,
-    "using `string::to_string` is common even today and specialization will likely happen soon"
-}
-
-declare_deprecated_lint! {
-    /// **What it does:** Nothing. This lint has been deprecated.
-    ///
     /// **Deprecation reason:** This lint should never have applied to non-pointer types, as transmuting
     /// between non-pointer types of differing alignment is well-defined behavior (it's semantically
     /// equivalent to a memcpy). This lint has thus been refactored into two separate lints:
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 866dae110cc..67a3a3fcf48 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -442,14 +442,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         "`Vec::as_mut_slice` has been stabilized in 1.7",
     );
     store.register_removed(
-        "clippy::str_to_string",
-        "using `str::to_string` is common even today and specialization will likely happen soon",
-    );
-    store.register_removed(
-        "clippy::string_to_string",
-        "using `string::to_string` is common even today and specialization will likely happen soon",
-    );
-    store.register_removed(
         "clippy::misaligned_transmute",
         "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
     );
@@ -840,6 +832,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &strings::STRING_ADD_ASSIGN,
         &strings::STRING_FROM_UTF8_AS_BYTES,
         &strings::STRING_LIT_AS_BYTES,
+        &strings::STRING_TO_STRING,
+        &strings::STR_TO_STRING,
         &suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
         &suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
         &swap::ALMOST_SWAPPED,
@@ -1186,6 +1180,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(|| box asm_syntax::InlineAsmX86AttSyntax);
     store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
     store.register_late_pass(|| box undropped_manually_drops::UndroppedManuallyDrops);
+    store.register_late_pass(|| box strings::StrToString);
+    store.register_late_pass(|| box strings::StringToString);
 
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
@@ -1228,6 +1224,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&shadow::SHADOW_REUSE),
         LintId::of(&shadow::SHADOW_SAME),
         LintId::of(&strings::STRING_ADD),
+        LintId::of(&strings::STRING_TO_STRING),
+        LintId::of(&strings::STR_TO_STRING),
         LintId::of(&types::RC_BUFFER),
         LintId::of(&unwrap_in_result::UNWRAP_IN_RESULT),
         LintId::of(&verbose_file_reads::VERBOSE_FILE_READS),
@@ -1944,14 +1942,6 @@ fn register_removed_non_tool_lints(store: &mut rustc_lint::LintStore) {
         "`Vec::as_mut_slice` has been stabilized in 1.7",
     );
     store.register_removed(
-        "str_to_string",
-        "using `str::to_string` is common even today and specialization will likely happen soon",
-    );
-    store.register_removed(
-        "string_to_string",
-        "using `string::to_string` is common even today and specialization will likely happen soon",
-    );
-    store.register_removed(
         "misaligned_transmute",
         "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
     );
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index ede37624f71..42c45be3b45 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -2,6 +2,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, QPath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Spanned;
 use rustc_span::sym;
@@ -11,7 +12,7 @@ use if_chain::if_chain;
 use crate::utils::SpanlessEq;
 use crate::utils::{
     get_parent_expr, is_allowed, is_type_diagnostic_item, match_function_call, method_calls, paths, span_lint,
-    span_lint_and_sugg,
+    span_lint_and_help, span_lint_and_sugg,
 };
 
 declare_clippy_lint! {
@@ -289,3 +290,100 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
         }
     }
 }
+
+declare_clippy_lint! {
+    /// **What it does:** This lint checks for `.to_string()` method calls on values of type `&str`.
+    ///
+    /// **Why is this bad?** The `to_string` method is also used on other types to convert them to a string.
+    /// When called on a `&str` it turns the `&str` into the owned variant `String`, which can be better
+    /// expressed with `.to_owned()`.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// // example code where clippy issues a warning
+    /// let _ = "str".to_string();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// // example code which does not raise clippy warning
+    /// let _ = "str".to_owned();
+    /// ```
+    pub STR_TO_STRING,
+    restriction,
+    "using `to_string()` on a `&str`, which should be `to_owned()`"
+}
+
+declare_lint_pass!(StrToString => [STR_TO_STRING]);
+
+impl LateLintPass<'_> for StrToString {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
+        if_chain! {
+            if let ExprKind::MethodCall(path, _, args, _) = &expr.kind;
+            if path.ident.name == sym!(to_string);
+            let ty = cx.typeck_results().expr_ty(&args[0]);
+            if let ty::Ref(_, ty, ..) = ty.kind();
+            if *ty.kind() == ty::Str;
+            then {
+                span_lint_and_help(
+                    cx,
+                    STR_TO_STRING,
+                    expr.span,
+                    "`to_string()` called on a `&str`",
+                    None,
+                    "consider using `.to_owned()`",
+                );
+            }
+        }
+    }
+}
+
+declare_clippy_lint! {
+    /// **What it does:** This lint checks for `.to_string()` method calls on values of type `String`.
+    ///
+    /// **Why is this bad?** The `to_string` method is also used on other types to convert them to a string.
+    /// When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`.
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// // example code where clippy issues a warning
+    /// let msg = String::from("Hello World");
+    /// let _ = msg.to_string();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// // example code which does not raise clippy warning
+    /// let msg = String::from("Hello World");
+    /// let _ = msg.clone();
+    /// ```
+    pub STRING_TO_STRING,
+    restriction,
+    "using `to_string()` on a `String`, which should be `clone()`"
+}
+
+declare_lint_pass!(StringToString => [STRING_TO_STRING]);
+
+impl LateLintPass<'_> for StringToString {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
+        if_chain! {
+            if let ExprKind::MethodCall(path, _, args, _) = &expr.kind;
+            if path.ident.name == sym!(to_string);
+            let ty = cx.typeck_results().expr_ty(&args[0]);
+            if is_type_diagnostic_item(cx, ty, sym!(string_type));
+            then {
+                span_lint_and_help(
+                    cx,
+                    STRING_TO_STRING,
+                    expr.span,
+                    "`to_string()` called on a `String`",
+                    None,
+                    "consider using `.clone()`",
+                );
+            }
+        }
+    }
+}
diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs
index 1d906d20ad4..a104f687bdf 100644
--- a/src/lintlist/mod.rs
+++ b/src/lintlist/mod.rs
@@ -2238,6 +2238,13 @@ vec![
         module: "stable_sort_primitive",
     },
     Lint {
+        name: "str_to_string",
+        group: "restriction",
+        desc: "using `to_string()` on a `&str`, which should be `to_owned()`",
+        deprecation: None,
+        module: "strings",
+    },
+    Lint {
         name: "string_add",
         group: "restriction",
         desc: "using `x + ..` where x is a `String` instead of `push_str()`",
@@ -2273,6 +2280,13 @@ vec![
         module: "strings",
     },
     Lint {
+        name: "string_to_string",
+        group: "restriction",
+        desc: "using `to_string()` on a `String`, which should be `clone()`",
+        deprecation: None,
+        module: "strings",
+    },
+    Lint {
         name: "struct_excessive_bools",
         group: "pedantic",
         desc: "using too many bools in a struct",
diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs
index 4cbc5630d75..e1ee8dbca2c 100644
--- a/tests/ui/deprecated.rs
+++ b/tests/ui/deprecated.rs
@@ -1,5 +1,3 @@
-#[warn(clippy::str_to_string)]
-#[warn(clippy::string_to_string)]
 #[warn(clippy::unstable_as_slice)]
 #[warn(clippy::unstable_as_mut_slice)]
 #[warn(clippy::misaligned_transmute)]
diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr
index a348d01d734..edbb891afe0 100644
--- a/tests/ui/deprecated.stderr
+++ b/tests/ui/deprecated.stderr
@@ -1,88 +1,76 @@
-error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon`
-  --> $DIR/deprecated.rs:1:8
-   |
-LL | #[warn(clippy::str_to_string)]
-   |        ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
-
-error: lint `clippy::string_to_string` has been removed: `using `string::to_string` is common even today and specialization will likely happen soon`
-  --> $DIR/deprecated.rs:2:8
-   |
-LL | #[warn(clippy::string_to_string)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: lint `clippy::unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7`
-  --> $DIR/deprecated.rs:3:8
+  --> $DIR/deprecated.rs:1:8
    |
 LL | #[warn(clippy::unstable_as_slice)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
 error: lint `clippy::unstable_as_mut_slice` has been removed: ``Vec::as_mut_slice` has been stabilized in 1.7`
-  --> $DIR/deprecated.rs:4:8
+  --> $DIR/deprecated.rs:2:8
    |
 LL | #[warn(clippy::unstable_as_mut_slice)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::misaligned_transmute` has been removed: `this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr`
-  --> $DIR/deprecated.rs:5:8
+  --> $DIR/deprecated.rs:3:8
    |
 LL | #[warn(clippy::misaligned_transmute)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unused_collect` has been removed: ``collect` has been marked as #[must_use] in rustc and that covers all cases of this lint`
-  --> $DIR/deprecated.rs:6:8
+  --> $DIR/deprecated.rs:4:8
    |
 LL | #[warn(clippy::unused_collect)]
    |        ^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::invalid_ref` has been removed: `superseded by rustc lint `invalid_value``
-  --> $DIR/deprecated.rs:7:8
+  --> $DIR/deprecated.rs:5:8
    |
 LL | #[warn(clippy::invalid_ref)]
    |        ^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::into_iter_on_array` has been removed: `this lint has been uplifted to rustc and is now called `array_into_iter``
-  --> $DIR/deprecated.rs:8:8
+  --> $DIR/deprecated.rs:6:8
    |
 LL | #[warn(clippy::into_iter_on_array)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unused_label` has been removed: `this lint has been uplifted to rustc and is now called `unused_labels``
-  --> $DIR/deprecated.rs:9:8
+  --> $DIR/deprecated.rs:7:8
    |
 LL | #[warn(clippy::unused_label)]
    |        ^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::regex_macro` has been removed: `the regex! macro has been removed from the regex crate in 2018`
-  --> $DIR/deprecated.rs:10:8
+  --> $DIR/deprecated.rs:8:8
    |
 LL | #[warn(clippy::regex_macro)]
    |        ^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::drop_bounds` has been removed: `this lint has been uplifted to rustc and is now called `drop_bounds``
-  --> $DIR/deprecated.rs:11:8
+  --> $DIR/deprecated.rs:9:8
    |
 LL | #[warn(clippy::drop_bounds)]
    |        ^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::temporary_cstring_as_ptr` has been removed: `this lint has been uplifted to rustc and is now called `temporary_cstring_as_ptr``
-  --> $DIR/deprecated.rs:12:8
+  --> $DIR/deprecated.rs:10:8
    |
 LL | #[warn(clippy::temporary_cstring_as_ptr)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::panic_params` has been removed: `this lint has been uplifted to rustc and is now called `panic_fmt``
-  --> $DIR/deprecated.rs:13:8
+  --> $DIR/deprecated.rs:11:8
    |
 LL | #[warn(clippy::panic_params)]
    |        ^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon`
+error: lint `clippy::unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7`
   --> $DIR/deprecated.rs:1:8
    |
-LL | #[warn(clippy::str_to_string)]
-   |        ^^^^^^^^^^^^^^^^^^^^^
+LL | #[warn(clippy::unstable_as_slice)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 14 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/tests/ui/deprecated_old.rs b/tests/ui/deprecated_old.rs
index 2e5c5b7ead1..e89dca4fcfd 100644
--- a/tests/ui/deprecated_old.rs
+++ b/tests/ui/deprecated_old.rs
@@ -1,5 +1,3 @@
-#[warn(str_to_string)]
-#[warn(string_to_string)]
 #[warn(unstable_as_slice)]
 #[warn(unstable_as_mut_slice)]
 #[warn(misaligned_transmute)]
diff --git a/tests/ui/deprecated_old.stderr b/tests/ui/deprecated_old.stderr
index ff3e9e8fcf3..2fe1facf0c7 100644
--- a/tests/ui/deprecated_old.stderr
+++ b/tests/ui/deprecated_old.stderr
@@ -1,40 +1,28 @@
-error: lint `str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon`
-  --> $DIR/deprecated_old.rs:1:8
-   |
-LL | #[warn(str_to_string)]
-   |        ^^^^^^^^^^^^^
-   |
-   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
-
-error: lint `string_to_string` has been removed: `using `string::to_string` is common even today and specialization will likely happen soon`
-  --> $DIR/deprecated_old.rs:2:8
-   |
-LL | #[warn(string_to_string)]
-   |        ^^^^^^^^^^^^^^^^
-
 error: lint `unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7`
-  --> $DIR/deprecated_old.rs:3:8
+  --> $DIR/deprecated_old.rs:1:8
    |
 LL | #[warn(unstable_as_slice)]
    |        ^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
 error: lint `unstable_as_mut_slice` has been removed: ``Vec::as_mut_slice` has been stabilized in 1.7`
-  --> $DIR/deprecated_old.rs:4:8
+  --> $DIR/deprecated_old.rs:2:8
    |
 LL | #[warn(unstable_as_mut_slice)]
    |        ^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `misaligned_transmute` has been removed: `this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr`
-  --> $DIR/deprecated_old.rs:5:8
+  --> $DIR/deprecated_old.rs:3:8
    |
 LL | #[warn(misaligned_transmute)]
    |        ^^^^^^^^^^^^^^^^^^^^
 
-error: lint `str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon`
+error: lint `unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7`
   --> $DIR/deprecated_old.rs:1:8
    |
-LL | #[warn(str_to_string)]
-   |        ^^^^^^^^^^^^^
+LL | #[warn(unstable_as_slice)]
+   |        ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/str_to_string.rs b/tests/ui/str_to_string.rs
new file mode 100644
index 00000000000..08f73402518
--- /dev/null
+++ b/tests/ui/str_to_string.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::str_to_string)]
+
+fn main() {
+    let hello = "hello world".to_string();
+    let msg = &hello[..];
+    msg.to_string();
+}
diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr
new file mode 100644
index 00000000000..b1f73eda5d2
--- /dev/null
+++ b/tests/ui/str_to_string.stderr
@@ -0,0 +1,19 @@
+error: `to_string()` called on a `&str`
+  --> $DIR/str_to_string.rs:4:17
+   |
+LL |     let hello = "hello world".to_string();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::str-to-string` implied by `-D warnings`
+   = help: consider using `.to_owned()`
+
+error: `to_string()` called on a `&str`
+  --> $DIR/str_to_string.rs:6:5
+   |
+LL |     msg.to_string();
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: consider using `.to_owned()`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/string_to_string.rs b/tests/ui/string_to_string.rs
new file mode 100644
index 00000000000..4c66855f709
--- /dev/null
+++ b/tests/ui/string_to_string.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::string_to_string)]
+#![allow(clippy::redundant_clone)]
+
+fn main() {
+    let mut message = String::from("Hello");
+    let mut v = message.to_string();
+}
diff --git a/tests/ui/string_to_string.stderr b/tests/ui/string_to_string.stderr
new file mode 100644
index 00000000000..1ebd17999bd
--- /dev/null
+++ b/tests/ui/string_to_string.stderr
@@ -0,0 +1,11 @@
+error: `to_string()` called on a `String`
+  --> $DIR/string_to_string.rs:6:17
+   |
+LL |     let mut v = message.to_string();
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::string-to-string` implied by `-D warnings`
+   = help: consider using `.clone()`
+
+error: aborting due to previous error
+