Skip to content

Commit 81053b9

Browse files
committed
Auto merge of #86995 - sexxi-goose:rewrite, r=nikomatsakis
2229: Rewrite/Refactor Closure Capture Analaysis While handling all the differnet edge cases the code for the captur analysis got pretty compicated. Looking at the overall picture of the edge cases the rules can still be layed out simply. Alogithm: https://hackmd.io/D3I_gwvuT-SPnJ22tgJumw r? `@nikomatsakis` Closes rust-lang/project-rfc-2229#52 Implementation part of rust-lang/project-rfc-2229#53
2 parents 4581c4e + 5055569 commit 81053b9

File tree

7 files changed

+302
-224
lines changed

7 files changed

+302
-224
lines changed

compiler/rustc_typeck/src/check/upvar.rs

+160-168
Large diffs are not rendered by default.

src/test/ui/closures/2229_closure_analysis/by_value.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ fn big_box() {
2222
//~^ First Pass analysis includes:
2323
//~| Min Capture analysis includes:
2424
let p = t.0.0;
25-
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
26-
//~| NOTE: Capturing t[(0, 0)] -> ByValue
25+
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
2726
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
2827
println!("{} {:?}", t.1, p);
2928
//~^ NOTE: Capturing t[(1, 0)] -> ImmBorrow

src/test/ui/closures/2229_closure_analysis/by_value.stderr

+3-8
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,13 @@ LL | |
1919
LL | | };
2020
| |_____^
2121
|
22-
note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
23-
--> $DIR/by_value.rs:24:17
24-
|
25-
LL | let p = t.0.0;
26-
| ^^^^^
27-
note: Capturing t[(0, 0)] -> ByValue
22+
note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
2823
--> $DIR/by_value.rs:24:17
2924
|
3025
LL | let p = t.0.0;
3126
| ^^^^^
3227
note: Capturing t[(1, 0)] -> ImmBorrow
33-
--> $DIR/by_value.rs:28:29
28+
--> $DIR/by_value.rs:27:29
3429
|
3530
LL | println!("{} {:?}", t.1, p);
3631
| ^^^
@@ -53,7 +48,7 @@ note: Min Capture t[(0, 0)] -> ByValue
5348
LL | let p = t.0.0;
5449
| ^^^^^
5550
note: Min Capture t[(1, 0)] -> ImmBorrow
56-
--> $DIR/by_value.rs:28:29
51+
--> $DIR/by_value.rs:27:29
5752
|
5853
LL | println!("{} {:?}", t.1, p);
5954
| ^^^

src/test/ui/closures/2229_closure_analysis/move_closure.rs

+44-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn simple_move_closure() {
1616
//~^ ERROR: First Pass analysis includes:
1717
//~| ERROR: Min Capture analysis includes:
1818
t.0.0 = "new S".into();
19-
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
19+
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> MutBorrow
2020
//~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
2121
};
2222
c();
@@ -78,7 +78,7 @@ fn struct_contains_ref_to_another_struct_2() {
7878
//~^ ERROR: First Pass analysis includes:
7979
//~| ERROR: Min Capture analysis includes:
8080
let _t = t.0.0;
81-
//~^ NOTE: Capturing t[(0, 0),Deref] -> ImmBorrow
81+
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
8282
//~| NOTE: Min Capture t[(0, 0),Deref] -> ImmBorrow
8383
};
8484

@@ -100,8 +100,7 @@ fn struct_contains_ref_to_another_struct_3() {
100100
//~^ ERROR: First Pass analysis includes:
101101
//~| ERROR: Min Capture analysis includes:
102102
let _t = t.0.0;
103-
//~^ NOTE: Capturing t[(0, 0),Deref] -> ImmBorrow
104-
//~| NOTE: Capturing t[(0, 0)] -> ByValue
103+
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
105104
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
106105
};
107106

@@ -122,8 +121,7 @@ fn truncate_box_derefs() {
122121
//~^ ERROR: First Pass analysis includes:
123122
//~| ERROR: Min Capture analysis includes:
124123
let _t = b.0;
125-
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ByValue
126-
//~| NOTE: Capturing b[] -> ByValue
124+
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
127125
//~| NOTE: Min Capture b[] -> ByValue
128126
};
129127

@@ -139,7 +137,7 @@ fn truncate_box_derefs() {
139137
//~^ ERROR: First Pass analysis includes:
140138
//~| ERROR: Min Capture analysis includes:
141139
println!("{}", b.0);
142-
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ByValue
140+
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
143141
//~| NOTE: Min Capture b[] -> ByValue
144142
};
145143

@@ -156,16 +154,54 @@ fn truncate_box_derefs() {
156154
//~^ ERROR: First Pass analysis includes:
157155
//~| ERROR: Min Capture analysis includes:
158156
println!("{}", t.1.0);
159-
//~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ByValue
157+
//~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ImmBorrow
160158
//~| NOTE: Min Capture t[(1, 0)] -> ByValue
161159
};
162160
}
163161

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)] -> UniqueImmBorrow
177+
//~| Min Capture analysis includes:
178+
//~| NOTE: Min Capture box_p_foo[Deref,Deref,(0, 0)] -> UniqueImmBorrow
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)] -> UniqueImmBorrow
194+
//~| Min Capture analysis includes:
195+
//~| NOTE: Min Capture p_foo[Deref,Deref,(0, 0)] -> UniqueImmBorrow
196+
}
197+
164198
fn main() {
165199
simple_move_closure();
166200
simple_ref();
167201
struct_contains_ref_to_another_struct_1();
168202
struct_contains_ref_to_another_struct_2();
169203
struct_contains_ref_to_another_struct_3();
170204
truncate_box_derefs();
205+
box_mut_2();
206+
box_mut_1();
171207
}

0 commit comments

Comments
 (0)