diff options
Diffstat (limited to 'tests/drop_order.rs')
-rw-r--r-- | tests/drop_order.rs | 159 |
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))); + } +} |