]>
Commit | Line | Data |
---|---|---|
5869c6ff XL |
1 | // run-pass |
2 | ||
3 | // Test that move closures compile properly with `capture_disjoint_fields` enabled. | |
4 | ||
5 | #![feature(capture_disjoint_fields)] | |
6 | //~^ WARNING: the feature `capture_disjoint_fields` is incomplete | |
7 | ||
8 | fn simple_ref() { | |
9 | let mut s = 10; | |
10 | let ref_s = &mut s; | |
11 | ||
12 | let mut c = move || { | |
13 | *ref_s += 10; | |
14 | }; | |
15 | c(); | |
16 | } | |
17 | ||
18 | fn struct_contains_ref_to_another_struct() { | |
19 | struct S(String); | |
20 | struct T<'a>(&'a mut S); | |
21 | ||
22 | let mut s = S("s".into()); | |
23 | let t = T(&mut s); | |
24 | ||
25 | let mut c = move || { | |
26 | t.0.0 = "new s".into(); | |
27 | }; | |
28 | ||
29 | c(); | |
30 | } | |
31 | ||
32 | #[derive(Debug)] | |
33 | struct S(String); | |
34 | ||
35 | #[derive(Debug)] | |
36 | struct T(S); | |
37 | ||
38 | fn no_ref() { | |
39 | let mut t = T(S("s".into())); | |
40 | let mut c = move || { | |
41 | t.0.0 = "new S".into(); | |
42 | }; | |
43 | c(); | |
44 | } | |
45 | ||
46 | fn no_ref_nested() { | |
47 | let mut t = T(S("s".into())); | |
48 | let c = || { | |
49 | println!("{:?}", t.0); | |
50 | let mut c = move || { | |
51 | t.0.0 = "new S".into(); | |
52 | println!("{:?}", t.0.0); | |
53 | }; | |
54 | c(); | |
55 | }; | |
56 | c(); | |
57 | } | |
58 | ||
6a06907d XL |
59 | struct A<'a>(&'a mut String, &'a mut String); |
60 | // Test that reborrowing works as expected for move closures | |
61 | // by attempting a disjoint capture through a reference. | |
62 | fn disjoint_via_ref() { | |
63 | let mut x = String::new(); | |
64 | let mut y = String::new(); | |
65 | ||
66 | let mut a = A(&mut x, &mut y); | |
67 | let a = &mut a; | |
68 | ||
69 | let mut c1 = move || { | |
70 | a.0.truncate(0); | |
71 | }; | |
72 | ||
73 | let mut c2 = move || { | |
74 | a.1.truncate(0); | |
75 | }; | |
76 | ||
77 | c1(); | |
78 | c2(); | |
79 | } | |
80 | ||
81 | // Test that even if a path is moved into the closure, the closure is not FnOnce | |
82 | // if the path is not moved by the closure call. | |
83 | fn data_moved_but_not_fn_once() { | |
84 | let x = Box::new(10i32); | |
85 | ||
86 | let c = move || { | |
87 | // *x has type i32 which is Copy. So even though the box `x` will be moved | |
88 | // into the closure, `x` is never moved when the closure is called, i.e. the | |
89 | // ownership stays with the closure and therefore we can call the function multiple times. | |
90 | let _x = *x; | |
91 | }; | |
92 | ||
93 | c(); | |
94 | c(); | |
95 | } | |
96 | ||
5869c6ff XL |
97 | fn main() { |
98 | simple_ref(); | |
99 | struct_contains_ref_to_another_struct(); | |
100 | no_ref(); | |
101 | no_ref_nested(); | |
6a06907d XL |
102 | |
103 | disjoint_via_ref(); | |
104 | data_moved_but_not_fn_once(); | |
5869c6ff | 105 | } |