diff options
Diffstat (limited to 'tests/ui/nll/match-guards-partially-borrow.rs')
-rw-r--r-- | tests/ui/nll/match-guards-partially-borrow.rs | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/tests/ui/nll/match-guards-partially-borrow.rs b/tests/ui/nll/match-guards-partially-borrow.rs new file mode 100644 index 000000000..3a9e1654b --- /dev/null +++ b/tests/ui/nll/match-guards-partially-borrow.rs @@ -0,0 +1,332 @@ +// Test that a (partially) mutably borrowed place can be matched on, so long as +// we don't have to read any values that are mutably borrowed to determine +// which arm to take. +// +// Test that we don't allow mutating the value being matched on in a way that +// changes which patterns it matches, until we have chosen an arm. + +#![feature(if_let_guard)] + +fn ok_mutation_in_if_guard(mut q: i32) { + match q { + // OK, mutation doesn't change which patterns g matches + _ if { q = 1; false } => (), + _ => (), + } +} + +fn ok_mutation_in_if_let_guard(mut q: i32) { + match q { + // OK, mutation doesn't change which patterns g matches + _ if let Some(()) = { q = 1; None } => (), + _ => (), + } +} + +fn ok_mutation_in_if_guard2(mut u: bool) { + // OK value of u is unused before modification + match u { + _ => (), + _ if { + u = true; + false + } => (), + x => (), + } +} + +fn ok_mutation_in_if_let_guard2(mut u: bool) { + // OK value of u is unused before modification + match u { + _ => (), + _ if let Some(()) = { + u = true; + None + } => (), + x => (), + } +} + +fn ok_mutation_in_if_guard4(mut w: (&mut bool,)) { + // OK value of u is unused before modification + match w { + _ => (), + _ if { + *w.0 = true; + false + } => (), + x => (), + } +} + +fn ok_mutation_in_if_let_guard4(mut w: (&mut bool,)) { + // OK value of u is unused before modification + match w { + _ => (), + _ if let Some(()) = { + *w.0 = true; + None + } => (), + x => (), + } +} + +fn ok_indirect_mutation_in_if_guard(mut p: &bool) { + match *p { + // OK, mutation doesn't change which patterns s matches + _ if { + p = &true; + false + } => (), + _ => (), + } +} + +fn ok_indirect_mutation_in_if_let_guard(mut p: &bool) { + match *p { + // OK, mutation doesn't change which patterns s matches + _ if let Some(()) = { + p = &true; + None + } => (), + _ => (), + } +} + +fn mutation_invalidates_pattern_in_if_guard(mut q: bool) { + match q { + // q doesn't match the pattern with the guard by the end of the guard. + false if { + q = true; //~ ERROR + true + } => (), + _ => (), + } +} + +fn mutation_invalidates_pattern_in_if_let_guard(mut q: bool) { + match q { + // q doesn't match the pattern with the guard by the end of the guard. + false if let Some(()) = { + q = true; //~ ERROR + Some(()) + } => (), + _ => (), + } +} + +fn mutation_invalidates_previous_pattern_in_if_guard(mut r: bool) { + match r { + // r matches a previous pattern by the end of the guard. + true => (), + _ if { + r = true; //~ ERROR + true + } => (), + _ => (), + } +} + +fn mutation_invalidates_previous_pattern_in_if_let_guard(mut r: bool) { + match r { + // r matches a previous pattern by the end of the guard. + true => (), + _ if let Some(()) = { + r = true; //~ ERROR + Some(()) + } => (), + _ => (), + } +} + +fn match_on_borrowed_early_end_if_guard(mut s: bool) { + let h = &mut s; + // OK value of s is unused before modification. + match s { + _ if { + *h = !*h; + false + } => (), + true => (), + false => (), + } +} + +fn match_on_borrowed_early_end_if_let_guard(mut s: bool) { + let h = &mut s; + // OK value of s is unused before modification. + match s { + _ if let Some(()) = { + *h = !*h; + None + } => (), + true => (), + false => (), + } +} + +fn bad_mutation_in_if_guard(mut t: bool) { + match t { + true => (), + false if { + t = true; //~ ERROR + false + } => (), + false => (), + } +} + +fn bad_mutation_in_if_let_guard(mut t: bool) { + match t { + true => (), + false if let Some(()) = { + t = true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_mutation_in_if_guard2(mut x: Option<Option<&i32>>) { + // Check that nested patterns are checked. + match x { + None => (), + Some(None) => (), + _ if { + match x { + Some(ref mut r) => *r = None, //~ ERROR + _ => return, + }; + false + } => (), + Some(Some(r)) => println!("{}", r), + } +} + +fn bad_mutation_in_if_let_guard2(mut x: Option<Option<&i32>>) { + // Check that nested patterns are checked. + match x { + None => (), + Some(None) => (), + _ if let Some(()) = { + match x { + Some(ref mut r) => *r = None, //~ ERROR + _ => return, + }; + None + } => (), + Some(Some(r)) => println!("{}", r), + } +} + +fn bad_mutation_in_if_guard3(mut t: bool) { + match t { + s if { + t = !t; //~ ERROR + false + } => (), // What value should `s` have in the arm? + _ => (), + } +} + +fn bad_mutation_in_if_let_guard3(mut t: bool) { + match t { + s if let Some(()) = { + t = !t; //~ ERROR + None + } => (), // What value should `s` have in the arm? + _ => (), + } +} + +fn bad_indirect_mutation_in_if_guard(mut y: &bool) { + match *y { + true => (), + false if { + y = &true; //~ ERROR + false + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_let_guard(mut y: &bool) { + match *y { + true => (), + false if let Some(()) = { + y = &true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_guard2(mut z: &bool) { + match z { + &true => (), + &false if { + z = &true; //~ ERROR + false + } => (), + &false => (), + } +} + +fn bad_indirect_mutation_in_if_let_guard2(mut z: &bool) { + match z { + &true => (), + &false if let Some(()) = { + z = &true; //~ ERROR + None + } => (), + &false => (), + } +} + +fn bad_indirect_mutation_in_if_guard3(mut a: &bool) { + // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics + match a { + true => (), + false if { + a = &true; //~ ERROR + false + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_let_guard3(mut a: &bool) { + // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics + match a { + true => (), + false if let Some(()) = { + a = &true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_guard4(mut b: &bool) { + match b { + &_ => (), + &_ if { + b = &true; //~ ERROR + false + } => (), + &b => (), + } +} + +fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) { + match b { + &_ => (), + &_ if let Some(()) = { + b = &true; //~ ERROR + None + } => (), + &b => (), + } +} + +fn main() {} |