]> git.lizzy.rs Git - rust.git/blob - tests/ui/explicit_auto_deref.rs
f49bc8bb9f0120307a9c4de899a54de620d61b23
[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 )]
15
16 trait CallableStr {
17     type T: Fn(&str);
18     fn callable_str(&self) -> Self::T;
19 }
20 impl CallableStr for () {
21     type T = fn(&str);
22     fn callable_str(&self) -> Self::T {
23         fn f(_: &str) {}
24         f
25     }
26 }
27 impl CallableStr for i32 {
28     type T = <() as CallableStr>::T;
29     fn callable_str(&self) -> Self::T {
30         ().callable_str()
31     }
32 }
33
34 trait CallableT<U: ?Sized> {
35     type T: Fn(&U);
36     fn callable_t(&self) -> Self::T;
37 }
38 impl<U: ?Sized> CallableT<U> for () {
39     type T = fn(&U);
40     fn callable_t(&self) -> Self::T {
41         fn f<U: ?Sized>(_: &U) {}
42         f::<U>
43     }
44 }
45 impl<U: ?Sized> CallableT<U> for i32 {
46     type T = <() as CallableT<U>>::T;
47     fn callable_t(&self) -> Self::T {
48         ().callable_t()
49     }
50 }
51
52 fn f_str(_: &str) {}
53 fn f_string(_: &String) {}
54 fn f_t<T>(_: T) {}
55 fn f_ref_t<T: ?Sized>(_: &T) {}
56
57 fn f_str_t<T>(_: &str, _: T) {}
58
59 fn f_box_t<T>(_: &Box<T>) {}
60
61 fn main() {
62     let s = String::new();
63
64     let _: &str = &*s;
65     let _ = &*s; // Don't lint. Inferred type would change.
66     let _: &_ = &*s; // Don't lint. Inferred type would change.
67
68     f_str(&*s);
69     f_t(&*s); // Don't lint. Inferred type would change.
70     f_ref_t(&*s); // Don't lint. Inferred type would change.
71
72     f_str_t(&*s, &*s); // Don't lint second param.
73
74     let b = Box::new(Box::new(Box::new(5)));
75     let _: &Box<i32> = &**b;
76     let _: &Box<_> = &**b; // Don't lint. Inferred type would change.
77
78     f_box_t(&**b); // Don't lint. Inferred type would change.
79
80     let c = |_x: &str| ();
81     c(&*s);
82
83     let c = |_x| ();
84     c(&*s); // Don't lint. Inferred type would change.
85
86     fn _f(x: &String) -> &str {
87         &**x
88     }
89
90     fn _f1(x: &String) -> &str {
91         { &**x }
92     }
93
94     fn _f2(x: &String) -> &str {
95         &**{ x }
96     }
97
98     fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {
99         &***x
100     }
101
102     fn _f4(
103         x: String,
104         f1: impl Fn(&str),
105         f2: &dyn Fn(&str),
106         f3: fn(&str),
107         f4: impl CallableStr,
108         f5: <() as CallableStr>::T,
109         f6: <i32 as CallableStr>::T,
110         f7: &dyn CallableStr<T = fn(&str)>,
111         f8: impl CallableT<str>,
112         f9: <() as CallableT<str>>::T,
113         f10: <i32 as CallableT<str>>::T,
114         f11: &dyn CallableT<str, T = fn(&str)>,
115     ) {
116         f1(&*x);
117         f2(&*x);
118         f3(&*x);
119         f4.callable_str()(&*x);
120         f5(&*x);
121         f6(&*x);
122         f7.callable_str()(&*x);
123         f8.callable_t()(&*x);
124         f9(&*x);
125         f10(&*x);
126         f11.callable_t()(&*x);
127     }
128
129     struct S1<'a>(&'a str);
130     let _ = S1(&*s);
131
132     struct S2<'a> {
133         s: &'a str,
134     }
135     let _ = S2 { s: &*s };
136
137     struct S3<'a, T: ?Sized>(&'a T);
138     let _ = S3(&*s); // Don't lint. Inferred type would change.
139
140     struct S4<'a, T: ?Sized> {
141         s: &'a T,
142     }
143     let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.
144
145     enum E1<'a> {
146         S1(&'a str),
147         S2 { s: &'a str },
148     }
149     impl<'a> E1<'a> {
150         fn m1(s: &'a String) {
151             let _ = Self::S1(&**s);
152             let _ = Self::S2 { s: &**s };
153         }
154     }
155     let _ = E1::S1(&*s);
156     let _ = E1::S2 { s: &*s };
157
158     enum E2<'a, T: ?Sized> {
159         S1(&'a T),
160         S2 { s: &'a T },
161     }
162     let _ = E2::S1(&*s); // Don't lint. Inferred type would change.
163     let _ = E2::S2 { s: &*s }; // Don't lint. Inferred type would change.
164
165     let ref_s = &s;
166     let _: &String = &*ref_s; // Don't lint reborrow.
167     f_string(&*ref_s); // Don't lint reborrow.
168
169     struct S5 {
170         foo: u32,
171     }
172     let b = Box::new(Box::new(S5 { foo: 5 }));
173     let _ = b.foo;
174     let _ = (*b).foo;
175     let _ = (**b).foo;
176
177     struct S6 {
178         foo: S5,
179     }
180     impl core::ops::Deref for S6 {
181         type Target = S5;
182         fn deref(&self) -> &Self::Target {
183             &self.foo
184         }
185     }
186     let s6 = S6 { foo: S5 { foo: 5 } };
187     let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`
188
189     let ref_str = &"foo";
190     let _ = f_str(*ref_str);
191     let ref_ref_str = &ref_str;
192     let _ = f_str(**ref_ref_str);
193
194     fn _f5(x: &u32) -> u32 {
195         if true {
196             *x
197         } else {
198             return *x;
199         }
200     }
201 }