aboutsummaryrefslogtreecommitdiff
path: root/tests/drop_order.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/drop_order.rs')
-rw-r--r--tests/drop_order.rs159
1 files changed, 159 insertions, 0 deletions
diff --git a/tests/drop_order.rs b/tests/drop_order.rs
new file mode 100644
index 0000000..1931b68
--- /dev/null
+++ b/tests/drop_order.rs
@@ -0,0 +1,159 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+// Refs: https://doc.rust-lang.org/reference/destructors.html
+
+use pin_project::pin_project;
+use std::{cell::Cell, pin::Pin, thread};
+
+struct D<'a>(&'a Cell<usize>, usize);
+
+impl Drop for D<'_> {
+ fn drop(&mut self) {
+ if !thread::panicking() {
+ let old = self.0.replace(self.1);
+ assert_eq!(old, self.1 - 1);
+ }
+ }
+}
+
+#[pin_project(project_replace)]
+struct StructPinned<'a> {
+ #[pin]
+ f1: D<'a>,
+ #[pin]
+ f2: D<'a>,
+}
+
+#[pin_project(project_replace)]
+struct StructUnpinned<'a> {
+ f1: D<'a>,
+ f2: D<'a>,
+}
+
+#[pin_project(project_replace)]
+struct TuplePinned<'a>(#[pin] D<'a>, #[pin] D<'a>);
+
+#[pin_project(project_replace)]
+struct TupleUnpinned<'a>(D<'a>, D<'a>);
+
+#[pin_project(project_replace = EnumProj)]
+enum Enum<'a> {
+ StructPinned {
+ #[pin]
+ f1: D<'a>,
+ #[pin]
+ f2: D<'a>,
+ },
+ StructUnpinned {
+ f1: D<'a>,
+ f2: D<'a>,
+ },
+ TuplePinned(#[pin] D<'a>, #[pin] D<'a>),
+ TupleUnpinned(D<'a>, D<'a>),
+}
+
+#[test]
+fn struct_pinned() {
+ {
+ let c = Cell::new(0);
+ let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+ }
+}
+
+#[test]
+fn struct_unpinned() {
+ {
+ let c = Cell::new(0);
+ let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+ }
+}
+
+#[test]
+fn tuple_pinned() {
+ {
+ let c = Cell::new(0);
+ let _x = TuplePinned(D(&c, 1), D(&c, 2));
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = TuplePinned(D(&c, 1), D(&c, 2));
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(TuplePinned(D(&c, 3), D(&c, 4)));
+ }
+}
+
+#[test]
+fn tuple_unpinned() {
+ {
+ let c = Cell::new(0);
+ let _x = TupleUnpinned(D(&c, 1), D(&c, 2));
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = TupleUnpinned(D(&c, 1), D(&c, 2));
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(TupleUnpinned(D(&c, 3), D(&c, 4)));
+ }
+}
+
+#[test]
+fn enum_struct() {
+ {
+ let c = Cell::new(0);
+ let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+ }
+
+ {
+ let c = Cell::new(0);
+ let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+ }
+}
+
+#[test]
+fn enum_tuple() {
+ {
+ let c = Cell::new(0);
+ let _x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(Enum::TuplePinned(D(&c, 3), D(&c, 4)));
+ }
+
+ {
+ let c = Cell::new(0);
+ let _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
+ }
+ {
+ let c = Cell::new(0);
+ let mut _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
+ let _y = Pin::new(&mut _x);
+ let _z = _y.project_replace(Enum::TupleUnpinned(D(&c, 3), D(&c, 4)));
+ }
+}