summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
blob: 556fd3a35427c1abd83e5b65d40c135fd2453ed2 (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#![warn(clippy::needless_borrowed_reference)]
#![allow(
    unused,
    irrefutable_let_patterns,
    non_shorthand_field_patterns,
    clippy::needless_borrow,
    clippy::needless_if
)]

fn main() {}

struct Struct {
    a: usize,
    b: usize,
    c: usize,
}

struct TupleStruct(u8, u8, u8);

fn should_lint(
    array: [u8; 4],
    slice: &[u8],
    slice_of_refs: &[&u8],
    vec: Vec<u8>,
    tuple: (u8, u8, u8),
    tuple_struct: TupleStruct,
    s: Struct,
) {
    let mut v = Vec::<String>::new();
    let _ = v.iter_mut().filter(|&ref a| a.is_empty());

    let var = 3;
    let thingy = Some(&var);
    if let Some(&ref v) = thingy {}

    if let &[&ref a, ref b] = slice_of_refs {}

    let &[ref a, ..] = &array;
    let &[ref a, ref b, ..] = &array;

    if let &[ref a, ref b] = slice {}
    if let &[ref a, ref b] = &vec[..] {}

    if let &[ref a, ref b, ..] = slice {}
    if let &[ref a, .., ref b] = slice {}
    if let &[.., ref a, ref b] = slice {}

    if let &[ref a, _] = slice {}

    if let &(ref a, ref b, ref c) = &tuple {}
    if let &(ref a, _, ref c) = &tuple {}
    if let &(ref a, ..) = &tuple {}

    if let &TupleStruct(ref a, ..) = &tuple_struct {}

    if let &Struct {
        ref a,
        b: ref b,
        c: ref renamed,
    } = &s
    {}

    if let &Struct { ref a, b: _, .. } = &s {}
}

fn should_not_lint(
    array: [u8; 4],
    slice: &[u8],
    slice_of_refs: &[&u8],
    vec: Vec<u8>,
    tuple: (u8, u8, u8),
    tuple_struct: TupleStruct,
    s: Struct,
) {
    if let [ref a] = slice {}
    if let &[ref a, b] = slice {}
    if let &[ref a, .., b] = slice {}

    if let &(ref a, b, ..) = &tuple {}
    if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
    if let &Struct { ref a, b, .. } = &s {}

    // must not be removed as variables must be bound consistently across | patterns
    if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}

    // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
    // the lint name
    if let &[] = slice {}
    if let &[_] = slice {}
    if let &[..] = slice {}
    if let &(..) = &tuple {}
    if let &TupleStruct(..) = &tuple_struct {}
    if let &Struct { .. } = &s {}

    let mut var2 = 5;
    let thingy2 = Some(&mut var2);
    if let Some(&mut ref mut v) = thingy2 {
        //          ^ should **not** be linted
        // v is borrowed as mutable.
        *v = 10;
    }
    if let Some(&mut ref v) = thingy2 {
        //          ^ should **not** be linted
        // here, v is borrowed as immutable.
        // can't do that:
        //*v = 15;
    }
}

enum Animal {
    Cat(u64),
    Dog(u64),
}

fn foo(a: &Animal, b: &Animal) {
    match (a, b) {
        // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
        //                  ^    and   ^ should **not** be linted
        (Animal::Dog(a), &Animal::Dog(_)) => (),
    }
}