3 #![feature(closure_lifetime_binder)]
4 #![warn(clippy::explicit_auto_deref)]
9 clippy::needless_borrow,
10 clippy::needless_return,
12 clippy::redundant_field_names,
13 clippy::too_many_arguments,
14 clippy::borrow_deref_ref,
15 clippy::let_unit_value
20 fn callable_str(&self) -> Self::T;
22 impl CallableStr for () {
24 fn callable_str(&self) -> Self::T {
29 impl CallableStr for i32 {
30 type T = <() as CallableStr>::T;
31 fn callable_str(&self) -> Self::T {
36 trait CallableT<U: ?Sized> {
38 fn callable_t(&self) -> Self::T;
40 impl<U: ?Sized> CallableT<U> for () {
42 fn callable_t(&self) -> Self::T {
43 fn f<U: ?Sized>(_: &U) {}
47 impl<U: ?Sized> CallableT<U> for i32 {
48 type T = <() as CallableT<U>>::T;
49 fn callable_t(&self) -> Self::T {
55 fn f_string(_: &String) {}
57 fn f_ref_t<T: ?Sized>(_: &T) {}
59 fn f_str_t<T>(_: &str, _: T) {}
61 fn f_box_t<T>(_: &Box<T>) {}
68 let s = String::new();
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.
77 f_t(&*s); // Don't lint. Inferred type would change.
78 f_ref_t(&*s); // Don't lint. Inferred type would change.
80 f_str_t(&*s, &*s); // Don't lint second param.
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.
86 f_box_t(&**b); // Don't lint. Inferred type would change.
88 let c = |_x: &str| ();
92 c(&*s); // Don't lint. Inferred type would change.
94 fn _f(x: &String) -> &str {
98 fn _f1(x: &String) -> &str {
102 fn _f2(x: &String) -> &str {
106 fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {
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)>,
127 f4.callable_str()(&*x);
130 f7.callable_str()(&*x);
131 f8.callable_t()(&*x);
134 f11.callable_t()(&*x);
137 struct S1<'a>(&'a str);
143 let _ = S2 { s: &*s };
145 struct S3<'a, T: ?Sized>(&'a T);
146 let _ = S3(&*s); // Don't lint. Inferred type would change.
148 struct S4<'a, T: ?Sized> {
151 let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.
158 fn m1(s: &'a String) {
159 let _ = Self::S1(&**s);
160 let _ = Self::S2 { s: &**s };
164 let _ = E1::S2 { s: &*s };
166 enum E2<'a, T: ?Sized> {
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.
174 let _: &String = &*ref_s; // Don't lint reborrow.
175 f_string(&*ref_s); // Don't lint reborrow.
180 let b = Box::new(Box::new(S5 { foo: 5 }));
188 impl core::ops::Deref for S6 {
190 fn deref(&self) -> &Self::Target {
194 let s6 = S6 { foo: S5 { foo: 5 } };
195 let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`
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);
202 fn _f5(x: &u32) -> u32 {
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
219 let _ = || return *s;
220 let _ = || -> &'static str { return *s };
224 impl core::ops::Deref for Y {
226 fn deref(&self) -> &Self::Target {
230 let _: &X = &*{ Y(X) };
231 let _: &X = &*match 0 {
236 let _: &X = &*if true { Y(X) } else { panic!() };
238 fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {
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 {
247 let x = String::new();
248 let _: *const str = &*x;
251 impl core::ops::Deref for S7 {
252 type Target = [u32; 1];
253 fn deref(&self) -> &Self::Target {
260 let c1 = |_: &Vec<&u32>| {};
261 let x = &&vec![&1u32];
263 let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {
273 impl WithAssoc for String {
276 fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {
279 let _: String = takes_assoc(&*String::new());
282 fn takes_ref(_: &i32) {}
283 takes_ref(*Box::new(&0i32));