Skip to content

Commit c9d6a9a

Browse files
committed
Extend implicit_clone to handle to_string calls
1 parent d92da0f commit c9d6a9a

9 files changed

+43
-14
lines changed

clippy_lints/src/methods/implicit_clone.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,12 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
4040
}
4141

4242
/// Returns true if the named method can be used to clone the receiver.
43-
/// Note that `to_string` is not flagged by `implicit_clone`. So other lints that call
44-
/// `is_clone_like` and that do flag `to_string` must handle it separately. See, e.g.,
45-
/// `is_to_owned_like` in `unnecessary_to_owned.rs`.
4643
pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir::def_id::DefId) -> bool {
4744
match method_name {
4845
"to_os_string" => is_diag_item_method(cx, method_def_id, sym::OsStr),
4946
"to_owned" => is_diag_trait_item(cx, method_def_id, sym::ToOwned),
5047
"to_path_buf" => is_diag_item_method(cx, method_def_id, sym::Path),
48+
"to_string" => is_diag_trait_item(cx, method_def_id, sym::ToString),
5149
"to_vec" => cx
5250
.tcx
5351
.impl_of_method(method_def_id)

clippy_lints/src/methods/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5372,7 +5372,7 @@ impl Methods {
53725372
implicit_clone::check(cx, name, expr, recv);
53735373
}
53745374
},
5375-
("to_os_string" | "to_path_buf" | "to_vec", []) => {
5375+
("to_os_string" | "to_path_buf" | "to_string" | "to_vec", []) => {
53765376
implicit_clone::check(cx, name, expr, recv);
53775377
},
53785378
("type_id", []) => {

clippy_lints/src/methods/unnecessary_to_owned.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,8 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id:
618618
/// Returns true if the named method can be used to convert the receiver to its "owned"
619619
/// representation.
620620
fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool {
621-
is_clone_like(cx, method_name.as_str(), method_def_id)
622-
|| is_cow_into_owned(cx, method_name, method_def_id)
621+
is_cow_into_owned(cx, method_name, method_def_id)
622+
|| (method_name != sym::to_string && is_clone_like(cx, method_name.as_str(), method_def_id))
623623
|| is_to_string_on_string_like(cx, call_expr, method_name, method_def_id)
624624
}
625625

tests/ui/implicit_clone.fixed

+6
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,10 @@ fn main() {
135135
}
136136
let no_clone = &NoClone;
137137
let _ = no_clone.to_owned();
138+
139+
let s = String::from("foo");
140+
let _ = s.clone();
141+
//~^ implicit_clone
142+
let _ = s.clone();
143+
//~^ implicit_clone
138144
}

tests/ui/implicit_clone.rs

+6
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,10 @@ fn main() {
135135
}
136136
let no_clone = &NoClone;
137137
let _ = no_clone.to_owned();
138+
139+
let s = String::from("foo");
140+
let _ = s.to_owned();
141+
//~^ implicit_clone
142+
let _ = s.to_string();
143+
//~^ implicit_clone
138144
}

tests/ui/implicit_clone.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,17 @@ error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenc
6767
LL | let _ = pathbuf_ref.to_path_buf();
6868
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`
6969

70-
error: aborting due to 11 previous errors
70+
error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
71+
--> tests/ui/implicit_clone.rs:140:13
72+
|
73+
LL | let _ = s.to_owned();
74+
| ^^^^^^^^^^^^ help: consider using: `s.clone()`
75+
76+
error: implicitly cloning a `String` by calling `to_string` on its dereferenced type
77+
--> tests/ui/implicit_clone.rs:142:13
78+
|
79+
LL | let _ = s.to_string();
80+
| ^^^^^^^^^^^^^ help: consider using: `s.clone()`
81+
82+
error: aborting due to 13 previous errors
7183

tests/ui/string_to_string.fixed

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![warn(clippy::implicit_clone)]
2+
#![allow(clippy::redundant_clone)]
3+
4+
fn main() {
5+
let mut message = String::from("Hello");
6+
let mut v = message.clone();
7+
//~^ ERROR: implicitly cloning a `String` by calling `to_string` on its dereferenced type
8+
}

tests/ui/string_to_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#![warn(clippy::string_to_string)]
1+
#![warn(clippy::implicit_clone)]
22
#![allow(clippy::redundant_clone)]
33

44
fn main() {
55
let mut message = String::from("Hello");
66
let mut v = message.to_string();
7-
//~^ string_to_string
7+
//~^ ERROR: implicitly cloning a `String` by calling `to_string` on its dereferenced type
88
}

tests/ui/string_to_string.stderr

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
error: `to_string()` called on a `String`
1+
error: implicitly cloning a `String` by calling `to_string` on its dereferenced type
22
--> tests/ui/string_to_string.rs:6:17
33
|
44
LL | let mut v = message.to_string();
5-
| ^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `message.clone()`
66
|
7-
= help: consider using `.clone()`
8-
= note: `-D clippy::string-to-string` implied by `-D warnings`
9-
= help: to override `-D warnings` add `#[allow(clippy::string_to_string)]`
7+
= note: `-D clippy::implicit-clone` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]`
109

1110
error: aborting due to 1 previous error
1211

0 commit comments

Comments
 (0)