3 #![warn(clippy::explicit_auto_deref)]
8 clippy::needless_borrow,
9 clippy::needless_return,
11 clippy::redundant_field_names,
12 clippy::too_many_arguments,
13 clippy::borrow_deref_ref,
14 clippy::let_unit_value
19 fn callable_str(&self) -> Self::T;
21 impl CallableStr for () {
23 fn callable_str(&self) -> Self::T {
28 impl CallableStr for i32 {
29 type T = <() as CallableStr>::T;
30 fn callable_str(&self) -> Self::T {
35 trait CallableT<U: ?Sized> {
37 fn callable_t(&self) -> Self::T;
39 impl<U: ?Sized> CallableT<U> for () {
41 fn callable_t(&self) -> Self::T {
42 fn f<U: ?Sized>(_: &U) {}
46 impl<U: ?Sized> CallableT<U> for i32 {
47 type T = <() as CallableT<U>>::T;
48 fn callable_t(&self) -> Self::T {
54 fn f_string(_: &String) {}
56 fn f_ref_t<T: ?Sized>(_: &T) {}
58 fn f_str_t<T>(_: &str, _: T) {}
60 fn f_box_t<T>(_: &Box<T>) {}
67 let s = String::new();
70 let _: &str = &*{ String::new() };
71 let _ = &*s; // Don't lint. Inferred type would change.
72 let _: &_ = &*s; // Don't lint. Inferred type would change.
75 f_t(&*s); // Don't lint. Inferred type would change.
76 f_ref_t(&*s); // Don't lint. Inferred type would change.
78 f_str_t(&*s, &*s); // Don't lint second param.
80 let b = Box::new(Box::new(Box::new(5)));
81 let _: &Box<i32> = &**b;
82 let _: &Box<_> = &**b; // Don't lint. Inferred type would change.
84 f_box_t(&**b); // Don't lint. Inferred type would change.
86 let c = |_x: &str| ();
90 c(&*s); // Don't lint. Inferred type would change.
92 fn _f(x: &String) -> &str {
96 fn _f1(x: &String) -> &str {
100 fn _f2(x: &String) -> &str {
104 fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {
113 f4: impl CallableStr,
114 f5: <() as CallableStr>::T,
115 f6: <i32 as CallableStr>::T,
116 f7: &dyn CallableStr<T = fn(&str)>,
117 f8: impl CallableT<str>,
118 f9: <() as CallableT<str>>::T,
119 f10: <i32 as CallableT<str>>::T,
120 f11: &dyn CallableT<str, T = fn(&str)>,
125 f4.callable_str()(&*x);
128 f7.callable_str()(&*x);
129 f8.callable_t()(&*x);
132 f11.callable_t()(&*x);
135 struct S1<'a>(&'a str);
141 let _ = S2 { s: &*s };
143 struct S3<'a, T: ?Sized>(&'a T);
144 let _ = S3(&*s); // Don't lint. Inferred type would change.
146 struct S4<'a, T: ?Sized> {
149 let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.
156 fn m1(s: &'a String) {
157 let _ = Self::S1(&**s);
158 let _ = Self::S2 { s: &**s };
162 let _ = E1::S2 { s: &*s };
164 enum E2<'a, T: ?Sized> {
168 let _ = E2::S1(&*s); // Don't lint. Inferred type would change.
169 let _ = E2::S2 { s: &*s }; // Don't lint. Inferred type would change.
172 let _: &String = &*ref_s; // Don't lint reborrow.
173 f_string(&*ref_s); // Don't lint reborrow.
178 let b = Box::new(Box::new(S5 { foo: 5 }));
186 impl core::ops::Deref for S6 {
188 fn deref(&self) -> &Self::Target {
192 let s6 = S6 { foo: S5 { foo: 5 } };
193 let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`
195 let ref_str = &"foo";
196 let _ = f_str(*ref_str);
197 let ref_ref_str = &ref_str;
198 let _ = f_str(**ref_ref_str);
200 fn _f5(x: &u32) -> u32 {
208 f_str(&&*ref_str); // `needless_borrow` will suggest removing both references
209 f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
217 let _ = || return *s;
218 let _ = || -> &'static str { return *s };
222 impl core::ops::Deref for Y {
224 fn deref(&self) -> &Self::Target {
228 let _: &X = &*{ Y(X) };
229 let _: &X = &*match 0 {
234 let _: &X = &*if true { Y(X) } else { panic!() };