summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
blob: 58c374ab8cd1025ed0793de99f1482f7ed87aa8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
#![allow(dead_code, clippy::let_unit_value, clippy::useless_vec)]

fn main() {
    let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];

    let _: Option<String> = vec.iter().cloned().last();

    let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();

    let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();

    let _: Vec<_> = vec.iter().cloned().take(2).collect();

    let _: Vec<_> = vec.iter().cloned().skip(2).collect();

    let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);

    let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
        .iter()
        .cloned()
        .flatten();

    let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));

    let _ = vec.iter().cloned().find(|x| x == "2");

    {
        let f = |x: &String| x.starts_with('2');
        let _ = vec.iter().cloned().filter(f);
        let _ = vec.iter().cloned().find(f);
    }

    {
        let vec: Vec<(String, String)> = vec![];
        let f = move |x: &(String, String)| x.0.starts_with('2');
        let _ = vec.iter().cloned().filter(f);
        let _ = vec.iter().cloned().find(f);
    }

    fn test_move<'a>(
        iter: impl Iterator<Item = &'a (&'a u32, String)> + 'a,
        target: String,
    ) -> impl Iterator<Item = (&'a u32, String)> + 'a {
        iter.cloned().filter(move |(&a, b)| a == 1 && b == &target)
    }

    {
        #[derive(Clone)]
        struct S<'a> {
            a: &'a u32,
            b: String,
        }

        fn bar<'a>(iter: impl Iterator<Item = &'a S<'a>> + 'a, target: String) -> impl Iterator<Item = S<'a>> + 'a {
            iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target)
        }
    }

    let _ = vec.iter().cloned().map(|x| x.len());

    // This would fail if changed.
    let _ = vec.iter().cloned().map(|x| x + "2");

    let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));

    let _ = vec.iter().cloned().all(|x| x.len() == 1);

    let _ = vec.iter().cloned().any(|x| x.len() == 1);

    // Should probably stay as it is.
    let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);

    // `&Range<_>` doesn't implement `IntoIterator`
    let _ = [0..1, 2..5].iter().cloned().flatten();
}

// #8527
fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
    x.cloned().flatten()
}