impl<T,U>Struct<T,U>{ fnmethod(self:Pin<&mutSelf>){ letthis=self.project(); let_:Pin<&mutT>=this.pinned;// Pinned reference to the field let_:&mutU=this.unpinned;// Normal reference to the field } } ```
#![no_std] #![doc(test(
no_crate_inject,
attr(
deny(warnings, rust_2018_idioms, single_use_lifetimes),
allow(dead_code, unused_variables)
)
))] // #![warn(unsafe_op_in_unsafe_fn)] // requires Rust 1.52 #![warn( // Lints that may help when writing public library.
missing_debug_implementations,
missing_docs,
clippy::alloc_instead_of_core,
clippy::exhaustive_enums,
clippy::exhaustive_structs,
clippy::impl_trait_in_params, // clippy::missing_inline_in_public_items,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core,
)]
/// A macro that creates a projection type covering all the fields of struct. /// /// This macro creates a projection type according to the following rules: /// /// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field. /// - For the other fields, makes the unpinned reference to the field. /// /// And the following methods are implemented on the original type: /// /// ``` /// # use std::pin::Pin; /// # type Projection<'a> = &'a (); /// # type ProjectionRef<'a> = &'a (); /// # trait Dox { /// fn project(self: Pin<&mut Self>) -> Projection<'_>; /// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; /// # } /// ``` /// /// By passing an attribute with the same name as the method to the macro, /// you can name the projection type returned from the method. This allows you /// to use pattern matching on the projected types. /// /// ``` /// # use pin_project_lite::pin_project; /// # use std::pin::Pin; /// pin_project! { /// #[project = EnumProj] /// enum Enum<T> { /// Variant { #[pin] field: T }, /// } /// } /// /// impl<T> Enum<T> { /// fn method(self: Pin<&mut Self>) { /// let this: EnumProj<'_, T> = self.project(); /// match this { /// EnumProj::Variant { field } => { /// let _: Pin<&mut T> = field; /// } /// } /// } /// } /// ``` /// /// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional /// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving /// out all unpinned fields in `Self`. /// /// ``` /// # use std::pin::Pin; /// # type MyProjReplace = (); /// # trait Dox { /// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace; /// # } /// ``` /// /// Also, note that the projection types returned by `project` and `project_ref` have /// an additional lifetime at the beginning of generics. /// /// ```text /// let this: EnumProj<'_, T> = self.project(); /// ^^ /// ``` /// /// The visibility of the projected types and projection methods is based on the /// original type. However, if the visibility of the original type is `pub`, the /// visibility of the projected types and the projection methods is downgraded /// to `pub(crate)`. /// /// # Safety /// /// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate. /// Both are completely safe unless you write other unsafe code. /// /// See [pin-project] crate for more details. /// /// # Examples /// /// ``` /// use std::pin::Pin; /// /// use pin_project_lite::pin_project; /// /// pin_project! { /// struct Struct<T, U> { /// #[pin] /// pinned: T, /// unpinned: U, /// } /// } /// /// impl<T, U> Struct<T, U> { /// fn method(self: Pin<&mut Self>) { /// let this = self.project(); /// let _: Pin<&mut T> = this.pinned; // Pinned reference to the field /// let _: &mut U = this.unpinned; // Normal reference to the field /// } /// } /// ``` /// /// To use `pin_project!` on enums, you need to name the projection type /// returned from the method. /// /// ``` /// use std::pin::Pin; /// /// use pin_project_lite::pin_project; /// /// pin_project! { /// #[project = EnumProj] /// enum Enum<T> { /// Struct { /// #[pin] /// field: T, /// }, /// Unit, /// } /// } /// /// impl<T> Enum<T> { /// fn method(self: Pin<&mut Self>) { /// match self.project() { /// EnumProj::Struct { field } => { /// let _: Pin<&mut T> = field; /// } /// EnumProj::Unit => {} /// } /// } /// } /// ``` /// /// If you want to call the `project()` method multiple times or later use the /// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid /// consuming the [`Pin`]. /// /// ``` /// use std::pin::Pin; /// /// use pin_project_lite::pin_project; /// /// pin_project! { /// struct Struct<T> { /// #[pin] /// field: T, /// } /// } /// /// impl<T> Struct<T> { /// fn call_project_twice(mut self: Pin<&mut Self>) { /// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`. /// self.as_mut().project(); /// self.as_mut().project(); /// } /// } /// ``` /// /// # `!Unpin` /// /// If you want to make sure `Unpin` is not implemented, use the `#[project(!Unpin)]` /// attribute. /// /// ``` /// use pin_project_lite::pin_project; /// /// pin_project! { /// #[project(!Unpin)] /// struct Struct<T> { /// #[pin] /// field: T, /// } /// } /// ``` /// /// This is equivalent to using `#[pin]` attribute for a [`PhantomPinned`] field. /// /// ``` /// use std::marker::PhantomPinned; /// /// use pin_project_lite::pin_project; /// /// pin_project! { /// struct Struct<T> { /// field: T, /// #[pin] /// _pin: PhantomPinned, /// } /// } /// ``` /// /// Note that using [`PhantomPinned`] without `#[pin]` or `#[project(!Unpin)]` /// attribute has no effect. /// /// # Pinned Drop /// /// In order to correctly implement pin projections, a type’s [`Drop`] impl must not move out of any /// structurally pinned fields. Unfortunately, [`Drop::drop`] takes `&mut Self`, not `Pin<&mut</span> /// Self>`. /// /// To implement [`Drop`] for type that has pin, add an `impl PinnedDrop` block at the end of the /// [`pin_project`] macro block. PinnedDrop has the following interface: /// /// ```rust /// # use std::pin::Pin; /// trait PinnedDrop { /// fn drop(this: Pin<&mut Self>); /// } /// ``` /// /// Note that the argument to `PinnedDrop::drop` cannot be named `self`. /// /// `pin_project!` implements the actual [`Drop`] trait via PinnedDrop you implemented. To /// explicitly drop a type that implements PinnedDrop, use the [drop] function just like dropping a /// type that directly implements [`Drop`]. /// /// `PinnedDrop::drop` will never be called more than once, just like [`Drop::drop`]. /// /// ```rust /// use pin_project_lite::pin_project; /// /// pin_project! { /// pub struct Struct<'a> { /// was_dropped: &'a mut bool, /// #[pin] /// field: u8, /// } /// /// impl PinnedDrop for Struct<'_> { /// fn drop(this: Pin<&mut Self>) { // <----- NOTE: this is not `self` /// **this.project().was_dropped = true; /// } /// } /// } /// /// let mut was_dropped = false; /// drop(Struct { was_dropped: &mut was_dropped, field: 42 }); /// assert!(was_dropped); /// ``` /// /// [`PhantomPinned`]: core::marker::PhantomPinned /// [`Pin::as_mut`]: core::pin::Pin::as_mut /// [`Pin`]: core::pin::Pin /// [pin-project]: https://github.com/taiki-e/pin-project #[macro_export]
macro_rules! pin_project {
($($tt:tt)*) => {
$crate::__pin_project_internal! {
[][][][][]
$($tt)*
}
};
}
// limitations: // - no support for tuple structs and tuple variant (wontfix). // - no support for multiple trait/lifetime bounds. // - no support for `Self` in where clauses. (wontfix) // - no support for overlapping lifetime names. (wontfix) // - no interoperability with other field attributes. // - no useful error messages. (wontfix) // etc...
// Destructors will run in reverse order, so next create a guard to overwrite // `self` with the replacement value without calling destructors. let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
// Destructors will run in reverse order, so next create a guard to overwrite // `self` with the replacement value without calling destructors. let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
#[doc(hidden)] #[macro_export]
macro_rules! __pin_project_make_unpin_impl {
(
[]
[$vis:vis $ident:ident]
[$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
$($field:tt)*
) => { // Automatically create the appropriate conditional `Unpin` implementation. // // Basically this is equivalent to the following code: // ``` // impl<T, U> Unpin for Struct<T, U> where T: Unpin {} // ``` // // However, if struct is public and there is a private type field, // this would cause an E0446 (private type in public interface). // // When RFC 2145 is implemented (rust-lang/rust#48054), // this will become a lint, rather then a hard error. // // As a workaround for this, we generate a new struct, containing all of the pinned // fields from our #[pin_project] type. This struct is declared within // a function, which makes it impossible to be named by user code. // This guarantees that it will use the default auto-trait impl for Unpin - // that is, it will implement Unpin iff all of its fields implement Unpin. // This type can be safely declared as 'public', satisfying the privacy // checker without actually allowing user code to access it. // // This allows users to apply the #[pin_project] attribute to types // regardless of the privacy of the types of their fields. // // See also https://github.com/taiki-e/pin-project/pull/53. #[allow(non_snake_case)]
$vis struct __Origin <'__pin, $($impl_generics)*>
$(where
$($where_clause)*)?
{
__dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
$($field)*
} impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*> where
__Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin
$(, $($where_clause)*)?
{
}
};
(
[$proj_not_unpin_mark:ident]
[$vis:vis $ident:ident]
[$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
$($field:tt)*
) => { #[doc(hidden)] impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*> where
(
::core::marker::PhantomData<&'__pin ()>,
::core::marker::PhantomPinned,
): $crate::__private::Unpin
$(, $($where_clause)*)?
{
}
}
}
#[doc(hidden)] #[macro_export]
macro_rules! __pin_project_make_drop_impl {
(
[$_ident:ident]
[$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]
$(#[$drop_impl_attrs:meta])* impl $(<
$( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
$( $generics:ident
$(: $generics_bound:path)?
$(: ?$generics_unsized_bound:path)?
$(: $generics_lifetime_bound:lifetime)?
),*
>)? PinnedDrop for $self_ty:ty
$(where
$( $where_clause_ty:ty
$(: $where_clause_bound:path)?
$(: ?$where_clause_unsized_bound:path)?
$(: $where_clause_lifetime_bound:lifetime)?
),* $(,)?
)?
{
$(#[$drop_fn_attrs:meta])* fn drop($($arg:ident)+: Pin<&mutSelf>) {
$($tt:tt)*
}
}
) => {
$(#[$drop_impl_attrs])* impl $(<
$( $lifetime $(: $lifetime_bound)? ,)*
$( $generics
$(: $generics_bound)?
$(: ?$generics_unsized_bound)?
$(: $generics_lifetime_bound)?
),*
>)? $crate::__private::Drop for $self_ty
$(where
$( $where_clause_ty
$(: $where_clause_bound)?
$(: ?$where_clause_unsized_bound)?
$(: $where_clause_lifetime_bound)?
),*
)?
{
$(#[$drop_fn_attrs])* fn drop(&mutself) { // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe. // This is because destructors can be called multiple times in safe code and // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360). // // `__drop_inner` is defined as a safe method, but this is fine since // `__drop_inner` is not accessible by the users and we call `__drop_inner` only // once. // // Users can implement [`Drop`] safely using `pin_project!` and can drop a // type that implements `PinnedDrop` using the [`drop`] function safely. fn __drop_inner $(<
$( $lifetime $(: $lifetime_bound)? ,)*
$( $generics
$(: $generics_bound)?
$(: ?$generics_unsized_bound)?
$(: $generics_lifetime_bound)?
),*
>)? (
$($arg)+: $crate::__private::Pin<&mut $self_ty>,
)
$(where
$( $where_clause_ty
$(: $where_clause_bound)?
$(: ?$where_clause_unsized_bound)?
$(: $where_clause_lifetime_bound)?
),*
)?
{ // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`. fn __drop_inner() {}
$($tt)*
}
// Safety - we're in 'drop', so we know that 'self' will // never move again. let pinned_self: $crate::__private::Pin<&mutSelf>
= unsafe { $crate::__private::Pin::new_unchecked(self) }; // We call `__drop_inner` only once. Since `__DropInner::__drop_inner` // is not accessible by the users, it is never called again.
__drop_inner(pinned_self);
}
}
};
(
[$ident:ident]
[$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
) => { // Ensure that struct does not implement `Drop`. // // There are two possible cases: // 1. The user type does not implement Drop. In this case, // the first blanked impl will not apply to it. This code // will compile, as there is only one impl of MustNotImplDrop for the user type // 2. The user type does impl Drop. This will make the blanket impl applicable, // which will then conflict with the explicit MustNotImplDrop impl below. // This will result in a compilation error, which is exactly what we want. trait MustNotImplDrop {} #[allow(clippy::drop_bounds, drop_bounds)] impl<T: $crate::__private::Drop> MustNotImplDrop for T {} impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
$(where
$($where_clause)*)?
{
}
};
}
#[project( ! $proj_not_unpin_mark:ident)]
$($tt:tt)*
) => {
$crate::__pin_project_internal! {
[$($proj_mut_ident)?]
[$($proj_ref_ident)?]
[$($proj_replace_ident)?]
[ ! $proj_not_unpin_mark]
[$($attrs)*]
$($tt)*
}
}; // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute // there could be more to parse
(
[$($proj_mut_ident:ident)?]
[$($proj_ref_ident:ident)?]
[$($proj_replace_ident:ident)?]
[$( ! $proj_not_unpin_mark:ident)?]
[$($attrs:tt)*]
impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> { fn drop(&mutself) { // SAFETY: the caller of `UnsafeDropInPlaceGuard::new` must guarantee // that `ptr` is valid for drop when this guard is destructed. unsafe {
ptr::drop_in_place(self.0);
}
}
}
// This is an internal helper used to ensure a value is overwritten without // its destructor being called. #[doc(hidden)] pubstruct UnsafeOverwriteGuard<T> {
target: *mut T,
value: ManuallyDrop<T>,
}
impl<T> Drop for UnsafeOverwriteGuard<T> { fn drop(&mutself) { // SAFETY: the caller of `UnsafeOverwriteGuard::new` must guarantee // that `target` is valid for writes when this guard is destructed. unsafe {
ptr::write(self.target, ptr::read(&*self.value));
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.