diff options
| author | Aman Arora <me@aman-arora.com> | 2021-02-04 02:12:31 -0500 |
|---|---|---|
| committer | Aman Arora <me@aman-arora.com> | 2021-02-15 22:00:25 -0500 |
| commit | b86c5db96eecbf6f4b08cd3f29d5a5b4dae13aee (patch) | |
| tree | 9a460ae26b0e84af8ccd72f785224a6355b0cafd /src | |
| parent | d1206f950ffb76c76e1b74a19ae33c2b7d949454 (diff) | |
| download | rust-b86c5db96eecbf6f4b08cd3f29d5a5b4dae13aee.tar.gz rust-b86c5db96eecbf6f4b08cd3f29d5a5b4dae13aee.zip | |
Implement reborrow for closure captures
Diffstat (limited to 'src')
5 files changed, 59 insertions, 12 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.rs b/src/test/ui/closures/2229_closure_analysis/by_value.rs index 1007fb582e5..27c8fb1363f 100644 --- a/src/test/ui/closures/2229_closure_analysis/by_value.rs +++ b/src/test/ui/closures/2229_closure_analysis/by_value.rs @@ -26,7 +26,8 @@ fn big_box() { //~^ First Pass analysis includes: //~| Min Capture analysis includes: let p = t.0.0; - //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue + //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow + //~| NOTE: Capturing t[(0, 0)] -> ByValue //~| NOTE: Min Capture t[(0, 0)] -> ByValue println!("{} {:?}", t.1, p); //~^ NOTE: Capturing t[(1, 0)] -> ImmBorrow diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.stderr b/src/test/ui/closures/2229_closure_analysis/by_value.stderr index fe04dbef6d8..944e4c40a78 100644 --- a/src/test/ui/closures/2229_closure_analysis/by_value.stderr +++ b/src/test/ui/closures/2229_closure_analysis/by_value.stderr @@ -28,13 +28,18 @@ LL | | LL | | }; | |_____^ | -note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue +note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow + --> $DIR/by_value.rs:28:17 + | +LL | let p = t.0.0; + | ^^^^^ +note: Capturing t[(0, 0)] -> ByValue --> $DIR/by_value.rs:28:17 | LL | let p = t.0.0; | ^^^^^ note: Capturing t[(1, 0)] -> ImmBorrow - --> $DIR/by_value.rs:31:29 + --> $DIR/by_value.rs:32:29 | LL | println!("{} {:?}", t.1, p); | ^^^ @@ -57,7 +62,7 @@ note: Min Capture t[(0, 0)] -> ByValue LL | let p = t.0.0; | ^^^^^ note: Min Capture t[(1, 0)] -> ImmBorrow - --> $DIR/by_value.rs:31:29 + --> $DIR/by_value.rs:32:29 | LL | println!("{} {:?}", t.1, p); | ^^^ diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/move_closure.rs index 8bdc999ca3c..d57c2280438 100644 --- a/src/test/ui/closures/2229_closure_analysis/move_closure.rs +++ b/src/test/ui/closures/2229_closure_analysis/move_closure.rs @@ -18,8 +18,8 @@ fn simple_ref() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: *ref_s += 10; - //~^ NOTE: Capturing ref_s[Deref] -> ByValue - //~| NOTE: Min Capture ref_s[] -> ByValue + //~^ NOTE: Capturing ref_s[Deref] -> UniqueImmBorrow + //~| NOTE: Min Capture ref_s[Deref] -> UniqueImmBorrow }; c(); } @@ -39,8 +39,8 @@ fn struct_contains_ref_to_another_struct() { //~^ ERROR: First Pass analysis includes: //~| ERROR: Min Capture analysis includes: t.0.0 = "new s".into(); - //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue - //~| NOTE: Min Capture t[(0, 0)] -> ByValue + //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow + //~| NOTE: Min Capture t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr index a745f14598e..554dc11f6ba 100644 --- a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr +++ b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr @@ -46,7 +46,7 @@ LL | | LL | | }; | |_____^ | -note: Capturing ref_s[Deref] -> ByValue +note: Capturing ref_s[Deref] -> UniqueImmBorrow --> $DIR/move_closure.rs:20:9 | LL | *ref_s += 10; @@ -64,7 +64,7 @@ LL | | LL | | }; | |_____^ | -note: Min Capture ref_s[] -> ByValue +note: Min Capture ref_s[Deref] -> UniqueImmBorrow --> $DIR/move_closure.rs:20:9 | LL | *ref_s += 10; @@ -82,7 +82,7 @@ LL | | LL | | }; | |_____^ | -note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue +note: Capturing t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow --> $DIR/move_closure.rs:41:9 | LL | t.0.0 = "new s".into(); @@ -100,7 +100,7 @@ LL | | LL | | }; | |_____^ | -note: Min Capture t[(0, 0)] -> ByValue +note: Min Capture t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow --> $DIR/move_closure.rs:41:9 | LL | t.0.0 = "new s".into(); diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs index 4007a5a48aa..afaafbda018 100644 --- a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs +++ b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs @@ -56,9 +56,50 @@ fn no_ref_nested() { c(); } +struct A<'a>(&'a mut String, &'a mut String); +// Test that reborrowing works as expected for move closures +// by attempting a disjoint capture through a reference. +fn disjoint_via_ref() { + let mut x = String::new(); + let mut y = String::new(); + + let mut a = A(&mut x, &mut y); + let a = &mut a; + + let mut c1 = move || { + a.0.truncate(0); + }; + + let mut c2 = move || { + a.1.truncate(0); + }; + + c1(); + c2(); +} + +// Test that even if a path is moved into the closure, the closure is not FnOnce +// if the path is not moved by the closure call. +fn data_moved_but_not_fn_once() { + let x = Box::new(10i32); + + let c = move || { + // *x has type i32 which is Copy. So even though the box `x` will be moved + // into the closure, `x` is never moved when the closure is called, i.e. the + // ownership stays with the closure and therefore we can call the function multiple times. + let _x = *x; + }; + + c(); + c(); +} + fn main() { simple_ref(); struct_contains_ref_to_another_struct(); no_ref(); no_ref_nested(); + + disjoint_via_ref(); + data_moved_but_not_fn_once(); } |
