]> git.lizzy.rs Git - rust.git/blob - tests/ui/nll/match-guards-partially-borrow.rs
Auto merge of #101138 - Rejyr:diagnostic-migration-rustc-lint-pt2, r=davidtwco
[rust.git] / tests / ui / nll / match-guards-partially-borrow.rs
1 // Test that a (partially) mutably borrowed place can be matched on, so long as
2 // we don't have to read any values that are mutably borrowed to determine
3 // which arm to take.
4 //
5 // Test that we don't allow mutating the value being matched on in a way that
6 // changes which patterns it matches, until we have chosen an arm.
7
8 #![feature(if_let_guard)]
9
10 fn ok_mutation_in_if_guard(mut q: i32) {
11     match q {
12         // OK, mutation doesn't change which patterns g matches
13         _ if { q = 1; false } => (),
14         _ => (),
15     }
16 }
17
18 fn ok_mutation_in_if_let_guard(mut q: i32) {
19     match q {
20         // OK, mutation doesn't change which patterns g matches
21         _ if let Some(()) = { q = 1; None } => (),
22         _ => (),
23     }
24 }
25
26 fn ok_mutation_in_if_guard2(mut u: bool) {
27     // OK value of u is unused before modification
28     match u {
29         _ => (),
30         _ if {
31             u = true;
32             false
33         } => (),
34         x => (),
35     }
36 }
37
38 fn ok_mutation_in_if_let_guard2(mut u: bool) {
39     // OK value of u is unused before modification
40     match u {
41         _ => (),
42         _ if let Some(()) = {
43             u = true;
44             None
45         } => (),
46         x => (),
47     }
48 }
49
50 fn ok_mutation_in_if_guard4(mut w: (&mut bool,)) {
51     // OK value of u is unused before modification
52     match w {
53         _ => (),
54         _ if {
55             *w.0 = true;
56             false
57         } => (),
58         x => (),
59     }
60 }
61
62 fn ok_mutation_in_if_let_guard4(mut w: (&mut bool,)) {
63     // OK value of u is unused before modification
64     match w {
65         _ => (),
66         _ if let Some(()) = {
67             *w.0 = true;
68             None
69         } => (),
70         x => (),
71     }
72 }
73
74 fn ok_indirect_mutation_in_if_guard(mut p: &bool) {
75     match *p {
76         // OK, mutation doesn't change which patterns s matches
77         _ if {
78             p = &true;
79             false
80         } => (),
81         _ => (),
82     }
83 }
84
85 fn ok_indirect_mutation_in_if_let_guard(mut p: &bool) {
86     match *p {
87         // OK, mutation doesn't change which patterns s matches
88         _ if let Some(()) = {
89             p = &true;
90             None
91         } => (),
92         _ => (),
93     }
94 }
95
96 fn mutation_invalidates_pattern_in_if_guard(mut q: bool) {
97     match q {
98         // q doesn't match the pattern with the guard by the end of the guard.
99         false if {
100             q = true; //~ ERROR
101             true
102         } => (),
103         _ => (),
104     }
105 }
106
107 fn mutation_invalidates_pattern_in_if_let_guard(mut q: bool) {
108     match q {
109         // q doesn't match the pattern with the guard by the end of the guard.
110         false if let Some(()) = {
111             q = true; //~ ERROR
112             Some(())
113         } => (),
114         _ => (),
115     }
116 }
117
118 fn mutation_invalidates_previous_pattern_in_if_guard(mut r: bool) {
119     match r {
120         // r matches a previous pattern by the end of the guard.
121         true => (),
122         _ if {
123             r = true; //~ ERROR
124             true
125         } => (),
126         _ => (),
127     }
128 }
129
130 fn mutation_invalidates_previous_pattern_in_if_let_guard(mut r: bool) {
131     match r {
132         // r matches a previous pattern by the end of the guard.
133         true => (),
134         _ if let Some(()) = {
135             r = true; //~ ERROR
136             Some(())
137         } => (),
138         _ => (),
139     }
140 }
141
142 fn match_on_borrowed_early_end_if_guard(mut s: bool) {
143     let h = &mut s;
144     // OK value of s is unused before modification.
145     match s {
146         _ if {
147             *h = !*h;
148             false
149         } => (),
150         true => (),
151         false => (),
152     }
153 }
154
155 fn match_on_borrowed_early_end_if_let_guard(mut s: bool) {
156     let h = &mut s;
157     // OK value of s is unused before modification.
158     match s {
159         _ if let Some(()) = {
160             *h = !*h;
161             None
162         } => (),
163         true => (),
164         false => (),
165     }
166 }
167
168 fn bad_mutation_in_if_guard(mut t: bool) {
169     match t {
170         true => (),
171         false if {
172             t = true; //~ ERROR
173             false
174         } => (),
175         false => (),
176     }
177 }
178
179 fn bad_mutation_in_if_let_guard(mut t: bool) {
180     match t {
181         true => (),
182         false if let Some(()) = {
183             t = true; //~ ERROR
184             None
185         } => (),
186         false => (),
187     }
188 }
189
190 fn bad_mutation_in_if_guard2(mut x: Option<Option<&i32>>) {
191     // Check that nested patterns are checked.
192     match x {
193         None => (),
194         Some(None) => (),
195         _ if {
196             match x {
197                 Some(ref mut r) => *r = None, //~ ERROR
198                 _ => return,
199             };
200             false
201         } => (),
202         Some(Some(r)) => println!("{}", r),
203     }
204 }
205
206 fn bad_mutation_in_if_let_guard2(mut x: Option<Option<&i32>>) {
207     // Check that nested patterns are checked.
208     match x {
209         None => (),
210         Some(None) => (),
211         _ if let Some(()) = {
212             match x {
213                 Some(ref mut r) => *r = None, //~ ERROR
214                 _ => return,
215             };
216             None
217         } => (),
218         Some(Some(r)) => println!("{}", r),
219     }
220 }
221
222 fn bad_mutation_in_if_guard3(mut t: bool) {
223     match t {
224         s if {
225             t = !t; //~ ERROR
226             false
227         } => (), // What value should `s` have in the arm?
228         _ => (),
229     }
230 }
231
232 fn bad_mutation_in_if_let_guard3(mut t: bool) {
233     match t {
234         s if let Some(()) = {
235             t = !t; //~ ERROR
236             None
237         } => (), // What value should `s` have in the arm?
238         _ => (),
239     }
240 }
241
242 fn bad_indirect_mutation_in_if_guard(mut y: &bool) {
243     match *y {
244         true => (),
245         false if {
246             y = &true; //~ ERROR
247             false
248         } => (),
249         false => (),
250     }
251 }
252
253 fn bad_indirect_mutation_in_if_let_guard(mut y: &bool) {
254     match *y {
255         true => (),
256         false if let Some(()) = {
257             y = &true; //~ ERROR
258             None
259         } => (),
260         false => (),
261     }
262 }
263
264 fn bad_indirect_mutation_in_if_guard2(mut z: &bool) {
265     match z {
266         &true => (),
267         &false if {
268             z = &true; //~ ERROR
269             false
270         } => (),
271         &false => (),
272     }
273 }
274
275 fn bad_indirect_mutation_in_if_let_guard2(mut z: &bool) {
276     match z {
277         &true => (),
278         &false if let Some(()) = {
279             z = &true; //~ ERROR
280             None
281         } => (),
282         &false => (),
283     }
284 }
285
286 fn bad_indirect_mutation_in_if_guard3(mut a: &bool) {
287     // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
288     match a {
289         true => (),
290         false if {
291             a = &true; //~ ERROR
292             false
293         } => (),
294         false => (),
295     }
296 }
297
298 fn bad_indirect_mutation_in_if_let_guard3(mut a: &bool) {
299     // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
300     match a {
301         true => (),
302         false if let Some(()) = {
303             a = &true; //~ ERROR
304             None
305         } => (),
306         false => (),
307     }
308 }
309
310 fn bad_indirect_mutation_in_if_guard4(mut b: &bool) {
311     match b {
312         &_ => (),
313         &_ if {
314             b = &true; //~ ERROR
315             false
316         } => (),
317         &b => (),
318     }
319 }
320
321 fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) {
322     match b {
323         &_ => (),
324         &_ if let Some(()) = {
325             b = &true; //~ ERROR
326             None
327         } => (),
328         &b => (),
329     }
330 }
331
332 fn main() {}