]> git.proxmox.com Git - rustc.git/blame - src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / test / ui / closures / 2229_closure_analysis / run_pass / move_closure.rs
CommitLineData
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
8fn 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
18fn 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)]
33struct S(String);
34
35#[derive(Debug)]
36struct T(S);
37
38fn 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
46fn 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
59struct 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.
62fn 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.
83fn 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
97fn 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}