]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/rfc-2005-default-binding-mode/general.rs
779a38bdb16720ef190af42db0d83697d976a0f8
[rust.git] / src / test / run-pass / rfc-2005-default-binding-mode / general.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![feature(match_default_bindings)]
12
13 fn some_or_wildcard(r: &Option<i32>, b: &i32) {
14     let _: &i32 = match r {
15         Some(a) => a,
16         _ => b,
17     };
18 }
19
20 fn none_or_wildcard(r: &Option<i32>, b: &i32) {
21     let _: &i32 = match r {
22         None => b,
23         _ => b,
24     };
25 }
26
27 fn some_or_ref_none(r: &Option<i32>, b: &i32) {
28     let _: &i32 = match r {
29         Some(a) => a,
30         &None => b,
31     };
32 }
33
34 fn ref_some_or_none(r: &Option<i32>, b: &i32) {
35     let _: &i32 = match r {
36         &Some(ref a) => a,
37         None => b,
38     };
39 }
40
41 fn some_or_self(r: &Option<i32>) {
42     let _: &Option<i32> = match r {
43         Some(n) => {
44             let _: &i32 = n;
45             r
46         },
47         x => x,
48     };
49 }
50
51 fn multiple_deref(r: &&&&&Option<i32>) {
52     let _: i32 = match r {
53         Some(a) => *a,
54         None => 5,
55     };
56 }
57
58 fn match_with_or() {
59     // FIXME(tschottdorf): #44912.
60     //
61     // let x = &Some((3, 3));
62     // let _: &i32 = match x {
63     //     Some((x, 3)) | &Some((ref x, 5)) => x,
64     //     _ => &5i32,
65     // };
66 }
67
68 fn nested_mixed() {
69     match (&Some(5), &Some(6)) {
70         (Some(a), &Some(mut b)) => {
71             // Here, the `a` will be `&i32`, because in the first half of the tuple
72             // we hit a non-reference pattern and shift into `ref` mode.
73             //
74             // In the second half of the tuple there's no non-reference pattern,
75             // so `b` will be `i32` (bound with `move` mode). Moreover, `b` is
76             // mutable.
77             let _: &i32 = a;
78             b = 7;
79             let _: i32 = b;
80         },
81         _ => {},
82     };
83 }
84
85 fn nested_mixed_multiple_deref_1() {
86     let x = (1, &Some(5));
87     let y = &Some(x);
88     match y {
89         Some((a, Some(b))) => {
90             let _: &i32 = a;
91             let _: &i32 = b;
92         },
93         _ => {},
94     };
95 }
96
97 fn nested_mixed_multiple_deref_2() {
98     let x = &Some(5);
99     let y = &x;
100     match y {
101         Some(z) => {
102             let _: &i32 = z;
103         },
104         _ => {},
105     }
106 }
107
108 fn new_mutable_reference() {
109     let mut x = &mut Some(5);
110     match &mut x {
111         Some(y) => {
112             *y = 5;
113         },
114         None => { },
115     }
116
117     match &mut x {
118         Some(y) => {
119             println!("{}", *y);
120         },
121         None => {},
122     }
123 }
124
125 fn let_implicit_ref_binding() {
126     struct Foo(i32);
127
128     // Note that these rules apply to any pattern matching
129     // whether it be in a `match` or a `let`.
130     // For example, `x` here is a `ref` binding:
131     let Foo(x) = &Foo(3);
132     let _: &i32 = x;
133 }
134
135 fn explicit_mut_binding() {
136     match &Some(5i32) {
137         Some(mut n) => {
138             n += 1;
139             let _ = n;
140         }
141         None => {},
142     };
143
144     match &mut Some(5i32) {
145         Some(n) => {
146             *n += 1;
147             let _ = n;
148         }
149         None => {},
150     };
151
152     match &mut &mut Some(5i32) {
153         Some(n) => {
154              let _: &mut i32 = n;
155         }
156         None => {},
157     };
158 }
159
160 fn tuple_mut_and_mut_mut() {
161     match (Some(5i32), &Some(5i32)) {
162         (Some(n), Some(m)) => {
163             // `n` and `m` are bound as immutable references. Make new references from them to
164             // assert that.
165             let r = n;
166             let _ = r;
167             let q = m;
168             let _ = q;
169
170             // Assert the types. Note that we use `n` and `m` here which would fail had they been
171             // moved due to the assignments above.
172             let _: i32 = n;
173             let _: &i32 = m;
174         }
175         (_, _) => {},
176     };
177
178     match (&Some(5i32), &&Some(5i32)) {
179         (Some(n), Some(m)) => {
180             let _: &i32 = n;
181             let _: &i32 = m;
182         }
183         (_, _) => {},
184     };
185
186     match &mut &mut (Some(5i32), Some(5i32)) {
187         (Some(n), Some(m)) => {
188             // Dereferenced through &mut &mut, so a mutable binding results.
189             let _: &mut i32 = n;
190             let _: &mut i32 = m;
191         }
192         (_, _) => {},
193     };
194
195     match (&mut Some(5i32), &mut &mut Some(5i32)) {
196         (Some(n), Some(m)) => {
197             let _: &mut i32 = n;
198             let _: &mut i32 = m;
199         }
200         (_, _) => {},
201     };
202 }
203
204 fn min_mir_embedded_type() {
205     // The reduced invocation that an ICE was diagnosed with (was consuming
206     // adjustments in wrong order).
207     match (0u8, &&Some(5i32)) {
208         (_, Some(m)) => {
209             let _: &i32 = m;
210         }
211         (_, _) => {},
212     };
213 }
214
215 fn no_autoderef() {
216     // Binding.
217     let x = &3;
218     println!("{}", *x);
219
220     // Wildcard.
221     let _ = &3;
222
223     // Constant of generic type (string)
224     const Y: &'static str = "foo";
225     assert_eq!(0, match "foo" {
226         Y => 0,
227         _ => 1,
228     });
229
230     // Reference pattern.
231     let &x = &3;
232 }
233
234 pub fn main() {
235     let r: &Option<i32> = &Some(3);
236     let b = &4i32;
237
238     none_or_wildcard(r, b);
239     some_or_wildcard(r, b);
240     some_or_ref_none(r, b);
241     ref_some_or_none(r, b);
242
243     some_or_self(r);
244     multiple_deref(&&&&r);
245     match_with_or();
246
247     nested_mixed();
248     nested_mixed_multiple_deref_1();
249     nested_mixed_multiple_deref_2();
250
251     new_mutable_reference();
252     explicit_mut_binding();
253     tuple_mut_and_mut_mut();
254     min_mir_embedded_type();
255
256     let_implicit_ref_binding();
257
258     no_autoderef();
259 }