1 // Test that or-patterns are pass-through with respect to default binding modes.
2 
3 // check-pass
4 
5 #![allow(irrefutable_let_patterns)]
6 
main()7 fn main() {
8     // A regression test for a mistake we made at one point:
9     match &1 {
10         e @ &(1..=2) | e @ &(3..=4) => {}
11         _ => {}
12     }
13 
14     match &0 {
15         0 | &1 => {}
16         _ => {}
17     }
18 
19     type R<'a> = &'a Result<u8, u8>;
20 
21     let res: R<'_> = &Ok(0);
22 
23     match res {
24         // Alternatives propagate expected type / binding mode independently.
25         Ok(mut x) | &Err(mut x) => drop::<u8>(x),
26     }
27     match res {
28         &(Ok(x) | Err(x)) => drop::<u8>(x),
29     }
30     match res {
31         Ok(x) | Err(x) => drop::<&u8>(x),
32     }
33     if let Ok(mut x) | &Err(mut x) = res {
34         drop::<u8>(x);
35     }
36     if let &(Ok(x) | Err(x)) = res {
37         drop::<u8>(x);
38     }
39     let (Ok(mut x) | &Err(mut x)) = res;
40     drop::<u8>(x);
41     let &(Ok(x) | Err(x)) = res;
42     drop::<u8>(x);
43     let (Ok(x) | Err(x)) = res;
44     drop::<&u8>(x);
45     for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
46         drop::<u8>(x);
47     }
48     for &(Ok(x) | Err(x)) in std::iter::once(res) {
49         drop::<u8>(x);
50     }
51     for Ok(x) | Err(x) in std::iter::once(res) {
52         drop::<&u8>(x);
53     }
54     fn f1((Ok(mut x) | &Err(mut x)): R<'_>) {
55         drop::<u8>(x);
56     }
57     fn f2(&(Ok(x) | Err(x)): R<'_>) {
58         drop::<u8>(x);
59     }
60     fn f3((Ok(x) | Err(x)): R<'_>) {
61         drop::<&u8>(x);
62     }
63 
64     // Wrap inside another type (a product for a simplity with irrefutable contexts).
65     #[derive(Copy, Clone)]
66     struct Wrap<T>(T);
67     let wres = Wrap(res);
68 
69     match wres {
70         Wrap(Ok(mut x) | &Err(mut x)) => drop::<u8>(x),
71     }
72     match wres {
73         Wrap(&(Ok(x) | Err(x))) => drop::<u8>(x),
74     }
75     match wres {
76         Wrap(Ok(x) | Err(x)) => drop::<&u8>(x),
77     }
78     if let Wrap(Ok(mut x) | &Err(mut x)) = wres {
79         drop::<u8>(x);
80     }
81     if let Wrap(&(Ok(x) | Err(x))) = wres {
82         drop::<u8>(x);
83     }
84     if let Wrap(Ok(x) | Err(x)) = wres {
85         drop::<&u8>(x);
86     }
87     let Wrap(Ok(mut x) | &Err(mut x)) = wres;
88     drop::<u8>(x);
89     let Wrap(&(Ok(x) | Err(x))) = wres;
90     drop::<u8>(x);
91     let Wrap(Ok(x) | Err(x)) = wres;
92     drop::<&u8>(x);
93     for Wrap(Ok(mut x) | &Err(mut x)) in std::iter::once(wres) {
94         drop::<u8>(x);
95     }
96     for Wrap(&(Ok(x) | Err(x))) in std::iter::once(wres) {
97         drop::<u8>(x);
98     }
99     for Wrap(Ok(x) | Err(x)) in std::iter::once(wres) {
100         drop::<&u8>(x);
101     }
102     fn fw1(Wrap(Ok(mut x) | &Err(mut x)): Wrap<R<'_>>) {
103         drop::<u8>(x);
104     }
105     fn fw2(Wrap(&(Ok(x) | Err(x))): Wrap<R<'_>>) {
106         drop::<u8>(x);
107     }
108     fn fw3(Wrap(Ok(x) | Err(x)): Wrap<R<'_>>) {
109         drop::<&u8>(x);
110     }
111 
112     // Nest some more:
113 
114     enum Tri<P> {
115         A(P),
116         B(P),
117         C(P),
118     }
119 
120     let tri = &Tri::A(&Ok(0));
121     let (Tri::A(Ok(mut x) | Err(mut x))
122     | Tri::B(&Ok(mut x) | Err(mut x))
123     | &Tri::C(Ok(mut x) | Err(mut x))) = tri;
124     drop::<u8>(x);
125 
126     match tri {
127         Tri::A(Ok(mut x) | Err(mut x))
128         | Tri::B(&Ok(mut x) | Err(mut x))
129         | &Tri::C(Ok(mut x) | Err(mut x)) => drop::<u8>(x),
130     }
131 }
132