about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorMichael Wright <mikerite@lavabit.com>2022-09-03 17:00:44 +0200
committerMichael Wright <mikerite@lavabit.com>2022-09-03 17:00:44 +0200
commit750a2d57bde6fca3bbd856410fe4fb54c4c068dc (patch)
tree2908bbab43b0bb6ac472f00a3a89b807b1615bd8 /tests
parent99ab5fe53a421e0ae3f1d922442fb994bcfcaf24 (diff)
downloadrust-750a2d57bde6fca3bbd856410fe4fb54c4c068dc.tar.gz
rust-750a2d57bde6fca3bbd856410fe4fb54c4c068dc.zip
Fix `unnecessary_to_owned` false positive
Fixes #9351.

Note that this commit reworks that fix for #9317. The change
is to check that the type implements `AsRef<str>` before regarding
`to_string` as an equivalent of `to_owned`. This was suggested
by Jarcho in the #9317 issue comments.

The benefit of this is that it moves some complexity out of
`check_other_call_arg` and simplifies the module as a whole.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/unnecessary_to_owned.fixed60
-rw-r--r--tests/ui/unnecessary_to_owned.rs60
-rw-r--r--tests/ui/unnecessary_to_owned.stderr8
3 files changed, 127 insertions, 1 deletions
diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed
index 9cd5bc73b1e..a920c63b199 100644
--- a/tests/ui/unnecessary_to_owned.fixed
+++ b/tests/ui/unnecessary_to_owned.fixed
@@ -357,3 +357,63 @@ mod issue_9317 {
         consume(b.to_string());
     }
 }
+
+mod issue_9351 {
+    #![allow(dead_code)]
+
+    use std::ops::Deref;
+    use std::path::{Path, PathBuf};
+
+    fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
+        x
+    }
+
+    fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
+
+    fn id<T: AsRef<str>>(x: T) -> T {
+        x
+    }
+
+    fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
+
+    // Should lint
+    fn single_return() -> impl AsRef<str> {
+        id("abc")
+    }
+
+    // Should not lint
+    fn multiple_returns(b: bool) -> impl AsRef<str> {
+        if b {
+            return String::new();
+        }
+
+        id("abc".to_string())
+    }
+
+    struct S1(String);
+
+    // Should not lint
+    fn fields1() -> S1 {
+        S1(id("abc".to_string()))
+    }
+
+    struct S2 {
+        s: String,
+    }
+
+    // Should not lint
+    fn fields2() {
+        let mut s = S2 { s: "abc".into() };
+        s.s = id("abc".to_string());
+    }
+
+    pub fn main() {
+        let path = std::path::Path::new("x");
+        let path_buf = path.to_owned();
+
+        // Should not lint.
+        let _x: PathBuf = require_deref_path(path.to_owned());
+        generic_arg_used_elsewhere(path.to_owned(), path_buf);
+        predicates_are_satisfied(id("abc".to_string()));
+    }
+}
diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs
index 7f62ba3ab5d..2128bdacdda 100644
--- a/tests/ui/unnecessary_to_owned.rs
+++ b/tests/ui/unnecessary_to_owned.rs
@@ -357,3 +357,63 @@ mod issue_9317 {
         consume(b.to_string());
     }
 }
+
+mod issue_9351 {
+    #![allow(dead_code)]
+
+    use std::ops::Deref;
+    use std::path::{Path, PathBuf};
+
+    fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
+        x
+    }
+
+    fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
+
+    fn id<T: AsRef<str>>(x: T) -> T {
+        x
+    }
+
+    fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
+
+    // Should lint
+    fn single_return() -> impl AsRef<str> {
+        id("abc".to_string())
+    }
+
+    // Should not lint
+    fn multiple_returns(b: bool) -> impl AsRef<str> {
+        if b {
+            return String::new();
+        }
+
+        id("abc".to_string())
+    }
+
+    struct S1(String);
+
+    // Should not lint
+    fn fields1() -> S1 {
+        S1(id("abc".to_string()))
+    }
+
+    struct S2 {
+        s: String,
+    }
+
+    // Should not lint
+    fn fields2() {
+        let mut s = S2 { s: "abc".into() };
+        s.s = id("abc".to_string());
+    }
+
+    pub fn main() {
+        let path = std::path::Path::new("x");
+        let path_buf = path.to_owned();
+
+        // Should not lint.
+        let _x: PathBuf = require_deref_path(path.to_owned());
+        generic_arg_used_elsewhere(path.to_owned(), path_buf);
+        predicates_are_satisfied(id("abc".to_string()));
+    }
+}
diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr
index 243b4599dba..7deb90b06f3 100644
--- a/tests/ui/unnecessary_to_owned.stderr
+++ b/tests/ui/unnecessary_to_owned.stderr
@@ -509,5 +509,11 @@ error: unnecessary use of `to_string`
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
-error: aborting due to 78 previous errors
+error: unnecessary use of `to_string`
+  --> $DIR/unnecessary_to_owned.rs:381:12
+   |
+LL |         id("abc".to_string())
+   |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
+
+error: aborting due to 79 previous errors