about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWesley Wiser <wesleywiser@microsoft.com>2021-09-23 15:15:51 -0400
committerWesley Wiser <wesleywiser@microsoft.com>2021-09-23 17:45:17 -0400
commit7a3e450df45d2e40cff0ab6a4928084d6f61e993 (patch)
tree6e6521f7e3af4226902984655f733727f4efff88
parent15d9ba0133ce0b35348e1c8367afe00aec841ffa (diff)
downloadrust-7a3e450df45d2e40cff0ab6a4928084d6f61e993.tar.gz
rust-7a3e450df45d2e40cff0ab6a4928084d6f61e993.zip
Add tests to verify the drop order of fields in fully captured upvars
-rw-r--r--src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs98
-rw-r--r--src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order.stderr228
-rw-r--r--src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.rs28
-rw-r--r--src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_eighteen.run.stdout3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/preserve_field_drop_order2.twenty_twentyone.run.stdout3
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