]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
New upstream version 1.62.1+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / unnecessary_to_owned.fixed
CommitLineData
a2a8927a
XL
1// run-rustfix
2
3#![allow(clippy::ptr_arg)]
4#![warn(clippy::unnecessary_to_owned)]
04454e1e 5#![feature(custom_inner_attributes)]
a2a8927a
XL
6
7use std::borrow::Cow;
8use std::ffi::{CStr, CString, OsStr, OsString};
9use std::ops::Deref;
10
11#[derive(Clone)]
12struct X(String);
13
14impl Deref for X {
15 type Target = [u8];
16 fn deref(&self) -> &[u8] {
17 self.0.as_bytes()
18 }
19}
20
21impl AsRef<str> for X {
22 fn as_ref(&self) -> &str {
23 self.0.as_str()
24 }
25}
26
27impl ToString for X {
28 fn to_string(&self) -> String {
29 self.0.to_string()
30 }
31}
32
33impl X {
34 fn join(&self, other: impl AsRef<str>) -> Self {
35 let mut s = self.0.clone();
36 s.push_str(other.as_ref());
37 Self(s)
38 }
39}
40
41#[allow(dead_code)]
42#[derive(Clone)]
43enum FileType {
44 Account,
45 PrivateKey,
46 Certificate,
47}
48
49fn main() {
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");
53 let s = "x";
54 let array = ["x"];
55 let array_ref = &["x"];
56 let slice = &["x"][..];
57 let x = X(String::from("x"));
58 let x_ref = &x;
59
60 require_c_str(&Cow::from(c_str));
61 require_c_str(c_str);
62
63 require_os_str(os_str);
64 require_os_str(&Cow::from(os_str));
65 require_os_str(os_str);
66
67 require_path(path);
68 require_path(&Cow::from(path));
69 require_path(path);
70
71 require_str(s);
72 require_str(&Cow::from(s));
73 require_str(s);
74 require_str(x_ref.as_ref());
75
76 require_slice(slice);
77 require_slice(&Cow::from(slice));
78 require_slice(array.as_ref());
79 require_slice(array_ref.as_ref());
80 require_slice(slice);
81 require_slice(x_ref);
82
83 require_x(&Cow::<X>::Owned(x.clone()));
84 require_x(x_ref);
85
86 require_deref_c_str(c_str);
87 require_deref_os_str(os_str);
88 require_deref_path(path);
89 require_deref_str(s);
90 require_deref_slice(slice);
91
92 require_impl_deref_c_str(c_str);
93 require_impl_deref_os_str(os_str);
94 require_impl_deref_path(path);
95 require_impl_deref_str(s);
96 require_impl_deref_slice(slice);
97
98 require_deref_str_slice(s, slice);
99 require_deref_slice_str(slice, s);
100
101 require_as_ref_c_str(c_str);
102 require_as_ref_os_str(os_str);
103 require_as_ref_path(path);
104 require_as_ref_str(s);
105 require_as_ref_str(&x);
106 require_as_ref_slice(array);
107 require_as_ref_slice(array_ref);
108 require_as_ref_slice(slice);
109
110 require_impl_as_ref_c_str(c_str);
111 require_impl_as_ref_os_str(os_str);
112 require_impl_as_ref_path(path);
113 require_impl_as_ref_str(s);
114 require_impl_as_ref_str(&x);
115 require_impl_as_ref_slice(array);
116 require_impl_as_ref_slice(array_ref);
117 require_impl_as_ref_slice(slice);
118
119 require_as_ref_str_slice(s, array);
120 require_as_ref_str_slice(s, array_ref);
121 require_as_ref_str_slice(s, slice);
122 require_as_ref_slice_str(array, s);
123 require_as_ref_slice_str(array_ref, s);
124 require_as_ref_slice_str(slice, s);
125
126 let _ = x.join(x_ref);
127
128 let _ = slice.iter().copied();
129 let _ = slice.iter().copied();
130 let _ = [std::path::PathBuf::new()][..].iter().cloned();
131 let _ = [std::path::PathBuf::new()][..].iter().cloned();
132
133 let _ = slice.iter().copied();
134 let _ = slice.iter().copied();
135 let _ = [std::path::PathBuf::new()][..].iter().cloned();
136 let _ = [std::path::PathBuf::new()][..].iter().cloned();
137
138 let _ = check_files(&[FileType::Account]);
139
140 // negative tests
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());
145
146 // `X` isn't copy.
147 require_slice(&x.to_owned());
148 require_deref_slice(x.to_owned());
149
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());
152 require_os_str(&OsString::from("x"));
153 require_path(&std::path::PathBuf::from("x"));
154 require_str(&String::from("x"));
155}
156
157fn require_c_str(_: &CStr) {}
158fn require_os_str(_: &OsStr) {}
159fn require_path(_: &std::path::Path) {}
160fn require_str(_: &str) {}
161fn require_slice<T>(_: &[T]) {}
162fn require_x(_: &X) {}
163
164fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}
165fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}
166fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}
167fn require_deref_str<T: Deref<Target = str>>(_: T) {}
168fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}
169
170fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}
171fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}
172fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}
173fn require_impl_deref_str(_: impl Deref<Target = str>) {}
174fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}
175
176fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}
177fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}
178
179fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}
180fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}
181fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}
182fn require_as_ref_str<T: AsRef<str>>(_: T) {}
183fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}
184
185fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}
186fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}
187fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}
188fn require_impl_as_ref_str(_: impl AsRef<str>) {}
189fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}
190
191fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}
192fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}
193
194// `check_files` is based on:
195// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
196fn check_files(file_types: &[FileType]) -> bool {
197 for t in file_types {
198 let path = match get_file_path(t) {
199 Ok(p) => p,
200 Err(_) => {
201 return false;
202 },
203 };
204 if !path.is_file() {
205 return false;
206 }
207 }
208 true
209}
210
211fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
212 Ok(std::path::PathBuf::new())
213}
214
215fn require_string(_: &String) {}
5e7ed085 216
04454e1e
FG
217fn _msrv_1_35() {
218 #![clippy::msrv = "1.35"]
219 // `copied` was stabilized in 1.36, so clippy should use `cloned`.
220 let _ = &["x"][..].iter().cloned();
221}
222
223fn _msrv_1_36() {
224 #![clippy::msrv = "1.36"]
225 let _ = &["x"][..].iter().copied();
226}
227
5e7ed085
FG
228// https://github.com/rust-lang/rust-clippy/issues/8507
229mod issue_8507 {
230 #![allow(dead_code)]
231
232 struct Opaque<P>(P);
233
234 pub trait Abstracted {}
235
236 impl<P> Abstracted for Opaque<P> {}
237
238 fn build<P>(p: P) -> Opaque<P>
239 where
240 P: AsRef<str>,
241 {
242 Opaque(p)
243 }
244
245 // Should not lint.
246 fn test_str(s: &str) -> Box<dyn Abstracted> {
247 Box::new(build(s.to_string()))
248 }
249
250 // Should not lint.
251 fn test_x(x: super::X) -> Box<dyn Abstracted> {
252 Box::new(build(x))
253 }
254
255 #[derive(Clone, Copy)]
256 struct Y(&'static str);
257
258 impl AsRef<str> for Y {
259 fn as_ref(&self) -> &str {
260 self.0
261 }
262 }
263
264 impl ToString for Y {
265 fn to_string(&self) -> String {
266 self.0.to_string()
267 }
268 }
269
270 // Should lint because Y is copy.
271 fn test_y(y: Y) -> Box<dyn Abstracted> {
272 Box::new(build(y))
273 }
274}