]> git.lizzy.rs Git - rust.git/blob - tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs
Rollup merge of #107171 - petrochenkov:encattrs, r=cjgillot
[rust.git] / tests / ui / unboxed-closures / unboxed-closures-mutate-upvar.rs
1 // Test that we cannot mutate an outer variable that is not declared
2 // as `mut` through a closure. Also test that we CAN mutate a moved copy,
3 // unless this is a `Fn` closure. Issue #16749.
4
5 #![feature(unboxed_closures, tuple_trait)]
6
7 use std::mem;
8
9 fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f }
10 fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
11
12 fn a() {
13     let n = 0;
14     let mut f = to_fn_mut(|| {
15         n += 1; //~ ERROR cannot assign to `n`, as it is not declared as mutable
16     });
17 }
18
19 fn b() {
20     let mut n = 0;
21     let mut f = to_fn_mut(|| {
22         n += 1; // OK
23     });
24 }
25
26 fn c() {
27     let n = 0;
28     let mut f = to_fn_mut(move || {
29         // If we just did a straight-forward desugaring, this would
30         // compile, but we do something a bit more subtle, and hence
31         // we get an error.
32         n += 1; //~ ERROR cannot assign
33     });
34 }
35
36 fn d() {
37     let mut n = 0;
38     let mut f = to_fn_mut(move || {
39         n += 1; // OK
40     });
41 }
42
43 fn e() {
44     let n = 0;
45     let mut f = to_fn(move || {
46         n += 1; //~ ERROR cannot assign
47     });
48 }
49
50 fn f() {
51     let mut n = 0;
52     let mut f = to_fn(move || {
53         n += 1; //~ ERROR cannot assign
54     });
55 }
56
57 fn main() { }