]> git.lizzy.rs Git - rust.git/blob - tests/ui/methods.rs
Check fn header along with decl when suggesting to implement trait
[rust.git] / tests / ui / methods.rs
1 // aux-build:option_helpers.rs
2 // edition:2018
3
4 #![warn(clippy::all, clippy::pedantic)]
5 #![allow(
6     clippy::blacklisted_name,
7     clippy::default_trait_access,
8     clippy::missing_docs_in_private_items,
9     clippy::missing_safety_doc,
10     clippy::non_ascii_literal,
11     clippy::new_without_default,
12     clippy::needless_pass_by_value,
13     clippy::print_stdout,
14     clippy::must_use_candidate,
15     clippy::use_self,
16     clippy::useless_format,
17     clippy::wrong_self_convention,
18     clippy::unused_self,
19     unused
20 )]
21
22 #[macro_use]
23 extern crate option_helpers;
24
25 use std::collections::BTreeMap;
26 use std::collections::HashMap;
27 use std::collections::HashSet;
28 use std::collections::VecDeque;
29 use std::iter::FromIterator;
30 use std::ops::Mul;
31 use std::rc::{self, Rc};
32 use std::sync::{self, Arc};
33
34 use option_helpers::IteratorFalsePositives;
35
36 pub struct T;
37
38 impl T {
39     pub fn add(self, other: T) -> T {
40         self
41     }
42
43     // no error, not public interface
44     pub(crate) fn drop(&mut self) {}
45
46     // no error, private function
47     fn neg(self) -> Self {
48         self
49     }
50
51     // no error, private function
52     fn eq(&self, other: T) -> bool {
53         true
54     }
55
56     // No error; self is a ref.
57     fn sub(&self, other: T) -> &T {
58         self
59     }
60
61     // No error; different number of arguments.
62     fn div(self) -> T {
63         self
64     }
65
66     // No error; wrong return type.
67     fn rem(self, other: T) {}
68
69     // Fine
70     fn into_u32(self) -> u32 {
71         0
72     }
73
74     fn into_u16(&self) -> u16 {
75         0
76     }
77
78     fn to_something(self) -> u32 {
79         0
80     }
81
82     fn new(self) -> Self {
83         unimplemented!();
84     }
85 }
86
87 pub struct T1;
88
89 impl T1 {
90     // Shouldn't trigger lint as it is unsafe.
91     pub unsafe fn add(self, rhs: T1) -> T1 {
92         self
93     }
94
95     // Should not trigger lint since this is an async function.
96     pub async fn next(&mut self) -> Option<T1> {
97         None
98     }
99 }
100
101 struct Lt<'a> {
102     foo: &'a u32,
103 }
104
105 impl<'a> Lt<'a> {
106     // The lifetime is different, but that’s irrelevant; see issue #734.
107     #[allow(clippy::needless_lifetimes)]
108     pub fn new<'b>(s: &'b str) -> Lt<'b> {
109         unimplemented!()
110     }
111 }
112
113 struct Lt2<'a> {
114     foo: &'a u32,
115 }
116
117 impl<'a> Lt2<'a> {
118     // The lifetime is different, but that’s irrelevant; see issue #734.
119     pub fn new(s: &str) -> Lt2 {
120         unimplemented!()
121     }
122 }
123
124 struct Lt3<'a> {
125     foo: &'a u32,
126 }
127
128 impl<'a> Lt3<'a> {
129     // The lifetime is different, but that’s irrelevant; see issue #734.
130     pub fn new() -> Lt3<'static> {
131         unimplemented!()
132     }
133 }
134
135 #[derive(Clone, Copy)]
136 struct U;
137
138 impl U {
139     fn new() -> Self {
140         U
141     }
142     // Ok because `U` is `Copy`.
143     fn to_something(self) -> u32 {
144         0
145     }
146 }
147
148 struct V<T> {
149     _dummy: T,
150 }
151
152 impl<T> V<T> {
153     fn new() -> Option<V<T>> {
154         None
155     }
156 }
157
158 struct AsyncNew;
159
160 impl AsyncNew {
161     async fn new() -> Option<Self> {
162         None
163     }
164 }
165
166 struct BadNew;
167
168 impl BadNew {
169     fn new() -> i32 {
170         0
171     }
172 }
173
174 impl Mul<T> for T {
175     type Output = T;
176     // No error, obviously.
177     fn mul(self, other: T) -> T {
178         self
179     }
180 }
181
182 /// Checks implementation of `FILTER_NEXT` lint.
183 #[rustfmt::skip]
184 fn filter_next() {
185     let v = vec![3, 2, 1, 0, -1, -2, -3];
186
187     // Single-line case.
188     let _ = v.iter().filter(|&x| *x < 0).next();
189
190     // Multi-line case.
191     let _ = v.iter().filter(|&x| {
192                                 *x < 0
193                             }
194                    ).next();
195
196     // Check that hat we don't lint if the caller is not an `Iterator`.
197     let foo = IteratorFalsePositives { foo: 0 };
198     let _ = foo.filter().next();
199 }
200
201 /// Checks implementation of `SEARCH_IS_SOME` lint.
202 #[rustfmt::skip]
203 fn search_is_some() {
204     let v = vec![3, 2, 1, 0, -1, -2, -3];
205     let y = &&42;
206
207     // Check `find().is_some()`, single-line case.
208     let _ = v.iter().find(|&x| *x < 0).is_some();
209     let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less
210     let _ = (0..1).find(|x| *x == 0).is_some();
211     let _ = v.iter().find(|x| **x == 0).is_some();
212
213     // Check `find().is_some()`, multi-line case.
214     let _ = v.iter().find(|&x| {
215                               *x < 0
216                           }
217                    ).is_some();
218
219     // Check `position().is_some()`, single-line case.
220     let _ = v.iter().position(|&x| x < 0).is_some();
221
222     // Check `position().is_some()`, multi-line case.
223     let _ = v.iter().position(|&x| {
224                                   x < 0
225                               }
226                    ).is_some();
227
228     // Check `rposition().is_some()`, single-line case.
229     let _ = v.iter().rposition(|&x| x < 0).is_some();
230
231     // Check `rposition().is_some()`, multi-line case.
232     let _ = v.iter().rposition(|&x| {
233                                    x < 0
234                                }
235                    ).is_some();
236
237     // Check that we don't lint if the caller is not an `Iterator`.
238     let foo = IteratorFalsePositives { foo: 0 };
239     let _ = foo.find().is_some();
240     let _ = foo.position().is_some();
241     let _ = foo.rposition().is_some();
242 }
243
244 fn main() {
245     filter_next();
246     search_is_some();
247 }