summaryrefslogtreecommitdiff
path: root/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
blob: c138d99d303280d835635f208bcc84b0a5035fb4 (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
123
124
125
126
127
128
129
130
131
132
133
// Test that or-patterns are pass-through with respect to default binding modes.

// check-pass

#![allow(irrefutable_let_patterns)]
#![allow(drop_copy)]
#![allow(drop_ref)]

fn main() {
    // A regression test for a mistake we made at one point:
    match &1 {
        e @ &(1..=2) | e @ &(3..=4) => {}
        _ => {}
    }

    match &0 {
        0 | &1 => {}
        _ => {}
    }

    type R<'a> = &'a Result<u8, u8>;

    let res: R<'_> = &Ok(0);

    match res {
        // Alternatives propagate expected type / binding mode independently.
        Ok(mut x) | &Err(mut x) => drop::<u8>(x),
    }
    match res {
        &(Ok(x) | Err(x)) => drop::<u8>(x),
    }
    match res {
        Ok(x) | Err(x) => drop::<&u8>(x),
    }
    if let Ok(mut x) | &Err(mut x) = res {
        drop::<u8>(x);
    }
    if let &(Ok(x) | Err(x)) = res {
        drop::<u8>(x);
    }
    let (Ok(mut x) | &Err(mut x)) = res;
    drop::<u8>(x);
    let &(Ok(x) | Err(x)) = res;
    drop::<u8>(x);
    let (Ok(x) | Err(x)) = res;
    drop::<&u8>(x);
    for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
        drop::<u8>(x);
    }
    for &(Ok(x) | Err(x)) in std::iter::once(res) {
        drop::<u8>(x);
    }
    for Ok(x) | Err(x) in std::iter::once(res) {
        drop::<&u8>(x);
    }
    fn f1((Ok(mut x) | &Err(mut x)): R<'_>) {
        drop::<u8>(x);
    }
    fn f2(&(Ok(x) | Err(x)): R<'_>) {
        drop::<u8>(x);
    }
    fn f3((Ok(x) | Err(x)): R<'_>) {
        drop::<&u8>(x);
    }

    // Wrap inside another type (a product for a simplity with irrefutable contexts).
    #[derive(Copy, Clone)]
    struct Wrap<T>(T);
    let wres = Wrap(res);

    match wres {
        Wrap(Ok(mut x) | &Err(mut x)) => drop::<u8>(x),
    }
    match wres {
        Wrap(&(Ok(x) | Err(x))) => drop::<u8>(x),
    }
    match wres {
        Wrap(Ok(x) | Err(x)) => drop::<&u8>(x),
    }
    if let Wrap(Ok(mut x) | &Err(mut x)) = wres {
        drop::<u8>(x);
    }
    if let Wrap(&(Ok(x) | Err(x))) = wres {
        drop::<u8>(x);
    }
    if let Wrap(Ok(x) | Err(x)) = wres {
        drop::<&u8>(x);
    }
    let Wrap(Ok(mut x) | &Err(mut x)) = wres;
    drop::<u8>(x);
    let Wrap(&(Ok(x) | Err(x))) = wres;
    drop::<u8>(x);
    let Wrap(Ok(x) | Err(x)) = wres;
    drop::<&u8>(x);
    for Wrap(Ok(mut x) | &Err(mut x)) in std::iter::once(wres) {
        drop::<u8>(x);
    }
    for Wrap(&(Ok(x) | Err(x))) in std::iter::once(wres) {
        drop::<u8>(x);
    }
    for Wrap(Ok(x) | Err(x)) in std::iter::once(wres) {
        drop::<&u8>(x);
    }
    fn fw1(Wrap(Ok(mut x) | &Err(mut x)): Wrap<R<'_>>) {
        drop::<u8>(x);
    }
    fn fw2(Wrap(&(Ok(x) | Err(x))): Wrap<R<'_>>) {
        drop::<u8>(x);
    }
    fn fw3(Wrap(Ok(x) | Err(x)): Wrap<R<'_>>) {
        drop::<&u8>(x);
    }

    // Nest some more:

    enum Tri<P> {
        A(P),
        B(P),
        C(P),
    }

    let tri = &Tri::A(&Ok(0));
    let (Tri::A(Ok(mut x) | Err(mut x))
    | Tri::B(&Ok(mut x) | Err(mut x))
    | &Tri::C(Ok(mut x) | Err(mut x))) = tri;
    drop::<u8>(x);

    match tri {
        Tri::A(Ok(mut x) | Err(mut x))
        | Tri::B(&Ok(mut x) | Err(mut x))
        | &Tri::C(Ok(mut x) | Err(mut x)) => drop::<u8>(x),
    }
}