about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAman Arora <me@aman-arora.com>2021-09-01 03:00:50 -0400
committerAman Arora <me@aman-arora.com>2021-09-03 04:38:28 -0400
commit153aa71c14d39ee1cb7f989d89b1f2891fdfcb6d (patch)
tree7fccf522968f7d872775dfaa79f549fe30f698b2 /src
parentc2a408840ad18f74280805535f0b7193528ff3df (diff)
downloadrust-153aa71c14d39ee1cb7f989d89b1f2891fdfcb6d.tar.gz
rust-153aa71c14d39ee1cb7f989d89b1f2891fdfcb6d.zip
2229: Don't move out of drop type
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88476.rs62
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88476.stderr97
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs47
3 files changed, 206 insertions, 0 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88476.rs b/src/test/ui/closures/2229_closure_analysis/issue-88476.rs
new file mode 100644
index 00000000000..f5906d30600
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88476.rs
@@ -0,0 +1,62 @@
+// edition:2021
+
+#![feature(rustc_attrs)]
+
+// Test that we can't move out of struct that impls `Drop`.
+
+
+use std::rc::Rc;
+
+// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths
+// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop.
+pub fn test1() {
+    struct Foo(Rc<i32>);
+
+    impl Drop for Foo {
+        fn drop(self: &mut Foo) {}
+    }
+
+    let f = Foo(Rc::new(1));
+    let x = #[rustc_capture_analysis] move || {
+    //~^ 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!("{:?}", f.0);
+        //~^ NOTE: Capturing f[(0, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture f[] -> ByValue
+    };
+
+    x();
+}
+
+// Test that we don't restrict precision when moving `Copy` types(i.e. when copying),
+// even if any of the parent paths implement `Drop`.
+fn test2() {
+    struct Character {
+        hp: u32,
+        name: String,
+    }
+
+    impl Drop for Character {
+        fn drop(&mut self) {}
+    }
+
+    let character = Character { hp: 100, name: format!("A") };
+
+    let c = #[rustc_capture_analysis] move || {
+    //~^ 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!("{}", character.hp)
+        //~^ NOTE: Capturing character[(0, 0)] -> ImmBorrow
+        //~| NOTE: Min Capture character[(0, 0)] -> ByValue
+    };
+
+    c();
+
+    println!("{}", character.name);
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr
new file mode 100644
index 00000000000..c7c9ecbbb0e
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88476.stderr
@@ -0,0 +1,97 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/issue-88476.rs:20:13
+   |
+LL |     let x = #[rustc_capture_analysis] move || {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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/issue-88476.rs:47:13
+   |
+LL |     let c = #[rustc_capture_analysis] move || {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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/issue-88476.rs:20:39
+   |
+LL |       let x = #[rustc_capture_analysis] move || {
+   |  _______________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing f[(0, 0)] -> ImmBorrow
+  --> $DIR/issue-88476.rs:25:26
+   |
+LL |         println!("{:?}", f.0);
+   |                          ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/issue-88476.rs:20:39
+   |
+LL |       let x = #[rustc_capture_analysis] move || {
+   |  _______________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture f[] -> ByValue
+  --> $DIR/issue-88476.rs:25:26
+   |
+LL |         println!("{:?}", f.0);
+   |                          ^^^
+
+error: First Pass analysis includes:
+  --> $DIR/issue-88476.rs:47:39
+   |
+LL |       let c = #[rustc_capture_analysis] move || {
+   |  _______________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing character[(0, 0)] -> ImmBorrow
+  --> $DIR/issue-88476.rs:52:24
+   |
+LL |         println!("{}", character.hp)
+   |                        ^^^^^^^^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/issue-88476.rs:47:39
+   |
+LL |       let c = #[rustc_capture_analysis] move || {
+   |  _______________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture character[(0, 0)] -> ByValue
+  --> $DIR/issue-88476.rs:52:24
+   |
+LL |         println!("{}", character.hp)
+   |                        ^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs
new file mode 100644
index 00000000000..f44c2af803b
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/issue-88476.rs
@@ -0,0 +1,47 @@
+// check-pass
+// edition:2021
+
+use std::rc::Rc;
+
+// Test that we restrict precision when moving not-`Copy` types, if any of the parent paths
+// implement `Drop`. This is to ensure that we don't move out of a type that implements Drop.
+pub fn test1() {
+    struct Foo(Rc<i32>);
+
+    impl Drop for Foo {
+        fn drop(self: &mut Foo) {}
+    }
+
+    let f = Foo(Rc::new(1));
+    let x = move || {
+        println!("{:?}", f.0);
+    };
+
+    x();
+}
+
+
+// Test that we don't restrict precision when moving `Copy` types(i.e. when copying),
+// even if any of the parent paths implement `Drop`.
+pub fn test2() {
+    struct Character {
+        hp: u32,
+        name: String,
+    }
+
+    impl Drop for Character {
+        fn drop(&mut self) {}
+    }
+
+    let character = Character { hp: 100, name: format!("A") };
+
+    let c = move || {
+        println!("{}", character.hp)
+    };
+
+    c();
+
+    println!("{}", character.name);
+}
+
+fn main() {}