3 #![allow(clippy::needless_borrow, clippy::ptr_arg)]
4 #![warn(clippy::unnecessary_to_owned)]
5 #![feature(custom_inner_attributes)]
8 use std
::ffi
::{CStr, CString, OsStr, OsString}
;
16 fn deref(&self) -> &[u8] {
21 impl AsRef
<str> for X
{
22 fn as_ref(&self) -> &str {
28 fn to_string(&self) -> String
{
34 fn join(&self, other
: impl AsRef
<str>) -> Self {
35 let mut s
= self.0.clone();
36 s
.push_str(other
.as_ref());
50 let c_str
= CStr
::from_bytes_with_nul(&[0]).unwrap();
51 let os_str
= OsStr
::new("x");
52 let path
= std
::path
::Path
::new("x");
55 let array_ref
= &["x"];
56 let slice
= &["x"][..];
57 let x
= X(String
::from("x"));
60 require_c_str(&Cow
::from(c_str
).into_owned());
61 require_c_str(&c_str
.to_owned());
63 require_os_str(&os_str
.to_os_string());
64 require_os_str(&Cow
::from(os_str
).into_owned());
65 require_os_str(&os_str
.to_owned());
67 require_path(&path
.to_path_buf());
68 require_path(&Cow
::from(path
).into_owned());
69 require_path(&path
.to_owned());
71 require_str(&s
.to_string());
72 require_str(&Cow
::from(s
).into_owned());
73 require_str(&s
.to_owned());
74 require_str(&x_ref
.to_string());
76 require_slice(&slice
.to_vec());
77 require_slice(&Cow
::from(slice
).into_owned());
78 require_slice(&array
.to_owned());
79 require_slice(&array_ref
.to_owned());
80 require_slice(&slice
.to_owned());
81 require_slice(&x_ref
.to_owned()); // No longer flagged because of #8759.
83 require_x(&Cow
::<X
>::Owned(x
.clone()).into_owned());
84 require_x(&x_ref
.to_owned()); // No longer flagged because of #8759.
86 require_deref_c_str(c_str
.to_owned());
87 require_deref_os_str(os_str
.to_owned());
88 require_deref_path(path
.to_owned());
89 require_deref_str(s
.to_owned());
90 require_deref_slice(slice
.to_owned());
92 require_impl_deref_c_str(c_str
.to_owned());
93 require_impl_deref_os_str(os_str
.to_owned());
94 require_impl_deref_path(path
.to_owned());
95 require_impl_deref_str(s
.to_owned());
96 require_impl_deref_slice(slice
.to_owned());
98 require_deref_str_slice(s
.to_owned(), slice
.to_owned());
99 require_deref_slice_str(slice
.to_owned(), s
.to_owned());
101 require_as_ref_c_str(c_str
.to_owned());
102 require_as_ref_os_str(os_str
.to_owned());
103 require_as_ref_path(path
.to_owned());
104 require_as_ref_str(s
.to_owned());
105 require_as_ref_str(x
.to_owned());
106 require_as_ref_slice(array
.to_owned());
107 require_as_ref_slice(array_ref
.to_owned());
108 require_as_ref_slice(slice
.to_owned());
110 require_impl_as_ref_c_str(c_str
.to_owned());
111 require_impl_as_ref_os_str(os_str
.to_owned());
112 require_impl_as_ref_path(path
.to_owned());
113 require_impl_as_ref_str(s
.to_owned());
114 require_impl_as_ref_str(x
.to_owned());
115 require_impl_as_ref_slice(array
.to_owned());
116 require_impl_as_ref_slice(array_ref
.to_owned());
117 require_impl_as_ref_slice(slice
.to_owned());
119 require_as_ref_str_slice(s
.to_owned(), array
.to_owned());
120 require_as_ref_str_slice(s
.to_owned(), array_ref
.to_owned());
121 require_as_ref_str_slice(s
.to_owned(), slice
.to_owned());
122 require_as_ref_slice_str(array
.to_owned(), s
.to_owned());
123 require_as_ref_slice_str(array_ref
.to_owned(), s
.to_owned());
124 require_as_ref_slice_str(slice
.to_owned(), s
.to_owned());
126 let _
= x
.join(&x_ref
.to_string());
128 let _
= slice
.to_vec().into_iter();
129 let _
= slice
.to_owned().into_iter();
130 let _
= [std
::path
::PathBuf
::new()][..].to_vec().into_iter();
131 let _
= [std
::path
::PathBuf
::new()][..].to_owned().into_iter();
133 let _
= IntoIterator
::into_iter(slice
.to_vec());
134 let _
= IntoIterator
::into_iter(slice
.to_owned());
135 let _
= IntoIterator
::into_iter([std
::path
::PathBuf
::new()][..].to_vec());
136 let _
= IntoIterator
::into_iter([std
::path
::PathBuf
::new()][..].to_owned());
138 let _
= check_files(&[FileType
::Account
]);
141 require_string(&s
.to_string());
142 require_string(&Cow
::from(s
).into_owned());
143 require_string(&s
.to_owned());
144 require_string(&x_ref
.to_string());
147 require_slice(&x
.to_owned());
148 require_deref_slice(x
.to_owned());
150 // The following should be flagged by `redundant_clone`, but not by this lint.
151 require_c_str(&CString
::from_vec_with_nul(vec
![0]).unwrap().to_owned());
152 require_os_str(&OsString
::from("x").to_os_string());
153 require_path(&std
::path
::PathBuf
::from("x").to_path_buf());
154 require_str(&String
::from("x").to_string());
155 require_slice(&[String
::from("x")].to_owned());
158 fn require_c_str(_
: &CStr
) {}
159 fn require_os_str(_
: &OsStr
) {}
160 fn require_path(_
: &std
::path
::Path
) {}
161 fn require_str(_
: &str) {}
162 fn require_slice
<T
>(_
: &[T
]) {}
163 fn require_x(_
: &X
) {}
165 fn require_deref_c_str
<T
: Deref
<Target
= CStr
>>(_
: T
) {}
166 fn require_deref_os_str
<T
: Deref
<Target
= OsStr
>>(_
: T
) {}
167 fn require_deref_path
<T
: Deref
<Target
= std
::path
::Path
>>(_
: T
) {}
168 fn require_deref_str
<T
: Deref
<Target
= str>>(_
: T
) {}
169 fn require_deref_slice
<T
, U
: Deref
<Target
= [T
]>>(_
: U
) {}
171 fn require_impl_deref_c_str(_
: impl Deref
<Target
= CStr
>) {}
172 fn require_impl_deref_os_str(_
: impl Deref
<Target
= OsStr
>) {}
173 fn require_impl_deref_path(_
: impl Deref
<Target
= std
::path
::Path
>) {}
174 fn require_impl_deref_str(_
: impl Deref
<Target
= str>) {}
175 fn require_impl_deref_slice
<T
>(_
: impl Deref
<Target
= [T
]>) {}
177 fn require_deref_str_slice
<T
: Deref
<Target
= str>, U
, V
: Deref
<Target
= [U
]>>(_
: T
, _
: V
) {}
178 fn require_deref_slice_str
<T
, U
: Deref
<Target
= [T
]>, V
: Deref
<Target
= str>>(_
: U
, _
: V
) {}
180 fn require_as_ref_c_str
<T
: AsRef
<CStr
>>(_
: T
) {}
181 fn require_as_ref_os_str
<T
: AsRef
<OsStr
>>(_
: T
) {}
182 fn require_as_ref_path
<T
: AsRef
<std
::path
::Path
>>(_
: T
) {}
183 fn require_as_ref_str
<T
: AsRef
<str>>(_
: T
) {}
184 fn require_as_ref_slice
<T
, U
: AsRef
<[T
]>>(_
: U
) {}
186 fn require_impl_as_ref_c_str(_
: impl AsRef
<CStr
>) {}
187 fn require_impl_as_ref_os_str(_
: impl AsRef
<OsStr
>) {}
188 fn require_impl_as_ref_path(_
: impl AsRef
<std
::path
::Path
>) {}
189 fn require_impl_as_ref_str(_
: impl AsRef
<str>) {}
190 fn require_impl_as_ref_slice
<T
>(_
: impl AsRef
<[T
]>) {}
192 fn require_as_ref_str_slice
<T
: AsRef
<str>, U
, V
: AsRef
<[U
]>>(_
: T
, _
: V
) {}
193 fn require_as_ref_slice_str
<T
, U
: AsRef
<[T
]>, V
: AsRef
<str>>(_
: U
, _
: V
) {}
195 // `check_files` is based on:
196 // https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
197 fn check_files(file_types
: &[FileType
]) -> bool
{
198 for t
in file_types
.to_vec() {
199 let path
= match get_file_path(&t
) {
212 fn get_file_path(_file_type
: &FileType
) -> Result
<std
::path
::PathBuf
, std
::io
::Error
> {
213 Ok(std
::path
::PathBuf
::new())
216 fn require_string(_
: &String
) {}
219 #![clippy::msrv = "1.35"]
220 // `copied` was stabilized in 1.36, so clippy should use `cloned`.
221 let _
= &["x"][..].to_vec().into_iter();
225 #![clippy::msrv = "1.36"]
226 let _
= &["x"][..].to_vec().into_iter();
229 // https://github.com/rust-lang/rust-clippy/issues/8507
235 pub trait Abstracted {}
237 impl<P
> Abstracted
for Opaque
<P
> {}
239 fn build
<P
>(p
: P
) -> Opaque
<P
>
247 fn test_str(s
: &str) -> Box
<dyn Abstracted
> {
248 Box
::new(build(s
.to_string()))
252 fn test_x(x
: super::X
) -> Box
<dyn Abstracted
> {
256 #[derive(Clone, Copy)]
257 struct Y(&'
static str);
259 impl AsRef
<str> for Y
{
260 fn as_ref(&self) -> &str {
265 impl ToString
for Y
{
266 fn to_string(&self) -> String
{
271 // Should lint because Y is copy.
272 fn test_y(y
: Y
) -> Box
<dyn Abstracted
> {
273 Box
::new(build(y
.to_string()))
277 // https://github.com/rust-lang/rust-clippy/issues/8759
284 impl std
::borrow
::ToOwned
for View
{
286 fn to_owned(&self) -> Self::Owned
{
292 struct RenderWindow
{
297 fn default_view(&self) -> &View
{
300 fn set_view(&mut self, _view
: &View
) {}
304 let mut rw
= RenderWindow
::default();
305 rw
.set_view(&rw
.default_view().to_owned());
309 mod issue_8759_variant
{
312 #[derive(Clone, Default)]
316 struct RenderWindow
{
321 fn default_view(&self) -> &View
{
324 fn set_view(&mut self, _view
: &View
) {}
328 let mut rw
= RenderWindow
::default();
329 rw
.set_view(&rw
.default_view().to_owned());
338 impl ToString
for Bytes
{
339 fn to_string(&self) -> String
{
344 impl AsRef
<[u8]> for Bytes
{
345 fn as_ref(&self) -> &[u8] {
350 fn consume
<C
: AsRef
<[u8]>>(c
: C
) {
357 consume(b
.to_string());
365 use std
::path
::{Path, PathBuf}
;
367 fn require_deref_path
<T
: Deref
<Target
= std
::path
::Path
>>(x
: T
) -> T
{
371 fn generic_arg_used_elsewhere
<T
: AsRef
<Path
>>(_x
: T
, _y
: T
) {}
373 fn id
<T
: AsRef
<str>>(x
: T
) -> T
{
377 fn predicates_are_satisfied(_x
: impl std
::fmt
::Write
) {}
380 fn single_return() -> impl AsRef
<str> {
381 id("abc".to_string())
385 fn multiple_returns(b
: bool
) -> impl AsRef
<str> {
387 return String
::new();
390 id("abc".to_string())
397 S1(id("abc".to_string()))
406 let mut s
= S2 { s: "abc".into() }
;
407 s
.s
= id("abc".to_string());
411 let path
= std
::path
::Path
::new("x");
412 let path_buf
= path
.to_owned();
415 let _x
: PathBuf
= require_deref_path(path
.to_owned());
416 generic_arg_used_elsewhere(path
.to_owned(), path_buf
);
417 predicates_are_satisfied(id("abc".to_string()));
424 async
fn foo
<S
: AsRef
<str>>(_
: S
) {}
426 foo(std
::path
::PathBuf
::new().to_string_lossy().to_string()).await
;