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