3 #![allow(clippy::needless_borrow, clippy::ptr_arg)]
4 #![warn(clippy::unnecessary_to_owned)]
7 use std::ffi::{CStr, CString, OsStr, OsString};
15 fn deref(&self) -> &[u8] {
20 impl AsRef<str> for X {
21 fn as_ref(&self) -> &str {
27 fn to_string(&self) -> String {
33 fn join(&self, other: impl AsRef<str>) -> Self {
34 let mut s = self.0.clone();
35 s.push_str(other.as_ref());
49 let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();
50 let os_str = OsStr::new("x");
51 let path = std::path::Path::new("x");
54 let array_ref = &["x"];
55 let slice = &["x"][..];
56 let x = X(String::from("x"));
59 require_c_str(&Cow::from(c_str));
62 require_os_str(os_str);
63 require_os_str(&Cow::from(os_str));
64 require_os_str(os_str);
67 require_path(&Cow::from(path));
71 require_str(&Cow::from(s));
73 require_str(x_ref.as_ref());
76 require_slice(&Cow::from(slice));
77 require_slice(array.as_ref());
78 require_slice(array_ref.as_ref());
80 require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.
82 require_x(&Cow::<X>::Owned(x.clone()));
83 require_x(&x_ref.to_owned()); // No longer flagged because of #8759.
85 require_deref_c_str(c_str);
86 require_deref_os_str(os_str);
87 require_deref_path(path);
89 require_deref_slice(slice);
91 require_impl_deref_c_str(c_str);
92 require_impl_deref_os_str(os_str);
93 require_impl_deref_path(path);
94 require_impl_deref_str(s);
95 require_impl_deref_slice(slice);
97 require_deref_str_slice(s, slice);
98 require_deref_slice_str(slice, s);
100 require_as_ref_c_str(c_str);
101 require_as_ref_os_str(os_str);
102 require_as_ref_path(path);
103 require_as_ref_str(s);
104 require_as_ref_str(&x);
105 require_as_ref_slice(array);
106 require_as_ref_slice(array_ref);
107 require_as_ref_slice(slice);
109 require_impl_as_ref_c_str(c_str);
110 require_impl_as_ref_os_str(os_str);
111 require_impl_as_ref_path(path);
112 require_impl_as_ref_str(s);
113 require_impl_as_ref_str(&x);
114 require_impl_as_ref_slice(array);
115 require_impl_as_ref_slice(array_ref);
116 require_impl_as_ref_slice(slice);
118 require_as_ref_str_slice(s, array);
119 require_as_ref_str_slice(s, array_ref);
120 require_as_ref_str_slice(s, slice);
121 require_as_ref_slice_str(array, s);
122 require_as_ref_slice_str(array_ref, s);
123 require_as_ref_slice_str(slice, s);
125 let _ = x.join(x_ref);
127 let _ = slice.iter().copied();
128 let _ = slice.iter().copied();
129 let _ = [std::path::PathBuf::new()][..].iter().cloned();
130 let _ = [std::path::PathBuf::new()][..].iter().cloned();
132 let _ = slice.iter().copied();
133 let _ = slice.iter().copied();
134 let _ = [std::path::PathBuf::new()][..].iter().cloned();
135 let _ = [std::path::PathBuf::new()][..].iter().cloned();
137 let _ = check_files(&[FileType::Account]);
140 require_string(&s.to_string());
141 require_string(&Cow::from(s).into_owned());
142 require_string(&s.to_owned());
143 require_string(&x_ref.to_string());
146 require_slice(&x.to_owned());
147 require_deref_slice(x.to_owned());
149 // The following should be flagged by `redundant_clone`, but not by this lint.
150 require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap());
151 require_os_str(&OsString::from("x"));
152 require_path(&std::path::PathBuf::from("x"));
153 require_str(&String::from("x"));
154 require_slice(&[String::from("x")]);
157 fn require_c_str(_: &CStr) {}
158 fn require_os_str(_: &OsStr) {}
159 fn require_path(_: &std::path::Path) {}
160 fn require_str(_: &str) {}
161 fn require_slice<T>(_: &[T]) {}
162 fn require_x(_: &X) {}
164 fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}
165 fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}
166 fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}
167 fn require_deref_str<T: Deref<Target = str>>(_: T) {}
168 fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}
170 fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}
171 fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}
172 fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}
173 fn require_impl_deref_str(_: impl Deref<Target = str>) {}
174 fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}
176 fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}
177 fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}
179 fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}
180 fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}
181 fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}
182 fn require_as_ref_str<T: AsRef<str>>(_: T) {}
183 fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}
185 fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}
186 fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}
187 fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}
188 fn require_impl_as_ref_str(_: impl AsRef<str>) {}
189 fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}
191 fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}
192 fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}
194 // `check_files` is based on:
195 // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
196 fn check_files(file_types: &[FileType]) -> bool {
197 for t in file_types {
198 let path = match get_file_path(t) {
211 fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
212 Ok(std::path::PathBuf::new())
215 fn require_string(_: &String) {}
217 #[clippy::msrv = "1.35"]
219 // `copied` was stabilized in 1.36, so clippy should use `cloned`.
220 let _ = &["x"][..].iter().cloned();
223 #[clippy::msrv = "1.36"]
225 let _ = &["x"][..].iter().copied();
228 // https://github.com/rust-lang/rust-clippy/issues/8507
234 pub trait Abstracted {}
236 impl<P> Abstracted for Opaque<P> {}
238 fn build<P>(p: P) -> Opaque<P>
246 fn test_str(s: &str) -> Box<dyn Abstracted> {
247 Box::new(build(s.to_string()))
251 fn test_x(x: super::X) -> Box<dyn Abstracted> {
255 #[derive(Clone, Copy)]
256 struct Y(&'static str);
258 impl AsRef<str> for Y {
259 fn as_ref(&self) -> &str {
264 impl ToString for Y {
265 fn to_string(&self) -> String {
270 // Should lint because Y is copy.
271 fn test_y(y: Y) -> Box<dyn Abstracted> {
276 // https://github.com/rust-lang/rust-clippy/issues/8759
283 impl std::borrow::ToOwned for View {
285 fn to_owned(&self) -> Self::Owned {
291 struct RenderWindow {
296 fn default_view(&self) -> &View {
299 fn set_view(&mut self, _view: &View) {}
303 let mut rw = RenderWindow::default();
304 rw.set_view(&rw.default_view().to_owned());
308 mod issue_8759_variant {
311 #[derive(Clone, Default)]
315 struct RenderWindow {
320 fn default_view(&self) -> &View {
323 fn set_view(&mut self, _view: &View) {}
327 let mut rw = RenderWindow::default();
328 rw.set_view(&rw.default_view().to_owned());
337 impl ToString for Bytes {
338 fn to_string(&self) -> String {
343 impl AsRef<[u8]> for Bytes {
344 fn as_ref(&self) -> &[u8] {
349 fn consume<C: AsRef<[u8]>>(c: C) {
356 consume(b.to_string());
364 use std::path::{Path, PathBuf};
366 fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
370 fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
372 fn id<T: AsRef<str>>(x: T) -> T {
376 fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
379 fn single_return() -> impl AsRef<str> {
384 fn multiple_returns(b: bool) -> impl AsRef<str> {
386 return String::new();
389 id("abc".to_string())
396 S1(id("abc".to_string()))
405 let mut s = S2 { s: "abc".into() };
406 s.s = id("abc".to_string());
410 let path = std::path::Path::new("x");
411 let path_buf = path.to_owned();
414 let _x: PathBuf = require_deref_path(path.to_owned());
415 generic_arg_used_elsewhere(path.to_owned(), path_buf);
416 predicates_are_satisfied(id("abc".to_string()));
423 async fn foo<S: AsRef<str>>(_: S) {}
425 foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
432 use std::marker::PhantomData;
434 pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
436 impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
437 pub fn new(key: K) -> Key<K, V> {
438 Key(key, PhantomData)
442 pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
443 Key::new([b"pkh-", pkh].concat().to_vec())
450 pub struct Key<K: AsRef<[u8]>>(K);
452 pub fn from(c: &[u8]) -> Key<Vec<u8>> {
453 let v = [c].concat();