diff options
Diffstat (limited to 'tests/pinned_drop.rs')
-rw-r--r-- | tests/pinned_drop.rs | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/tests/pinned_drop.rs b/tests/pinned_drop.rs new file mode 100644 index 0000000..b0677e2 --- /dev/null +++ b/tests/pinned_drop.rs @@ -0,0 +1,235 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] +#![allow(dead_code)] + +use pin_project::{pin_project, pinned_drop}; +use std::pin::Pin; + +#[test] +fn safe_project() { + #[pin_project(PinnedDrop)] + pub struct Struct<'a> { + was_dropped: &'a mut bool, + #[pin] + field: u8, + } + + #[pinned_drop] + impl PinnedDrop for Struct<'_> { + fn drop(self: Pin<&mut Self>) { + **self.project().was_dropped = true; + } + } + + let mut was_dropped = false; + drop(Struct { was_dropped: &mut was_dropped, field: 42 }); + assert!(was_dropped); +} + +#[test] +fn mut_self_argument() { + #[pin_project(PinnedDrop)] + struct Struct { + data: usize, + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(mut self: Pin<&mut Self>) { + let _: &mut _ = &mut self.data; + } + } +} + +#[test] +fn self_in_vec() { + #[pin_project(PinnedDrop)] + struct Struct { + data: usize, + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(self: Pin<&mut Self>) { + let _: Vec<_> = vec![self.data]; + } + } +} + +#[test] +fn self_in_macro_containing_fn() { + #[pin_project(PinnedDrop)] + pub struct Struct { + data: usize, + } + + macro_rules! emit { + ($($tt:tt)*) => { + $($tt)* + }; + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(self: Pin<&mut Self>) { + let _ = emit!({ + impl Struct { + pub fn f(self) {} + } + }); + let _ = self.data; + } + } +} + +#[test] +fn self_call() { + #[pin_project(PinnedDrop)] + pub struct Struct { + data: usize, + } + + trait Trait { + fn self_ref(&self) {} + fn self_pin_ref(self: Pin<&Self>) {} + fn self_mut(&mut self) {} + fn self_pin_mut(self: Pin<&mut Self>) {} + fn assoc_fn(_this: Pin<&mut Self>) {} + } + + impl Trait for Struct {} + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(mut self: Pin<&mut Self>) { + self.self_ref(); + self.as_ref().self_pin_ref(); + self.self_mut(); + self.as_mut().self_pin_mut(); + Self::assoc_fn(self.as_mut()); + <Self>::assoc_fn(self.as_mut()); + } + } +} + +#[test] +fn self_expr() { + #[pin_project(PinnedDrop)] + pub struct Struct { + x: usize, + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(mut self: Pin<&mut Self>) { + let _: Self = Self { x: 0 }; + } + } + + #[pin_project(PinnedDrop)] + pub struct TupleStruct(usize); + + #[pinned_drop] + impl PinnedDrop for TupleStruct { + fn drop(mut self: Pin<&mut Self>) { + let _: Self = Self(0); + } + } +} + +#[rustversion::since(1.37)] +#[test] +fn self_expr_enum() { + #[pin_project(PinnedDrop)] + pub enum Enum { + StructVariant { x: usize }, + TupleVariant(usize), + } + + #[pinned_drop] + impl PinnedDrop for Enum { + fn drop(mut self: Pin<&mut Self>) { + let _: Self = Self::StructVariant { x: 0 }; + let _: Self = Self::TupleVariant(0); + } + } +} + +#[test] +fn self_pat() { + #[pin_project(PinnedDrop)] + pub struct Struct { + x: usize, + } + + #[pinned_drop] + impl PinnedDrop for Struct { + #[allow(irrefutable_let_patterns)] + #[allow(clippy::match_single_binding)] + fn drop(mut self: Pin<&mut Self>) { + match *self { + Self { x: _ } => {} + } + if let Self { x: _ } = *self {} + let Self { x: _ } = *self; + } + } + + #[pin_project(PinnedDrop)] + pub struct TupleStruct(usize); + + #[pinned_drop] + impl PinnedDrop for TupleStruct { + #[allow(irrefutable_let_patterns)] + fn drop(mut self: Pin<&mut Self>) { + match *self { + Self(_) => {} + } + if let Self(_) = *self {} + let Self(_) = *self; + } + } +} + +#[rustversion::since(1.37)] +#[test] +fn self_pat_enum() { + #[pin_project(PinnedDrop)] + pub enum Enum { + StructVariant { x: usize }, + TupleVariant(usize), + } + + #[pinned_drop] + impl PinnedDrop for Enum { + fn drop(mut self: Pin<&mut Self>) { + match *self { + Self::StructVariant { x: _ } => {} + Self::TupleVariant(_) => {} + } + if let Self::StructVariant { x: _ } = *self {} + if let Self::TupleVariant(_) = *self {} + } + } +} + +// See also `ui/pinned_drop/self.rs`. +#[rustversion::since(1.40)] // https://github.com/rust-lang/rust/pull/64690 +#[test] +fn self_in_macro_def() { + #[pin_project(PinnedDrop)] + pub struct Struct { + x: usize, + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(self: Pin<&mut Self>) { + macro_rules! t { + () => {{ + let _ = self; + }}; + } + t!(); + } + } +} |