]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.rs
Auto merge of #3640 - detrumi:nested_use_self, r=flip1995
[rust.git] / tests / ui / use_self.rs
1 // Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 #![warn(clippy::use_self)]
11 #![allow(dead_code)]
12 #![allow(clippy::should_implement_trait)]
13
14 fn main() {}
15
16 mod use_self {
17     struct Foo {}
18
19     impl Foo {
20         fn new() -> Foo {
21             Foo {}
22         }
23         fn test() -> Foo {
24             Foo::new()
25         }
26     }
27
28     impl Default for Foo {
29         fn default() -> Foo {
30             Foo::new()
31         }
32     }
33 }
34
35 mod better {
36     struct Foo {}
37
38     impl Foo {
39         fn new() -> Self {
40             Self {}
41         }
42         fn test() -> Self {
43             Self::new()
44         }
45     }
46
47     impl Default for Foo {
48         fn default() -> Self {
49             Self::new()
50         }
51     }
52 }
53
54 mod lifetimes {
55     struct Foo<'a> {
56         foo_str: &'a str,
57     }
58
59     impl<'a> Foo<'a> {
60         // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
61         // Foo<'b>`
62         fn foo(s: &str) -> Foo {
63             Foo { foo_str: s }
64         }
65         // cannot replace with `Self`, because that's `Foo<'a>`
66         fn bar() -> Foo<'static> {
67             Foo { foo_str: "foo" }
68         }
69
70         // FIXME: the lint does not handle lifetimed struct
71         // `Self` should be applicable here
72         fn clone(&self) -> Foo<'a> {
73             Foo { foo_str: self.foo_str }
74         }
75     }
76 }
77
78 #[allow(clippy::boxed_local)]
79 mod traits {
80
81     use std::ops::Mul;
82
83     trait SelfTrait {
84         fn refs(p1: &Self) -> &Self;
85         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;
86         fn mut_refs(p1: &mut Self) -> &mut Self;
87         fn nested(p1: Box<Self>, p2: (&u8, &Self));
88         fn vals(r: Self) -> Self;
89     }
90
91     #[derive(Default)]
92     struct Bad;
93
94     impl SelfTrait for Bad {
95         fn refs(p1: &Bad) -> &Bad {
96             p1
97         }
98
99         fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
100             p1
101         }
102
103         fn mut_refs(p1: &mut Bad) -> &mut Bad {
104             p1
105         }
106
107         fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
108
109         fn vals(_: Bad) -> Bad {
110             Bad::default()
111         }
112     }
113
114     impl Mul for Bad {
115         type Output = Bad;
116
117         fn mul(self, rhs: Bad) -> Bad {
118             rhs
119         }
120     }
121
122     #[derive(Default)]
123     struct Good;
124
125     impl SelfTrait for Good {
126         fn refs(p1: &Self) -> &Self {
127             p1
128         }
129
130         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
131             p1
132         }
133
134         fn mut_refs(p1: &mut Self) -> &mut Self {
135             p1
136         }
137
138         fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
139
140         fn vals(_: Self) -> Self {
141             Self::default()
142         }
143     }
144
145     impl Mul for Good {
146         type Output = Self;
147
148         fn mul(self, rhs: Self) -> Self {
149             rhs
150         }
151     }
152
153     trait NameTrait {
154         fn refs(p1: &u8) -> &u8;
155         fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;
156         fn mut_refs(p1: &mut u8) -> &mut u8;
157         fn nested(p1: Box<u8>, p2: (&u8, &u8));
158         fn vals(p1: u8) -> u8;
159     }
160
161     // Using `Self` instead of the type name is OK
162     impl NameTrait for u8 {
163         fn refs(p1: &Self) -> &Self {
164             p1
165         }
166
167         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
168             p1
169         }
170
171         fn mut_refs(p1: &mut Self) -> &mut Self {
172             p1
173         }
174
175         fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}
176
177         fn vals(_: Self) -> Self {
178             Self::default()
179         }
180     }
181
182     // Check that self arg isn't linted
183     impl Clone for Good {
184         fn clone(&self) -> Self {
185             // Note: Not linted and it wouldn't be valid
186             // because "can't use `Self` as a constructor`"
187             Good
188         }
189     }
190 }
191
192 mod issue2894 {
193     trait IntoBytes {
194         fn into_bytes(&self) -> Vec<u8>;
195     }
196
197     // This should not be linted
198     impl IntoBytes for u8 {
199         fn into_bytes(&self) -> Vec<u8> {
200             vec![*self]
201         }
202     }
203 }
204
205 mod existential {
206     struct Foo;
207
208     impl Foo {
209         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
210             foos.iter()
211         }
212
213         fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
214             foos.iter()
215         }
216     }
217 }
218
219 mod tuple_structs {
220     pub struct TS(i32);
221
222     impl TS {
223         pub fn ts() -> Self {
224             TS(0)
225         }
226     }
227 }
228
229 mod macros {
230     macro_rules! use_self_expand {
231         () => {
232             fn new() -> Foo {
233                 Foo {}
234             }
235         };
236     }
237
238     struct Foo {}
239
240     impl Foo {
241         use_self_expand!(); // Should lint in local macros
242     }
243 }
244
245 mod nesting {
246     struct Foo {}
247     impl Foo {
248         fn foo() {
249             use self::Foo; // Can't use Self here
250             struct Bar {
251                 foo: Foo, // Foo != Self
252             }
253
254             impl Bar {
255                 fn bar() -> Bar {
256                     Bar { foo: Foo {} }
257                 }
258             }
259         }
260     }
261
262     enum Enum {
263         A,
264     }
265     impl Enum {
266         fn method() {
267             use self::Enum::*; // Issue 3425
268             static STATIC: Enum = Enum::A; // Can't use Self as type
269         }
270     }
271 }
272
273 mod issue3410 {
274
275     struct A;
276     struct B;
277
278     trait Trait<T> {
279         fn a(v: T);
280     }
281
282     impl Trait<Vec<A>> for Vec<B> {
283         fn a(_: Vec<A>) {}
284     }
285 }