]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/tests/ui/explicit_auto_deref.fixed
New upstream version 1.65.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / explicit_auto_deref.fixed
1 // run-rustfix
2
3 #![feature(closure_lifetime_binder)]
4 #![warn(clippy::explicit_auto_deref)]
5 #![allow(
6 dead_code,
7 unused_braces,
8 clippy::borrowed_box,
9 clippy::needless_borrow,
10 clippy::needless_return,
11 clippy::ptr_arg,
12 clippy::redundant_field_names,
13 clippy::too_many_arguments,
14 clippy::borrow_deref_ref,
15 clippy::let_unit_value
16 )]
17
18 trait CallableStr {
19 type T: Fn(&str);
20 fn callable_str(&self) -> Self::T;
21 }
22 impl CallableStr for () {
23 type T = fn(&str);
24 fn callable_str(&self) -> Self::T {
25 fn f(_: &str) {}
26 f
27 }
28 }
29 impl CallableStr for i32 {
30 type T = <() as CallableStr>::T;
31 fn callable_str(&self) -> Self::T {
32 ().callable_str()
33 }
34 }
35
36 trait CallableT<U: ?Sized> {
37 type T: Fn(&U);
38 fn callable_t(&self) -> Self::T;
39 }
40 impl<U: ?Sized> CallableT<U> for () {
41 type T = fn(&U);
42 fn callable_t(&self) -> Self::T {
43 fn f<U: ?Sized>(_: &U) {}
44 f::<U>
45 }
46 }
47 impl<U: ?Sized> CallableT<U> for i32 {
48 type T = <() as CallableT<U>>::T;
49 fn callable_t(&self) -> Self::T {
50 ().callable_t()
51 }
52 }
53
54 fn f_str(_: &str) {}
55 fn f_string(_: &String) {}
56 fn f_t<T>(_: T) {}
57 fn f_ref_t<T: ?Sized>(_: &T) {}
58
59 fn f_str_t<T>(_: &str, _: T) {}
60
61 fn f_box_t<T>(_: &Box<T>) {}
62
63 extern "C" {
64 fn var(_: u32, ...);
65 }
66
67 fn main() {
68 let s = String::new();
69
70 let _: &str = &s;
71 let _: &str = &{ String::new() };
72 let _: &str = &mut { String::new() };
73 let _ = &*s; // Don't lint. Inferred type would change.
74 let _: &_ = &*s; // Don't lint. Inferred type would change.
75
76 f_str(&s);
77 f_t(&*s); // Don't lint. Inferred type would change.
78 f_ref_t(&*s); // Don't lint. Inferred type would change.
79
80 f_str_t(&s, &*s); // Don't lint second param.
81
82 let b = Box::new(Box::new(Box::new(5)));
83 let _: &Box<i32> = &b;
84 let _: &Box<_> = &**b; // Don't lint. Inferred type would change.
85
86 f_box_t(&**b); // Don't lint. Inferred type would change.
87
88 let c = |_x: &str| ();
89 c(&s);
90
91 let c = |_x| ();
92 c(&*s); // Don't lint. Inferred type would change.
93
94 fn _f(x: &String) -> &str {
95 x
96 }
97
98 fn _f1(x: &String) -> &str {
99 { x }
100 }
101
102 fn _f2(x: &String) -> &str {
103 { x }
104 }
105
106 fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {
107 x
108 }
109
110 fn _f4(
111 x: String,
112 f1: impl Fn(&str),
113 f2: &dyn Fn(&str),
114 f3: fn(&str),
115 f4: impl CallableStr,
116 f5: <() as CallableStr>::T,
117 f6: <i32 as CallableStr>::T,
118 f7: &dyn CallableStr<T = fn(&str)>,
119 f8: impl CallableT<str>,
120 f9: <() as CallableT<str>>::T,
121 f10: <i32 as CallableT<str>>::T,
122 f11: &dyn CallableT<str, T = fn(&str)>,
123 ) {
124 f1(&x);
125 f2(&x);
126 f3(&x);
127 f4.callable_str()(&x);
128 f5(&x);
129 f6(&x);
130 f7.callable_str()(&x);
131 f8.callable_t()(&x);
132 f9(&x);
133 f10(&x);
134 f11.callable_t()(&x);
135 }
136
137 struct S1<'a>(&'a str);
138 let _ = S1(&s);
139
140 struct S2<'a> {
141 s: &'a str,
142 }
143 let _ = S2 { s: &s };
144
145 struct S3<'a, T: ?Sized>(&'a T);
146 let _ = S3(&*s); // Don't lint. Inferred type would change.
147
148 struct S4<'a, T: ?Sized> {
149 s: &'a T,
150 }
151 let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.
152
153 enum E1<'a> {
154 S1(&'a str),
155 S2 { s: &'a str },
156 }
157 impl<'a> E1<'a> {
158 fn m1(s: &'a String) {
159 let _ = Self::S1(s);
160 let _ = Self::S2 { s: s };
161 }
162 }
163 let _ = E1::S1(&s);
164 let _ = E1::S2 { s: &s };
165
166 enum E2<'a, T: ?Sized> {
167 S1(&'a T),
168 S2 { s: &'a T },
169 }
170 let _ = E2::S1(&*s); // Don't lint. Inferred type would change.
171 let _ = E2::S2 { s: &*s }; // Don't lint. Inferred type would change.
172
173 let ref_s = &s;
174 let _: &String = &*ref_s; // Don't lint reborrow.
175 f_string(&*ref_s); // Don't lint reborrow.
176
177 struct S5 {
178 foo: u32,
179 }
180 let b = Box::new(Box::new(S5 { foo: 5 }));
181 let _ = b.foo;
182 let _ = b.foo;
183 let _ = b.foo;
184
185 struct S6 {
186 foo: S5,
187 }
188 impl core::ops::Deref for S6 {
189 type Target = S5;
190 fn deref(&self) -> &Self::Target {
191 &self.foo
192 }
193 }
194 let s6 = S6 { foo: S5 { foo: 5 } };
195 let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`
196
197 let ref_str = &"foo";
198 let _ = f_str(ref_str);
199 let ref_ref_str = &ref_str;
200 let _ = f_str(ref_ref_str);
201
202 fn _f5(x: &u32) -> u32 {
203 if true {
204 *x
205 } else {
206 return *x;
207 }
208 }
209
210 f_str(&&ref_str); // `needless_borrow` will suggest removing both references
211 f_str(&ref_str); // `needless_borrow` will suggest removing only one reference
212
213 let x = &&40;
214 unsafe {
215 var(0, &**x);
216 }
217
218 let s = &"str";
219 let _ = || return *s;
220 let _ = || -> &'static str { return s };
221
222 struct X;
223 struct Y(X);
224 impl core::ops::Deref for Y {
225 type Target = X;
226 fn deref(&self) -> &Self::Target {
227 &self.0
228 }
229 }
230 let _: &X = &*{ Y(X) };
231 let _: &X = &*match 0 {
232 #[rustfmt::skip]
233 0 => { Y(X) },
234 _ => panic!(),
235 };
236 let _: &X = &*if true { Y(X) } else { panic!() };
237
238 fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {
239 x
240 }
241
242 let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x };
243 fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any {
244 &**x
245 }
246
247 let x = String::new();
248 let _: *const str = &*x;
249
250 struct S7([u32; 1]);
251 impl core::ops::Deref for S7 {
252 type Target = [u32; 1];
253 fn deref(&self) -> &Self::Target {
254 &self.0
255 }
256 }
257 let x = S7([0]);
258 let _: &[u32] = &*x;
259
260 let c1 = |_: &Vec<&u32>| {};
261 let x = &&vec![&1u32];
262 c1(x);
263 let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
264 if b {
265 return x;
266 }
267 x
268 };
269 }