diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/closures/2229_closure_analysis/move_closure.rs | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/closures/2229_closure_analysis/move_closure.rs')
-rw-r--r-- | tests/ui/closures/2229_closure_analysis/move_closure.rs | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/tests/ui/closures/2229_closure_analysis/move_closure.rs b/tests/ui/closures/2229_closure_analysis/move_closure.rs new file mode 100644 index 000000000..b542fa243 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/move_closure.rs @@ -0,0 +1,222 @@ +// edition:2021 + +// Test that move closures drop derefs with `capture_disjoint_fields` enabled. + +#![feature(rustc_attrs)] + +fn simple_move_closure() { + struct S(String); + struct T(S); + + let t = T(S("s".into())); + let mut c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + t.0.0 = "new S".into(); + //~^ NOTE: Capturing t[(0, 0),(0, 0)] -> MutBorrow + //~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue + }; + c(); +} + +// Test move closure use reborrows when using references +fn simple_ref() { + let mut s = 10; + let ref_s = &mut s; + + let mut c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + *ref_s += 10; + //~^ NOTE: Capturing ref_s[Deref] -> MutBorrow + //~| NOTE: Min Capture ref_s[] -> ByValue + }; + c(); +} + +// Test move closure use reborrows when using references +fn struct_contains_ref_to_another_struct_1() { + struct S(String); + struct T<'a>(&'a mut S); + + let mut s = S("s".into()); + let t = T(&mut s); + + let mut c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + t.0.0 = "new s".into(); + //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> MutBorrow + //~| NOTE: Min Capture t[(0, 0)] -> ByValue + }; + + c(); +} + +// Test that we can use reborrows to read data of Copy types +// i.e. without truncating derefs +fn struct_contains_ref_to_another_struct_2() { + struct S(i32); + struct T<'a>(&'a S); + + let s = S(0); + let t = T(&s); + + let mut c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + let _t = t.0.0; + //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture t[(0, 0)] -> ByValue + }; + + c(); +} + +// Test that we can use truncate to move out of !Copy types +fn struct_contains_ref_to_another_struct_3() { + struct S(String); + struct T<'a>(&'a S); + + let s = S("s".into()); + let t = T(&s); + + let mut c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + let _t = t.0.0; + //~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue + //~| NOTE: Min Capture t[(0, 0)] -> ByValue + }; + + c(); +} + +// Test that derefs of box are truncated in move closures +fn truncate_box_derefs() { + struct S(i32); + + + // Content within the box is moved within the closure + let b = Box::new(S(10)); + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + let _t = b.0; + //~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[] -> ByValue + }; + + c(); + + // Content within the box is used by a shared ref and the box is the root variable + let b = Box::new(S(10)); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{}", b.0); + //~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[] -> ByValue + }; + + c(); + + // Content within the box is used by a shared ref and the box is not the root variable + let b = Box::new(S(10)); + let t = (0, b); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + move || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{}", t.1.0); + //~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture t[(1, 0)] -> ByValue + }; +} + +struct Foo { x: i32 } + +// Ensure that even in move closures, if the data is not owned by the root variable +// then we don't truncate the derefs or a ByValue capture, rather do a reborrow +fn box_mut_1() { + let mut foo = Foo { x: 0 } ; + + let p_foo = &mut foo; + let box_p_foo = Box::new(p_foo); + + let c = #[rustc_capture_analysis] move || box_p_foo.x += 10; + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + //~| First Pass analysis includes: + //~| NOTE: Capturing box_p_foo[Deref,Deref,(0, 0)] -> MutBorrow + //~| Min Capture analysis includes: + //~| NOTE: Min Capture box_p_foo[] -> ByValue +} + +// Ensure that even in move closures, if the data is not owned by the root variable +// then we don't truncate the derefs or a ByValue capture, rather do a reborrow +fn box_mut_2() { + let foo = Foo { x: 0 } ; + + let mut box_foo = Box::new(foo); + let p_foo = &mut box_foo; + + let c = #[rustc_capture_analysis] move || p_foo.x += 10; + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + //~| First Pass analysis includes: + //~| NOTE: Capturing p_foo[Deref,Deref,(0, 0)] -> MutBorrow + //~| Min Capture analysis includes: + //~| NOTE: Min Capture p_foo[] -> ByValue +} + +// Test that move closures can take ownership of Copy type +fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 { + let x = 10; + + let c = #[rustc_capture_analysis] move || x; + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + //~| First Pass analysis includes: + //~| NOTE: Capturing x[] -> ImmBorrow + //~| Min Capture analysis includes: + //~| NOTE: Min Capture x[] -> ByValue + + c +} + +fn main() { + simple_move_closure(); + simple_ref(); + struct_contains_ref_to_another_struct_1(); + struct_contains_ref_to_another_struct_2(); + struct_contains_ref_to_another_struct_3(); + truncate_box_derefs(); + box_mut_2(); + box_mut_1(); +} |