blob: 1931b68436907a1671e0257a078dd326653602cf [file] [log] [blame]
#![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)));
}
}