]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/explicit_auto_deref.fixed
Auto merge of #99099 - Stargateur:phantomdata_debug, r=joshtriplett
[rust.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 }