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