]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.rs
Merge branch 'master' into rustfmt_tests
[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 //todo the lint does not handle lifetimed struct
55 //the following module should trigger the lint on the third method only
56 mod lifetimes {
57     struct Foo<'a> {
58         foo_str: &'a str,
59     }
60
61     impl<'a> Foo<'a> {
62         // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
63         // Foo<'b>`
64         fn foo(s: &str) -> Foo {
65             Foo { foo_str: s }
66         }
67         // cannot replace with `Self`, because that's `Foo<'a>`
68         fn bar() -> Foo<'static> {
69             Foo { foo_str: "foo" }
70         }
71
72         // `Self` is applicable here
73         fn clone(&self) -> Foo<'a> {
74             Foo { foo_str: self.foo_str }
75         }
76     }
77 }
78
79 #[allow(clippy::boxed_local)]
80 mod traits {
81
82     use std::ops::Mul;
83
84     trait SelfTrait {
85         fn refs(p1: &Self) -> &Self;
86         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;
87         fn mut_refs(p1: &mut Self) -> &mut Self;
88         fn nested(p1: Box<Self>, p2: (&u8, &Self));
89         fn vals(r: Self) -> Self;
90     }
91
92     #[derive(Default)]
93     struct Bad;
94
95     impl SelfTrait for Bad {
96         fn refs(p1: &Bad) -> &Bad {
97             p1
98         }
99
100         fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
101             p1
102         }
103
104         fn mut_refs(p1: &mut Bad) -> &mut Bad {
105             p1
106         }
107
108         fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
109
110         fn vals(_: Bad) -> Bad {
111             Bad::default()
112         }
113     }
114
115     impl Mul for Bad {
116         type Output = Bad;
117
118         fn mul(self, rhs: Bad) -> Bad {
119             rhs
120         }
121     }
122
123     #[derive(Default)]
124     struct Good;
125
126     impl SelfTrait for Good {
127         fn refs(p1: &Self) -> &Self {
128             p1
129         }
130
131         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
132             p1
133         }
134
135         fn mut_refs(p1: &mut Self) -> &mut Self {
136             p1
137         }
138
139         fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
140
141         fn vals(_: Self) -> Self {
142             Self::default()
143         }
144     }
145
146     impl Mul for Good {
147         type Output = Self;
148
149         fn mul(self, rhs: Self) -> Self {
150             rhs
151         }
152     }
153
154     trait NameTrait {
155         fn refs(p1: &u8) -> &u8;
156         fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;
157         fn mut_refs(p1: &mut u8) -> &mut u8;
158         fn nested(p1: Box<u8>, p2: (&u8, &u8));
159         fn vals(p1: u8) -> u8;
160     }
161
162     // Using `Self` instead of the type name is OK
163     impl NameTrait for u8 {
164         fn refs(p1: &Self) -> &Self {
165             p1
166         }
167
168         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
169             p1
170         }
171
172         fn mut_refs(p1: &mut Self) -> &mut Self {
173             p1
174         }
175
176         fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}
177
178         fn vals(_: Self) -> Self {
179             Self::default()
180         }
181     }
182
183     // Check that self arg isn't linted
184     impl Clone for Good {
185         fn clone(&self) -> Self {
186             // Note: Not linted and it wouldn't be valid
187             // because "can't use `Self` as a constructor`"
188             Good
189         }
190     }
191 }
192
193 mod issue2894 {
194     trait IntoBytes {
195         fn into_bytes(&self) -> Vec<u8>;
196     }
197
198     // This should not be linted
199     impl IntoBytes for u8 {
200         fn into_bytes(&self) -> Vec<u8> {
201             vec![*self]
202         }
203     }
204 }
205
206 mod existential {
207     struct Foo;
208
209     impl Foo {
210         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
211             foos.iter()
212         }
213
214         fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
215             foos.iter()
216         }
217     }
218 }
219
220 mod issue3410 {
221
222     struct A;
223     struct B;
224
225     trait Trait<T> {
226         fn a(v: T);
227     }
228
229     impl Trait<Vec<A>> for Vec<B> {
230         fn a(_: Vec<A>) {}
231     }
232 }
233
234 mod issue3425 {
235     enum Enum {
236         A,
237     }
238     impl Enum {
239         fn a() {
240             use self::Enum::*;
241         }
242     }
243 }