diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/pin-project/tests/pinned_drop.rs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/pin-project/tests/pinned_drop.rs')
-rw-r--r-- | third_party/rust/pin-project/tests/pinned_drop.rs | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/third_party/rust/pin-project/tests/pinned_drop.rs b/third_party/rust/pin-project/tests/pinned_drop.rs new file mode 100644 index 0000000000..99273c4234 --- /dev/null +++ b/third_party/rust/pin-project/tests/pinned_drop.rs @@ -0,0 +1,284 @@ +#![warn(rust_2018_idioms, single_use_lifetimes)] + +use std::pin::Pin; + +use pin_project::{pin_project, pinned_drop}; + +#[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 self_call() { + #[pin_project(PinnedDrop)] + pub struct S<T>(T); + + 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<T> Trait for S<T> {} + + #[pinned_drop] + impl<T> PinnedDrop for S<T> { + 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_ty() { + #[pin_project(PinnedDrop)] + pub struct Struct { + pub f: (), + } + + #[pinned_drop] + impl PinnedDrop for Struct { + #[allow(irrefutable_let_patterns)] + #[allow(clippy::match_single_binding)] + fn drop(mut self: Pin<&mut Self>) { + // expr + let _: Self = Self { f: () }; + + // pat + match *self { + Self { f: () } => {} + } + if let Self { f: () } = *self {} + let Self { f: () } = *self; + } + } + + #[pin_project(PinnedDrop)] + pub struct TupleStruct(()); + + #[pinned_drop] + impl PinnedDrop for TupleStruct { + #[allow(irrefutable_let_patterns)] + fn drop(mut self: Pin<&mut Self>) { + // expr + let _: Self = Self(()); + + // pat + match *self { + Self(_) => {} + } + if let Self(_) = *self {} + let Self(_) = *self; + } + } + + #[pin_project(PinnedDrop, project = EnumProj, project_ref = EnumProjRef)] + pub enum Enum { + Struct { f: () }, + Tuple(()), + Unit, + } + + #[pinned_drop] + impl PinnedDrop for Enum { + fn drop(mut self: Pin<&mut Self>) { + // expr + let _: Self = Self::Struct { f: () }; + let _: Self = Self::Tuple(()); + let _: Self = Self::Unit; + + // pat + match *self { + Self::Struct { f: () } => {} + Self::Tuple(_) => {} + Self::Unit => {} + } + if let Self::Struct { f: () } = *self {} + if let Self::Tuple(_) = *self {} + if let Self::Unit = *self {} + } + } +} + +#[test] +fn self_inside_macro_containing_fn() { + macro_rules! mac { + ($($tt:tt)*) => { + $($tt)* + }; + } + + #[pin_project(PinnedDrop)] + pub struct S(()); + + #[pinned_drop] + impl PinnedDrop for S { + fn drop(self: Pin<&mut Self>) { + mac!({ + impl S { + pub fn _f(self) -> Self { + self + } + } + }); + } + } +} + +// See also `ui/pinned_drop/self.rs`. +#[rustversion::since(1.40)] // https://github.com/rust-lang/rust/pull/64690 +#[test] +fn self_inside_macro_def() { + #[pin_project(PinnedDrop)] + pub struct S(()); + + #[pinned_drop] + impl PinnedDrop for S { + fn drop(self: Pin<&mut Self>) { + macro_rules! mac { + () => {{ + let _ = self; + let _ = Self(()); + }}; + } + mac!(); + } + } +} + +#[test] +fn self_arg_inside_macro_call() { + #[pin_project(PinnedDrop)] + struct Struct { + f: (), + } + + #[pinned_drop] + impl PinnedDrop for Struct { + fn drop(self: Pin<&mut Self>) { + let _: Vec<_> = vec![self.f]; + } + } +} + +#[test] +fn self_ty_inside_macro_call() { + macro_rules! mac { + ($($tt:tt)*) => { + $($tt)* + }; + } + + #[pin_project(PinnedDrop)] + pub struct Struct<T: Send> + where + mac!(Self): Send, + { + _f: T, + } + + impl<T: Send> Struct<T> { + const ASSOC1: usize = 1; + fn assoc1() {} + } + + trait Trait { + type Assoc2; + const ASSOC2: usize; + fn assoc2(); + } + + impl<T: Send> Trait for Struct<T> { + type Assoc2 = u8; + const ASSOC2: usize = 2; + fn assoc2() {} + } + + #[pinned_drop] + impl<T: Send> PinnedDrop for Struct<T> + where + mac!(Self): Send, + { + #[allow(path_statements)] + #[allow(clippy::no_effect)] + fn drop(self: Pin<&mut Self>) { + // inherent items + mac!(Self::ASSOC1;); + mac!(<Self>::ASSOC1;); + mac!(Self::assoc1();); + mac!(<Self>::assoc1();); + + // trait items + mac!(let _: <Self as Trait>::Assoc2;); + mac!(Self::ASSOC2;); + mac!(<Self>::ASSOC2;); + mac!(<Self as Trait>::ASSOC2;); + mac!(Self::assoc2();); + mac!(<Self>::assoc2();); + mac!(<Self as Trait>::assoc2();); + } + } +} + +#[test] +fn inside_macro() { + #[pin_project(PinnedDrop)] + struct S(()); + + macro_rules! mac { + ($expr:expr) => { + #[pinned_drop] + impl PinnedDrop for S { + fn drop(self: Pin<&mut Self>) { + let _ = $expr; + } + } + }; + } + + mac!(1); +} + +pub mod self_path { + use super::*; + + #[pin_project(PinnedDrop)] + pub struct S<T: Unpin>(T); + + fn f() {} + + #[pinned_drop] + impl<T: Unpin> PinnedDrop for self::S<T> { + fn drop(mut self: Pin<&mut Self>) { + self::f(); + let _: self::S<()> = self::S(()); + let _: self::S<Pin<&mut Self>> = self::S(self.as_mut()); + let self::S(()) = self::S(()); + let self::S(&mut Self(_)) = self::S(&mut *self); + } + } +} |