You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
3.9 KiB
163 lines
3.9 KiB
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
|
|
|
// Refs: https://doc.rust-lang.org/reference/destructors.html
|
|
|
|
use std::{cell::Cell, pin::Pin, thread};
|
|
|
|
use pin_project::pin_project;
|
|
|
|
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> {
|
|
#[allow(dead_code)] // false positive that fixed in Rust 1.38
|
|
StructPinned {
|
|
#[pin]
|
|
f1: D<'a>,
|
|
#[pin]
|
|
f2: D<'a>,
|
|
},
|
|
#[allow(dead_code)] // false positive that fixed in Rust 1.38
|
|
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)));
|
|
}
|
|
}
|