1 // aux-build:option_helpers.rs
2 // compile-flags: --edition 2018
7 clippy::option_unwrap_used,
8 clippy::option_expect_used,
9 clippy::result_expect_used
12 clippy::blacklisted_name,
13 clippy::default_trait_access,
14 clippy::missing_docs_in_private_items,
15 clippy::non_ascii_literal,
16 clippy::new_without_default,
17 clippy::needless_pass_by_value,
19 clippy::must_use_candidate,
21 clippy::useless_format,
22 clippy::wrong_self_convention,
28 extern crate option_helpers;
30 use std::collections::BTreeMap;
31 use std::collections::HashMap;
32 use std::collections::HashSet;
33 use std::collections::VecDeque;
34 use std::iter::FromIterator;
36 use std::rc::{self, Rc};
37 use std::sync::{self, Arc};
39 use option_helpers::IteratorFalsePositives;
44 pub fn add(self, other: T) -> T {
48 // no error, not public interface
49 pub(crate) fn drop(&mut self) {}
51 // no error, private function
52 fn neg(self) -> Self {
56 // no error, private function
57 fn eq(&self, other: T) -> bool {
61 // No error; self is a ref.
62 fn sub(&self, other: T) -> &T {
66 // No error; different number of arguments.
71 // No error; wrong return type.
72 fn rem(self, other: T) {}
75 fn into_u32(self) -> u32 {
79 fn into_u16(&self) -> u16 {
83 fn to_something(self) -> u32 {
87 fn new(self) -> Self {
97 // The lifetime is different, but that’s irrelevant; see issue #734.
98 #[allow(clippy::needless_lifetimes)]
99 pub fn new<'b>(s: &'b str) -> Lt<'b> {
109 // The lifetime is different, but that’s irrelevant; see issue #734.
110 pub fn new(s: &str) -> Lt2 {
120 // The lifetime is different, but that’s irrelevant; see issue #734.
121 pub fn new() -> Lt3<'static> {
126 #[derive(Clone, Copy)]
133 // Ok because `U` is `Copy`.
134 fn to_something(self) -> u32 {
144 fn new() -> Option<V<T>> {
152 async fn new() -> Option<Self> {
167 // No error, obviously.
168 fn mul(self, other: T) -> T {
173 /// Checks implementation of the following lints:
174 /// * `OPTION_MAP_UNWRAP_OR`
175 /// * `OPTION_MAP_UNWRAP_OR_ELSE`
177 fn option_methods() {
180 // Check `OPTION_MAP_UNWRAP_OR`.
182 let _ = opt.map(|x| x + 1)
183 // Should lint even though this call is on a separate line.
186 let _ = opt.map(|x| {
190 let _ = opt.map(|x| x + 1)
194 // Single line `map(f).unwrap_or(None)` case.
195 let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);
196 // Multi-line `map(f).unwrap_or(None)` cases.
197 let _ = opt.map(|x| {
202 .map(|x| Some(x + 1))
205 let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint
207 // Should not lint if not copyable
208 let id: String = "identifier".to_string();
209 let _ = Some("prefix").map(|p| format!("{}.{}", p, id)).unwrap_or(id);
210 // ...but DO lint if the `unwrap_or` argument is not used in the `map`
211 let id: String = "identifier".to_string();
212 let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id);
214 // Check OPTION_MAP_UNWRAP_OR_ELSE
216 let _ = opt.map(|x| x + 1)
217 // Should lint even though this call is on a separate line.
218 .unwrap_or_else(|| 0);
220 let _ = opt.map(|x| {
223 ).unwrap_or_else(|| 0);
224 let _ = opt.map(|x| x + 1)
230 let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0);
234 let mut frequencies = HashMap::new();
243 frequencies.insert(word.to_owned(), 1);
248 /// Checks implementation of `FILTER_NEXT` lint.
251 let v = vec![3, 2, 1, 0, -1, -2, -3];
254 let _ = v.iter().filter(|&x| *x < 0).next();
257 let _ = v.iter().filter(|&x| {
262 // Check that hat we don't lint if the caller is not an `Iterator`.
263 let foo = IteratorFalsePositives { foo: 0 };
264 let _ = foo.filter().next();
267 /// Checks implementation of `SEARCH_IS_SOME` lint.
269 fn search_is_some() {
270 let v = vec![3, 2, 1, 0, -1, -2, -3];
273 // Check `find().is_some()`, single-line case.
274 let _ = v.iter().find(|&x| *x < 0).is_some();
275 let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less
276 let _ = (0..1).find(|x| *x == 0).is_some();
277 let _ = v.iter().find(|x| **x == 0).is_some();
279 // Check `find().is_some()`, multi-line case.
280 let _ = v.iter().find(|&x| {
285 // Check `position().is_some()`, single-line case.
286 let _ = v.iter().position(|&x| x < 0).is_some();
288 // Check `position().is_some()`, multi-line case.
289 let _ = v.iter().position(|&x| {
294 // Check `rposition().is_some()`, single-line case.
295 let _ = v.iter().rposition(|&x| x < 0).is_some();
297 // Check `rposition().is_some()`, multi-line case.
298 let _ = v.iter().rposition(|&x| {
303 // Check that we don't lint if the caller is not an `Iterator`.
304 let foo = IteratorFalsePositives { foo: 0 };
305 let _ = foo.find().is_some();
306 let _ = foo.position().is_some();
307 let _ = foo.rposition().is_some();
310 #[allow(clippy::similar_names)]
313 let _ = opt.unwrap();