]> git.proxmox.com Git - rustc.git/blob - src/test/ui/closures/2229_closure_analysis/move_closure.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / src / test / ui / closures / 2229_closure_analysis / move_closure.rs
1 // edition:2021
2
3 // Test that move closures drop derefs with `capture_disjoint_fields` enabled.
4
5 #![feature(rustc_attrs)]
6
7 fn simple_move_closure() {
8 struct S(String);
9 struct T(S);
10
11 let t = T(S("s".into()));
12 let mut c = #[rustc_capture_analysis]
13 //~^ ERROR: attributes on expressions are experimental
14 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
15 move || {
16 //~^ ERROR: First Pass analysis includes:
17 //~| ERROR: Min Capture analysis includes:
18 t.0.0 = "new S".into();
19 //~^ NOTE: Capturing t[(0, 0),(0, 0)] -> MutBorrow
20 //~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
21 };
22 c();
23 }
24
25 // Test move closure use reborrows when using references
26 fn simple_ref() {
27 let mut s = 10;
28 let ref_s = &mut s;
29
30 let mut c = #[rustc_capture_analysis]
31 //~^ ERROR: attributes on expressions are experimental
32 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
33 move || {
34 //~^ ERROR: First Pass analysis includes:
35 //~| ERROR: Min Capture analysis includes:
36 *ref_s += 10;
37 //~^ NOTE: Capturing ref_s[Deref] -> MutBorrow
38 //~| NOTE: Min Capture ref_s[] -> ByValue
39 };
40 c();
41 }
42
43 // Test move closure use reborrows when using references
44 fn struct_contains_ref_to_another_struct_1() {
45 struct S(String);
46 struct T<'a>(&'a mut S);
47
48 let mut s = S("s".into());
49 let t = T(&mut s);
50
51 let mut c = #[rustc_capture_analysis]
52 //~^ ERROR: attributes on expressions are experimental
53 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
54 move || {
55 //~^ ERROR: First Pass analysis includes:
56 //~| ERROR: Min Capture analysis includes:
57 t.0.0 = "new s".into();
58 //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> MutBorrow
59 //~| NOTE: Min Capture t[(0, 0)] -> ByValue
60 };
61
62 c();
63 }
64
65 // Test that we can use reborrows to read data of Copy types
66 // i.e. without truncating derefs
67 fn struct_contains_ref_to_another_struct_2() {
68 struct S(i32);
69 struct T<'a>(&'a S);
70
71 let s = S(0);
72 let t = T(&s);
73
74 let mut c = #[rustc_capture_analysis]
75 //~^ ERROR: attributes on expressions are experimental
76 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
77 move || {
78 //~^ ERROR: First Pass analysis includes:
79 //~| ERROR: Min Capture analysis includes:
80 let _t = t.0.0;
81 //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
82 //~| NOTE: Min Capture t[(0, 0)] -> ByValue
83 };
84
85 c();
86 }
87
88 // Test that we can use truncate to move out of !Copy types
89 fn struct_contains_ref_to_another_struct_3() {
90 struct S(String);
91 struct T<'a>(&'a S);
92
93 let s = S("s".into());
94 let t = T(&s);
95
96 let mut c = #[rustc_capture_analysis]
97 //~^ ERROR: attributes on expressions are experimental
98 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
99 move || {
100 //~^ ERROR: First Pass analysis includes:
101 //~| ERROR: Min Capture analysis includes:
102 let _t = t.0.0;
103 //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
104 //~| NOTE: Min Capture t[(0, 0)] -> ByValue
105 };
106
107 c();
108 }
109
110 // Test that derefs of box are truncated in move closures
111 fn truncate_box_derefs() {
112 struct S(i32);
113
114
115 // Content within the box is moved within the closure
116 let b = Box::new(S(10));
117 let c = #[rustc_capture_analysis]
118 //~^ ERROR: attributes on expressions are experimental
119 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
120 move || {
121 //~^ ERROR: First Pass analysis includes:
122 //~| ERROR: Min Capture analysis includes:
123 let _t = b.0;
124 //~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
125 //~| NOTE: Min Capture b[] -> ByValue
126 };
127
128 c();
129
130 // Content within the box is used by a shared ref and the box is the root variable
131 let b = Box::new(S(10));
132
133 let c = #[rustc_capture_analysis]
134 //~^ ERROR: attributes on expressions are experimental
135 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
136 move || {
137 //~^ ERROR: First Pass analysis includes:
138 //~| ERROR: Min Capture analysis includes:
139 println!("{}", b.0);
140 //~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
141 //~| NOTE: Min Capture b[] -> ByValue
142 };
143
144 c();
145
146 // Content within the box is used by a shared ref and the box is not the root variable
147 let b = Box::new(S(10));
148 let t = (0, b);
149
150 let c = #[rustc_capture_analysis]
151 //~^ ERROR: attributes on expressions are experimental
152 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
153 move || {
154 //~^ ERROR: First Pass analysis includes:
155 //~| ERROR: Min Capture analysis includes:
156 println!("{}", t.1.0);
157 //~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ImmBorrow
158 //~| NOTE: Min Capture t[(1, 0)] -> ByValue
159 };
160 }
161
162 struct Foo { x: i32 }
163
164 // Ensure that even in move closures, if the data is not owned by the root variable
165 // then we don't truncate the derefs or a ByValue capture, rather do a reborrow
166 fn box_mut_1() {
167 let mut foo = Foo { x: 0 } ;
168
169 let p_foo = &mut foo;
170 let box_p_foo = Box::new(p_foo);
171
172 let c = #[rustc_capture_analysis] move || box_p_foo.x += 10;
173 //~^ ERROR: attributes on expressions are experimental
174 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
175 //~| First Pass analysis includes:
176 //~| NOTE: Capturing box_p_foo[Deref,Deref,(0, 0)] -> MutBorrow
177 //~| Min Capture analysis includes:
178 //~| NOTE: Min Capture box_p_foo[] -> ByValue
179 }
180
181 // Ensure that even in move closures, if the data is not owned by the root variable
182 // then we don't truncate the derefs or a ByValue capture, rather do a reborrow
183 fn box_mut_2() {
184 let foo = Foo { x: 0 } ;
185
186 let mut box_foo = Box::new(foo);
187 let p_foo = &mut box_foo;
188
189 let c = #[rustc_capture_analysis] move || p_foo.x += 10;
190 //~^ ERROR: attributes on expressions are experimental
191 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
192 //~| First Pass analysis includes:
193 //~| NOTE: Capturing p_foo[Deref,Deref,(0, 0)] -> MutBorrow
194 //~| Min Capture analysis includes:
195 //~| NOTE: Min Capture p_foo[] -> ByValue
196 }
197
198 // Test that move closures can take ownership of Copy type
199 fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 {
200 let x = 10;
201
202 let c = #[rustc_capture_analysis] move || x;
203 //~^ ERROR: attributes on expressions are experimental
204 //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
205 //~| First Pass analysis includes:
206 //~| NOTE: Capturing x[] -> ImmBorrow
207 //~| Min Capture analysis includes:
208 //~| NOTE: Min Capture x[] -> ByValue
209
210 c
211 }
212
213 fn main() {
214 simple_move_closure();
215 simple_ref();
216 struct_contains_ref_to_another_struct_1();
217 struct_contains_ref_to_another_struct_2();
218 struct_contains_ref_to_another_struct_3();
219 truncate_box_derefs();
220 box_mut_2();
221 box_mut_1();
222 }