diff options
| author | Wesley Wiser <wesleywiser@microsoft.com> | 2021-09-23 15:15:51 -0400 |
|---|---|---|
| committer | Wesley Wiser <wesleywiser@microsoft.com> | 2021-09-23 17:45:17 -0400 |
| commit | 7a3e450df45d2e40cff0ab6a4928084d6f61e993 (patch) | |
| tree | 6e6521f7e3af4226902984655f733727f4efff88 | |
| parent | 15d9ba0133ce0b35348e1c8367afe00aec841ffa (diff) | |
| download | rust-7a3e450df45d2e40cff0ab6a4928084d6f61e993.tar.gz rust-7a3e450df45d2e40cff0ab6a4928084d6f61e993.zip | |
Add tests to verify the drop order of fields in fully captured upvars
5 files changed, 360 insertions, 0 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs new file mode 100644 index 00000000000..ecc265208c5 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs @@ -0,0 +1,98 @@ +// edition:2021 + +// Tests that in cases where we individually capture all the fields of a type, +// we still drop them in the order they would have been dropped in the 2018 edition. + +#![feature(rustc_attrs)] + +#[derive(Debug)] +struct HasDrop; +impl Drop for HasDrop { + fn drop(&mut self) { + println!("dropped"); + } +} + +fn test_one() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + }; +} + +fn test_two() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + }; +} + +fn test_three() { + let a = (HasDrop, HasDrop); + let b = (HasDrop, HasDrop); + + let c = #[rustc_capture_analysis] + //~^ ERROR: attributes on expressions are experimental + //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> + || { + //~^ ERROR: First Pass analysis includes: + //~| ERROR: Min Capture analysis includes: + println!("{:?}", b.1); + //~^ NOTE: Capturing b[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(1, 0)] -> ImmBorrow + println!("{:?}", a.1); + //~^ NOTE: Capturing a[(1, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(1, 0)] -> ImmBorrow + println!("{:?}", a.0); + //~^ NOTE: Capturing a[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture a[(0, 0)] -> ImmBorrow + + println!("{:?}", b.0); + //~^ NOTE: Capturing b[(0, 0)] -> ImmBorrow + //~| NOTE: Min Capture b[(0, 0)] -> ImmBorrow + }; +} + +fn main() { + test_one(); + test_two(); + test_three(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr new file mode 100644 index 00000000000..7fdeab6a74d --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr @@ -0,0 +1,228 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:20:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:46:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error[E0658]: attributes on expressions are experimental + --> $DIR/preserve_field_drop_order.rs:72:13 + | +LL | let c = #[rustc_capture_analysis] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:23:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.0); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:26:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:29:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:33:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:36:26 + | +LL | println!("{:?}", b.1); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:23:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.0); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:26:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:29:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:33:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:36:26 + | +LL | println!("{:?}", b.1); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:49:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:52:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:55:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:59:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:62:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:49:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", a.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:52:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:55:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:59:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:62:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: First Pass analysis includes: + --> $DIR/preserve_field_drop_order.rs:75:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", b.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Capturing b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:78:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Capturing a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:81:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Capturing a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:84:26 + | +LL | println!("{:?}", a.0); + | ^^^ +note: Capturing b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:88:26 + | +LL | println!("{:?}", b.0); + | ^^^ + +error: Min Capture analysis includes: + --> $DIR/preserve_field_drop_order.rs:75:5 + | +LL | / || { +LL | | +LL | | +LL | | println!("{:?}", b.1); +... | +LL | | +LL | | }; + | |_____^ + | +note: Min Capture b[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:78:26 + | +LL | println!("{:?}", b.1); + | ^^^ +note: Min Capture b[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:88:26 + | +LL | println!("{:?}", b.0); + | ^^^ +note: Min Capture a[(1, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:81:26 + | +LL | println!("{:?}", a.1); + | ^^^ +note: Min Capture a[(0, 0)] -> ImmBorrow + --> $DIR/preserve_field_drop_order.rs:84:26 + | +LL | println!("{:?}", a.0); + | ^^^ + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs new file mode 100644 index 00000000000..bc5c92122c6 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs @@ -0,0 +1,28 @@ +// run-pass +// check-run-results +// revisions: twenty_eighteen twenty_twentyone +// [twenty_eighteen]compile-flags: --edition 2018 +// [twenty_twentyone]compile-flags: --edition 2021 + +#[derive(Debug)] +struct Dropable(String); + +impl Drop for Dropable { + fn drop(&mut self) { + println!("Dropping {}", self.0) + } +} + +#[derive(Debug)] +struct A { + x: Dropable, + y: Dropable, +} + +fn main() { + let a = A { x: Dropable(format!("x")), y: Dropable(format!("y")) }; + + let c = move || println!("{:?} {:?}", a.y, a.x); + + c(); +} diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout new file mode 100644 index 00000000000..e3931696518 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout @@ -0,0 +1,3 @@ +Dropable("y") Dropable("x") +Dropping x +Dropping y diff --git a/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout new file mode 100644 index 00000000000..90b1200fd08 --- /dev/null +++ b/src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout @@ -0,0 +1,3 @@ +Dropable("y") Dropable("x") +Dropping y +Dropping x |
