diff options
| author | bors <bors@rust-lang.org> | 2021-12-15 10:46:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-12-15 10:46:43 +0000 |
| commit | 40fd785199d80a06c1a1664d64209f78343c0e05 (patch) | |
| tree | fa0c4f45b7d51dc4d4d3b158e78fbcc59d9c56eb /tests | |
| parent | aa3648af504389ece9c5e09b848b450edad3ac38 (diff) | |
| parent | b8913894a13431bea99400dc9f53a1fd9f41a6c6 (diff) | |
Auto merge of #7978 - smoelius:master, r=llogiq
Add `unnecessary_to_owned` lint
This PR adds a lint to check for unnecessary calls to `ToOwned::to_owned` and other similar functions (e.g., `Cow::into_owned`, `ToString::to_string`, etc.).
The lint checks for expressions of the form `&receiver.to_owned_like()` used in a position requiring type `&T` where one of the following is true:
* `receiver`'s type is `T` exactly
* `receiver`'s type implements `Deref<Target = T>`
* `receiver`'s type implements `AsRef<T>`
The lint additionally checks for expressions of the form `receiver.to_owned_like()` used as arguments of type `impl AsRef<T>`.
It would be nice if the lint could also check for expressions used as arguments to functions like the following:
```
fn foo<T: AsRef<str>>(x: T) { ... }
```
However, I couldn't figure out how to determine whether a function input type was instantiated from a parameter with a trait bound.
If someone could offer me some guidance, I would be happy to add such functionality.
Closes #7933
changelog: Add [`unnecessary_to_owned`] lint
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/unnecessary_iter_cloned.fixed | 142 | ||||
| -rw-r--r-- | tests/ui/unnecessary_iter_cloned.rs | 142 | ||||
| -rw-r--r-- | tests/ui/unnecessary_iter_cloned.stderr | 35 | ||||
| -rw-r--r-- | tests/ui/unnecessary_to_owned.fixed | 214 | ||||
| -rw-r--r-- | tests/ui/unnecessary_to_owned.rs | 214 | ||||
| -rw-r--r-- | tests/ui/unnecessary_to_owned.stderr | 495 |
6 files changed, 1242 insertions, 0 deletions
diff --git a/tests/ui/unnecessary_iter_cloned.fixed b/tests/ui/unnecessary_iter_cloned.fixed new file mode 100644 index 00000000000..e01e9f07baf --- /dev/null +++ b/tests/ui/unnecessary_iter_cloned.fixed @@ -0,0 +1,142 @@ +// run-rustfix + +#![allow(unused_assignments)] +#![warn(clippy::unnecessary_to_owned)] + +#[allow(dead_code)] +#[derive(Clone, Copy)] +enum FileType { + Account, + PrivateKey, + Certificate, +} + +fn main() { + let path = std::path::Path::new("x"); + + let _ = check_files(&[(FileType::Account, path)]); + let _ = check_files_vec(vec![(FileType::Account, path)]); + + // negative tests + let _ = check_files_ref(&[(FileType::Account, path)]); + let _ = check_files_mut(&[(FileType::Account, path)]); + let _ = check_files_ref_mut(&[(FileType::Account, path)]); + let _ = check_files_self_and_arg(&[(FileType::Account, path)]); + let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]); +} + +// `check_files` and its variants are based on: +// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 +fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { + for (t, path) in files { + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { + for (t, path) in files.iter() { + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool { + for (ref t, path) in files.iter().copied() { + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +#[allow(unused_assignments)] +fn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool { + for (mut t, path) in files.iter().copied() { + t = FileType::PrivateKey; + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool { + for (ref mut t, path) in files.iter().copied() { + *t = FileType::PrivateKey; + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool { + for (t, path) in files.iter().copied() { + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.join(path).is_file() || !other.is_file() { + return false; + } + } + true +} + +#[allow(unused_assignments)] +fn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool { + for (mut t, path) in files.iter().cloned() { + t = FileType::PrivateKey; + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> { + Ok(std::path::PathBuf::new()) +} diff --git a/tests/ui/unnecessary_iter_cloned.rs b/tests/ui/unnecessary_iter_cloned.rs new file mode 100644 index 00000000000..6ef2966c8b7 --- /dev/null +++ b/tests/ui/unnecessary_iter_cloned.rs @@ -0,0 +1,142 @@ +// run-rustfix + +#![allow(unused_assignments)] +#![warn(clippy::unnecessary_to_owned)] + +#[allow(dead_code)] +#[derive(Clone, Copy)] +enum FileType { + Account, + PrivateKey, + Certificate, +} + +fn main() { + let path = std::path::Path::new("x"); + + let _ = check_files(&[(FileType::Account, path)]); + let _ = check_files_vec(vec![(FileType::Account, path)]); + + // negative tests + let _ = check_files_ref(&[(FileType::Account, path)]); + let _ = check_files_mut(&[(FileType::Account, path)]); + let _ = check_files_ref_mut(&[(FileType::Account, path)]); + let _ = check_files_self_and_arg(&[(FileType::Account, path)]); + let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]); +} + +// `check_files` and its variants are based on: +// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 +fn check_files(files: &[(FileType, &std::path::Path)]) -> bool { + for (t, path) in files.iter().copied() { + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool { + for (t, path) in files.iter().copied() { + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool { + for (ref t, path) in files.iter().copied() { + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +#[allow(unused_assignments)] +fn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool { + for (mut t, path) in files.iter().copied() { + t = FileType::PrivateKey; + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool { + for (ref mut t, path) in files.iter().copied() { + *t = FileType::PrivateKey; + let other = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool { + for (t, path) in files.iter().copied() { + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.join(path).is_file() || !other.is_file() { + return false; + } + } + true +} + +#[allow(unused_assignments)] +fn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool { + for (mut t, path) in files.iter().cloned() { + t = FileType::PrivateKey; + let other = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() || !other.is_file() { + return false; + } + } + true +} + +fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> { + Ok(std::path::PathBuf::new()) +} diff --git a/tests/ui/unnecessary_iter_cloned.stderr b/tests/ui/unnecessary_iter_cloned.stderr new file mode 100644 index 00000000000..e44379f8aa0 --- /dev/null +++ b/tests/ui/unnecessary_iter_cloned.stderr @@ -0,0 +1,35 @@ +error: unnecessary use of `copied` + --> $DIR/unnecessary_iter_cloned.rs:31:22 + | +LL | for (t, path) in files.iter().copied() { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings` +help: use + | +LL | for (t, path) in files { + | ~~~~~ +help: remove this `&` + | +LL - let other = match get_file_path(&t) { +LL + let other = match get_file_path(t) { + | + +error: unnecessary use of `copied` + --> $DIR/unnecessary_iter_cloned.rs:46:22 + | +LL | for (t, path) in files.iter().copied() { + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for (t, path) in files.iter() { + | ~~~~~~~~~~~~ +help: remove this `&` + | +LL - let other = match get_file_path(&t) { +LL + let other = match get_file_path(t) { + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed new file mode 100644 index 00000000000..720138db137 --- /dev/null +++ b/tests/ui/unnecessary_to_owned.fixed @@ -0,0 +1,214 @@ +// run-rustfix + +#![allow(clippy::ptr_arg)] +#![warn(clippy::unnecessary_to_owned)] + +use std::borrow::Cow; +use std::ffi::{CStr, CString, OsStr, OsString}; +use std::ops::Deref; + +#[derive(Clone)] +struct X(String); + +impl Deref for X { + type Target = [u8]; + fn deref(&self) -> &[u8] { + self.0.as_bytes() + } +} + +impl AsRef<str> for X { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} + +impl ToString for X { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +impl X { + fn join(&self, other: impl AsRef<str>) -> Self { + let mut s = self.0.clone(); + s.push_str(other.as_ref()); + Self(s) + } +} + +#[allow(dead_code)] +#[derive(Clone)] +enum FileType { + Account, + PrivateKey, + Certificate, +} + +fn main() { + let c_str = CStr::from_bytes_with_nul(&[0]).unwrap(); + let os_str = OsStr::new("x"); + let path = std::path::Path::new("x"); + let s = "x"; + let array = ["x"]; + let array_ref = &["x"]; + let slice = &["x"][..]; + let x = X(String::from("x")); + let x_ref = &x; + + require_c_str(&Cow::from(c_str)); + require_c_str(c_str); + + require_os_str(os_str); + require_os_str(&Cow::from(os_str)); + require_os_str(os_str); + + require_path(path); + require_path(&Cow::from(path)); + require_path(path); + + require_str(s); + require_str(&Cow::from(s)); + require_str(s); + require_str(x_ref.as_ref()); + + require_slice(slice); + require_slice(&Cow::from(slice)); + require_slice(array.as_ref()); + require_slice(array_ref.as_ref()); + require_slice(slice); + require_slice(x_ref); + + require_x(&Cow::<X>::Owned(x.clone())); + require_x(x_ref); + + require_deref_c_str(c_str); + require_deref_os_str(os_str); + require_deref_path(path); + require_deref_str(s); + require_deref_slice(slice); + + require_impl_deref_c_str(c_str); + require_impl_deref_os_str(os_str); + require_impl_deref_path(path); + require_impl_deref_str(s); + require_impl_deref_slice(slice); + + require_deref_str_slice(s, slice); + require_deref_slice_str(slice, s); + + require_as_ref_c_str(c_str); + require_as_ref_os_str(os_str); + require_as_ref_path(path); + require_as_ref_str(s); + require_as_ref_str(&x); + require_as_ref_slice(array); + require_as_ref_slice(array_ref); + require_as_ref_slice(slice); + + require_impl_as_ref_c_str(c_str); + require_impl_as_ref_os_str(os_str); + require_impl_as_ref_path(path); + require_impl_as_ref_str(s); + require_impl_as_ref_str(&x); + require_impl_as_ref_slice(array); + require_impl_as_ref_slice(array_ref); + require_impl_as_ref_slice(slice); + + require_as_ref_str_slice(s, array); + require_as_ref_str_slice(s, array_ref); + require_as_ref_str_slice(s, slice); + require_as_ref_slice_str(array, s); + require_as_ref_slice_str(array_ref, s); + require_as_ref_slice_str(slice, s); + + let _ = x.join(x_ref); + + let _ = slice.iter().copied(); + let _ = slice.iter().copied(); + let _ = [std::path::PathBuf::new()][..].iter().cloned(); + let _ = [std::path::PathBuf::new()][..].iter().cloned(); + + let _ = slice.iter().copied(); + let _ = slice.iter().copied(); + let _ = [std::path::PathBuf::new()][..].iter().cloned(); + let _ = [std::path::PathBuf::new()][..].iter().cloned(); + + let _ = check_files(&[FileType::Account]); + + // negative tests + require_string(&s.to_string()); + require_string(&Cow::from(s).into_owned()); + require_string(&s.to_owned()); + require_string(&x_ref.to_string()); + + // `X` isn't copy. + require_slice(&x.to_owned()); + require_deref_slice(x.to_owned()); + + // The following should be flagged by `redundant_clone`, but not by this lint. + require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap()); + require_os_str(&OsString::from("x")); + require_path(&std::path::PathBuf::from("x")); + require_str(&String::from("x")); +} + +fn require_c_str(_: &CStr) {} +fn require_os_str(_: &OsStr) {} +fn require_path(_: &std::path::Path) {} +fn require_str(_: &str) {} +fn require_slice<T>(_: &[T]) {} +fn require_x(_: &X) {} + +fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {} +fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {} +fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {} +fn require_deref_str<T: Deref<Target = str>>(_: T) {} +fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {} + +fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {} +fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {} +fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {} +fn require_impl_deref_str(_: impl Deref<Target = str>) {} +fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {} + +fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {} +fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {} + +fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {} +fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {} +fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {} +fn require_as_ref_str<T: AsRef<str>>(_: T) {} +fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {} + +fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {} +fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {} +fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {} +fn require_impl_as_ref_str(_: impl AsRef<str>) {} +fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {} + +fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {} +fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {} + +// `check_files` is based on: +// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 +fn check_files(file_types: &[FileType]) -> bool { + for t in file_types { + let path = match get_file_path(t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() { + return false; + } + } + true +} + +fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> { + Ok(std::path::PathBuf::new()) +} + +fn require_string(_: &String) {} diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs new file mode 100644 index 00000000000..60b2e718f5d --- /dev/null +++ b/tests/ui/unnecessary_to_owned.rs @@ -0,0 +1,214 @@ +// run-rustfix + +#![allow(clippy::ptr_arg)] +#![warn(clippy::unnecessary_to_owned)] + +use std::borrow::Cow; +use std::ffi::{CStr, CString, OsStr, OsString}; +use std::ops::Deref; + +#[derive(Clone)] +struct X(String); + +impl Deref for X { + type Target = [u8]; + fn deref(&self) -> &[u8] { + self.0.as_bytes() + } +} + +impl AsRef<str> for X { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} + +impl ToString for X { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +impl X { + fn join(&self, other: impl AsRef<str>) -> Self { + let mut s = self.0.clone(); + s.push_str(other.as_ref()); + Self(s) + } +} + +#[allow(dead_code)] +#[derive(Clone)] +enum FileType { + Account, + PrivateKey, + Certificate, +} + +fn main() { + let c_str = CStr::from_bytes_with_nul(&[0]).unwrap(); + let os_str = OsStr::new("x"); + let path = std::path::Path::new("x"); + let s = "x"; + let array = ["x"]; + let array_ref = &["x"]; + let slice = &["x"][..]; + let x = X(String::from("x")); + let x_ref = &x; + + require_c_str(&Cow::from(c_str).into_owned()); + require_c_str(&c_str.to_owned()); + + require_os_str(&os_str.to_os_string()); + require_os_str(&Cow::from(os_str).into_owned()); + require_os_str(&os_str.to_owned()); + + require_path(&path.to_path_buf()); + require_path(&Cow::from(path).into_owned()); + require_path(&path.to_owned()); + + require_str(&s.to_string()); + require_str(&Cow::from(s).into_owned()); + require_str(&s.to_owned()); + require_str(&x_ref.to_string()); + + require_slice(&slice.to_vec()); + require_slice(&Cow::from(slice).into_owned()); + require_slice(&array.to_owned()); + require_slice(&array_ref.to_owned()); + require_slice(&slice.to_owned()); + require_slice(&x_ref.to_owned()); + + require_x(&Cow::<X>::Owned(x.clone()).into_owned()); + require_x(&x_ref.to_owned()); + + require_deref_c_str(c_str.to_owned()); + require_deref_os_str(os_str.to_owned()); + require_deref_path(path.to_owned()); + require_deref_str(s.to_owned()); + require_deref_slice(slice.to_owned()); + + require_impl_deref_c_str(c_str.to_owned()); + require_impl_deref_os_str(os_str.to_owned()); + require_impl_deref_path(path.to_owned()); + require_impl_deref_str(s.to_owned()); + require_impl_deref_slice(slice.to_owned()); + + require_deref_str_slice(s.to_owned(), slice.to_owned()); + require_deref_slice_str(slice.to_owned(), s.to_owned()); + + require_as_ref_c_str(c_str.to_owned()); + require_as_ref_os_str(os_str.to_owned()); + require_as_ref_path(path.to_owned()); + require_as_ref_str(s.to_owned()); + require_as_ref_str(x.to_owned()); + require_as_ref_slice(array.to_owned()); + require_as_ref_slice(array_ref.to_owned()); + require_as_ref_slice(slice.to_owned()); + + require_impl_as_ref_c_str(c_str.to_owned()); + require_impl_as_ref_os_str(os_str.to_owned()); + require_impl_as_ref_path(path.to_owned()); + require_impl_as_ref_str(s.to_owned()); + require_impl_as_ref_str(x.to_owned()); + require_impl_as_ref_slice(array.to_owned()); + require_impl_as_ref_slice(array_ref.to_owned()); + require_impl_as_ref_slice(slice.to_owned()); + + require_as_ref_str_slice(s.to_owned(), array.to_owned()); + require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); + require_as_ref_str_slice(s.to_owned(), slice.to_owned()); + require_as_ref_slice_str(array.to_owned(), s.to_owned()); + require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); + require_as_ref_slice_str(slice.to_owned(), s.to_owned()); + + let _ = x.join(&x_ref.to_string()); + + let _ = slice.to_vec().into_iter(); + let _ = slice.to_owned().into_iter(); + let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); + let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); + + let _ = IntoIterator::into_iter(slice.to_vec()); + let _ = IntoIterator::into_iter(slice.to_owned()); + let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); + let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); + + let _ = check_files(&[FileType::Account]); + + // negative tests + require_string(&s.to_string()); + require_string(&Cow::from(s).into_owned()); + require_string(&s.to_owned()); + require_string(&x_ref.to_string()); + + // `X` isn't copy. + require_slice(&x.to_owned()); + require_deref_slice(x.to_owned()); + + // The following should be flagged by `redundant_clone`, but not by this lint. + require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); + require_os_str(&OsString::from("x").to_os_string()); + require_path(&std::path::PathBuf::from("x").to_path_buf()); + require_str(&String::from("x").to_string()); +} + +fn require_c_str(_: &CStr) {} +fn require_os_str(_: &OsStr) {} +fn require_path(_: &std::path::Path) {} +fn require_str(_: &str) {} +fn require_slice<T>(_: &[T]) {} +fn require_x(_: &X) {} + +fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {} +fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {} +fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {} +fn require_deref_str<T: Deref<Target = str>>(_: T) {} +fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {} + +fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {} +fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {} +fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {} +fn require_impl_deref_str(_: impl Deref<Target = str>) {} +fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {} + +fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {} +fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {} + +fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {} +fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {} +fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {} +fn require_as_ref_str<T: AsRef<str>>(_: T) {} +fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {} + +fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {} +fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {} +fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {} +fn require_impl_as_ref_str(_: impl AsRef<str>) {} +fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {} + +fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {} +fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {} + +// `check_files` is based on: +// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262 +fn check_files(file_types: &[FileType]) -> bool { + for t in file_types.to_vec() { + let path = match get_file_path(&t) { + Ok(p) => p, + Err(_) => { + return false; + }, + }; + if !path.is_file() { + return false; + } + } + true +} + +fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> { + Ok(std::path::PathBuf::new()) +} + +fn require_string(_: &String) {} diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr new file mode 100644 index 00000000000..1dfc65e22e2 --- /dev/null +++ b/tests/ui/unnecessary_to_owned.stderr @@ -0,0 +1,495 @@ +error: redundant clone + --> $DIR/unnecessary_to_owned.rs:150:64 + | +LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); + | ^^^^^^^^^^^ help: remove this + | + = note: `-D clippy::redundant-clone` implied by `-D warnings` +note: this value is dropped without further use + --> $DIR/unnecessary_to_owned.rs:150:20 + | +LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant clone + --> $DIR/unnecessary_to_owned.rs:151:40 + | +LL | require_os_str(&OsString::from("x").to_os_string()); + | ^^^^^^^^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> $DIR/unnecessary_to_owned.rs:151:21 + | +LL | require_os_str(&OsString::from("x").to_os_string()); + | ^^^^^^^^^^^^^^^^^^^ + +error: redundant clone + --> $DIR/unnecessary_to_owned.rs:152:48 + | +LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); + | ^^^^^^^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> $DIR/unnecessary_to_owned.rs:152:19 + | +LL | require_path(&std::path::PathBuf::from("x").to_path_buf()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: redundant clone + --> $DIR/unnecessary_to_owned.rs:153:35 + | +LL | require_str(&String::from("x").to_string()); + | ^^^^^^^^^^^^ help: remove this + | +note: this value is dropped without further use + --> $DIR/unnecessary_to_owned.rs:153:18 + | +LL | require_str(&String::from("x").to_string()); + | ^^^^^^^^^^^^^^^^^ + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:59:36 + | +LL | require_c_str(&Cow::from(c_str).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + | + = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:60:19 + | +LL | require_c_str(&c_str.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `c_str` + +error: unnecessary use of `to_os_string` + --> $DIR/unnecessary_to_owned.rs:62:20 + | +LL | require_os_str(&os_str.to_os_string()); + | ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:63:38 + | +LL | require_os_str(&Cow::from(os_str).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:64:20 + | +LL | require_os_str(&os_str.to_owned()); + | ^^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `to_path_buf` + --> $DIR/unnecessary_to_owned.rs:66:18 + | +LL | require_path(&path.to_path_buf()); + | ^^^^^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:67:34 + | +LL | require_path(&Cow::from(path).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:68:18 + | +LL | require_path(&path.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `to_string` + --> $DIR/unnecessary_to_owned.rs:70:17 + | +LL | require_str(&s.to_string()); + | ^^^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:71:30 + | +LL | require_str(&Cow::from(s).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:72:17 + | +LL | require_str(&s.to_owned()); + | ^^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_string` + --> $DIR/unnecessary_to_owned.rs:73:17 + | +LL | require_str(&x_ref.to_string()); + | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:75:19 + | +LL | require_slice(&slice.to_vec()); + | ^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:76:36 + | +LL | require_slice(&Cow::from(slice).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:77:19 + | +LL | require_slice(&array.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:78:19 + | +LL | require_slice(&array_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:79:19 + | +LL | require_slice(&slice.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:80:19 + | +LL | require_slice(&x_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `x_ref` + +error: unnecessary use of `into_owned` + --> $DIR/unnecessary_to_owned.rs:82:42 + | +LL | require_x(&Cow::<X>::Owned(x.clone()).into_owned()); + | ^^^^^^^^^^^^^ help: remove this + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:83:15 + | +LL | require_x(&x_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `x_ref` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:85:25 + | +LL | require_deref_c_str(c_str.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `c_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:86:26 + | +LL | require_deref_os_str(os_str.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:87:24 + | +LL | require_deref_path(path.to_owned()); + | ^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:88:23 + | +LL | require_deref_str(s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:89:25 + | +LL | require_deref_slice(slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:91:30 + | +LL | require_impl_deref_c_str(c_str.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `c_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:92:31 + | +LL | require_impl_deref_os_str(os_str.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:93:29 + | +LL | require_impl_deref_path(path.to_owned()); + | ^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:94:28 + | +LL | require_impl_deref_str(s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:95:30 + | +LL | require_impl_deref_slice(slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:97:29 + | +LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:97:43 + | +LL | require_deref_str_slice(s.to_owned(), slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:98:29 + | +LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:98:47 + | +LL | require_deref_slice_str(slice.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:100:26 + | +LL | require_as_ref_c_str(c_str.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `c_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:101:27 + | +LL | require_as_ref_os_str(os_str.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:102:25 + | +LL | require_as_ref_path(path.to_owned()); + | ^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:103:24 + | +LL | require_as_ref_str(s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:104:24 + | +LL | require_as_ref_str(x.to_owned()); + | ^^^^^^^^^^^^ help: use: `&x` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:105:26 + | +LL | require_as_ref_slice(array.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `array` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:106:26 + | +LL | require_as_ref_slice(array_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:107:26 + | +LL | require_as_ref_slice(slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:109:31 + | +LL | require_impl_as_ref_c_str(c_str.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `c_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:110:32 + | +LL | require_impl_as_ref_os_str(os_str.to_owned()); + | ^^^^^^^^^^^^^^^^^ help: use: `os_str` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:111:30 + | +LL | require_impl_as_ref_path(path.to_owned()); + | ^^^^^^^^^^^^^^^ help: use: `path` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:112:29 + | +LL | require_impl_as_ref_str(s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:113:29 + | +LL | require_impl_as_ref_str(x.to_owned()); + | ^^^^^^^^^^^^ help: use: `&x` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:114:31 + | +LL | require_impl_as_ref_slice(array.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `array` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:115:31 + | +LL | require_impl_as_ref_slice(array_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:116:31 + | +LL | require_impl_as_ref_slice(slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:118:30 + | +LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:118:44 + | +LL | require_as_ref_str_slice(s.to_owned(), array.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `array` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:119:30 + | +LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:119:44 + | +LL | require_as_ref_str_slice(s.to_owned(), array_ref.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:120:30 + | +LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:120:44 + | +LL | require_as_ref_str_slice(s.to_owned(), slice.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:121:30 + | +LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `array` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:121:48 + | +LL | require_as_ref_slice_str(array.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:122:30 + | +LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:122:52 + | +LL | require_as_ref_slice_str(array_ref.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:123:30 + | +LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^^^^^ help: use: `slice` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:123:48 + | +LL | require_as_ref_slice_str(slice.to_owned(), s.to_owned()); + | ^^^^^^^^^^^^ help: use: `s` + +error: unnecessary use of `to_string` + --> $DIR/unnecessary_to_owned.rs:125:20 + | +LL | let _ = x.join(&x_ref.to_string()); + | ^^^^^^^^^^^^^^^^^^ help: use: `x_ref` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:127:13 + | +LL | let _ = slice.to_vec().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:128:13 + | +LL | let _ = slice.to_owned().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:129:13 + | +LL | let _ = [std::path::PathBuf::new()][..].to_vec().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:130:13 + | +LL | let _ = [std::path::PathBuf::new()][..].to_owned().into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:132:13 + | +LL | let _ = IntoIterator::into_iter(slice.to_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:133:13 + | +LL | let _ = IntoIterator::into_iter(slice.to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:134:13 + | +LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` + +error: unnecessary use of `to_owned` + --> $DIR/unnecessary_to_owned.rs:135:13 + | +LL | let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()` + +error: unnecessary use of `to_vec` + --> $DIR/unnecessary_to_owned.rs:196:14 + | +LL | for t in file_types.to_vec() { + | ^^^^^^^^^^^^^^^^^^^ + | +help: use + | +LL | for t in file_types { + | ~~~~~~~~~~ +help: remove this `&` + | +LL - let path = match get_file_path(&t) { +LL + let path = match get_file_path(t) { + | + +error: aborting due to 76 previous errors + |
