]> git.proxmox.com Git - rustc.git/blame - vendor/pin-project-lite/src/lib.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / vendor / pin-project-lite / src / lib.rs
CommitLineData
5869c6ff
XL
1//! A lightweight version of [pin-project] written with declarative macros.
2//!
3//! # Examples
4//!
5//! [`pin_project!`] macro creates a projection type covering all the fields of struct.
6//!
7//! ```rust
5869c6ff
XL
8//! use std::pin::Pin;
9//!
6a06907d
XL
10//! use pin_project_lite::pin_project;
11//!
5869c6ff
XL
12//! pin_project! {
13//! struct Struct<T, U> {
14//! #[pin]
15//! pinned: T,
16//! unpinned: U,
17//! }
18//! }
19//!
20//! impl<T, U> Struct<T, U> {
21//! fn method(self: Pin<&mut Self>) {
22//! let this = self.project();
23//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
24//! let _: &mut U = this.unpinned; // Normal reference to the field
25//! }
26//! }
27//! ```
28//!
29//! To use [`pin_project!`] on enums, you need to name the projection type
30//! returned from the method.
31//!
32//! ```rust
5869c6ff
XL
33//! use std::pin::Pin;
34//!
6a06907d
XL
35//! use pin_project_lite::pin_project;
36//!
5869c6ff
XL
37//! pin_project! {
38//! #[project = EnumProj]
39//! enum Enum<T, U> {
40//! Variant { #[pin] pinned: T, unpinned: U },
5099ac24 41//! }
5869c6ff
XL
42//! }
43//!
44//! impl<T, U> Enum<T, U> {
45//! fn method(self: Pin<&mut Self>) {
46//! match self.project() {
47//! EnumProj::Variant { pinned, unpinned } => {
48//! let _: Pin<&mut T> = pinned;
49//! let _: &mut U = unpinned;
50//! }
51//! }
52//! }
53//! }
54//! ```
55//!
56//! # [pin-project] vs pin-project-lite
57//!
58//! Here are some similarities and differences compared to [pin-project].
59//!
60//! ## Similar: Safety
61//!
62//! pin-project-lite guarantees safety in much the same way as [pin-project].
63//! Both are completely safe unless you write other unsafe code.
64//!
65//! ## Different: Minimal design
66//!
67//! This library does not tackle as expansive of a range of use cases as
68//! [pin-project] does. If your use case is not already covered, please use
69//! [pin-project].
70//!
71//! ## Different: No proc-macro related dependencies
72//!
73//! This is the **only** reason to use this crate. However, **if you already
74//! have proc-macro related dependencies in your crate's dependency graph, there
75//! is no benefit from using this crate.** (Note: There is almost no difference
76//! in the amount of code generated between [pin-project] and pin-project-lite.)
77//!
78//! ## Different: No useful error messages
79//!
80//! This macro does not handle any invalid input. So error messages are not to
81//! be useful in most cases. If you do need useful error messages, then upon
82//! error you can pass the same input to [pin-project] to receive a helpful
83//! description of the compile error.
84//!
5869c6ff
XL
85//! ## Different: No support for custom Unpin implementation
86//!
87//! pin-project supports this by [`UnsafeUnpin`][unsafe-unpin] and [`!Unpin`][not-unpin].
88//!
89//! ## Different: No support for tuple structs and tuple variants
90//!
91//! pin-project supports this.
92//!
93//! [not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin
94//! [pin-project]: https://github.com/taiki-e/pin-project
5869c6ff
XL
95//! [unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin
96
97#![no_std]
98#![doc(test(
99 no_crate_inject,
100 attr(
101 deny(warnings, rust_2018_idioms, single_use_lifetimes),
102 allow(dead_code, unused_variables)
103 )
104))]
5099ac24 105#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
136023e0 106#![warn(clippy::default_trait_access, clippy::wildcard_imports)]
5869c6ff
XL
107
108/// A macro that creates a projection type covering all the fields of struct.
109///
110/// This macro creates a projection type according to the following rules:
111///
5099ac24
FG
112/// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field.
113/// - For the other fields, makes the unpinned reference to the field.
5869c6ff
XL
114///
115/// And the following methods are implemented on the original type:
116///
117/// ```rust
118/// # use std::pin::Pin;
119/// # type Projection<'a> = &'a ();
120/// # type ProjectionRef<'a> = &'a ();
121/// # trait Dox {
122/// fn project(self: Pin<&mut Self>) -> Projection<'_>;
123/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
124/// # }
125/// ```
126///
127/// By passing an attribute with the same name as the method to the macro,
128/// you can name the projection type returned from the method. This allows you
129/// to use pattern matching on the projected types.
130///
131/// ```rust
132/// # use pin_project_lite::pin_project;
133/// # use std::pin::Pin;
134/// pin_project! {
135/// #[project = EnumProj]
136/// enum Enum<T> {
137/// Variant { #[pin] field: T },
138/// }
139/// }
140///
141/// impl<T> Enum<T> {
142/// fn method(self: Pin<&mut Self>) {
143/// let this: EnumProj<'_, T> = self.project();
144/// match this {
145/// EnumProj::Variant { field } => {
146/// let _: Pin<&mut T> = field;
147/// }
148/// }
149/// }
150/// }
151/// ```
152///
153/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
154/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
155/// out all unpinned fields in `Self`.
156///
157/// ```rust
158/// # use std::pin::Pin;
159/// # type MyProjReplace = ();
160/// # trait Dox {
161/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
162/// # }
163/// ```
164///
5869c6ff
XL
165/// Also, note that the projection types returned by `project` and `project_ref` have
166/// an additional lifetime at the beginning of generics.
167///
168/// ```text
169/// let this: EnumProj<'_, T> = self.project();
170/// ^^
171/// ```
172///
173/// The visibility of the projected types and projection methods is based on the
174/// original type. However, if the visibility of the original type is `pub`, the
175/// visibility of the projected types and the projection methods is downgraded
176/// to `pub(crate)`.
177///
178/// # Safety
179///
180/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate.
181/// Both are completely safe unless you write other unsafe code.
182///
183/// See [pin-project] crate for more details.
184///
185/// # Examples
186///
187/// ```rust
5869c6ff
XL
188/// use std::pin::Pin;
189///
6a06907d
XL
190/// use pin_project_lite::pin_project;
191///
5869c6ff
XL
192/// pin_project! {
193/// struct Struct<T, U> {
194/// #[pin]
195/// pinned: T,
196/// unpinned: U,
197/// }
198/// }
199///
200/// impl<T, U> Struct<T, U> {
201/// fn method(self: Pin<&mut Self>) {
202/// let this = self.project();
203/// let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
204/// let _: &mut U = this.unpinned; // Normal reference to the field
205/// }
206/// }
207/// ```
208///
209/// To use `pin_project!` on enums, you need to name the projection type
210/// returned from the method.
211///
212/// ```rust
5869c6ff
XL
213/// use std::pin::Pin;
214///
6a06907d
XL
215/// use pin_project_lite::pin_project;
216///
5869c6ff
XL
217/// pin_project! {
218/// #[project = EnumProj]
219/// enum Enum<T> {
220/// Struct {
221/// #[pin]
222/// field: T,
223/// },
224/// Unit,
225/// }
226/// }
227///
228/// impl<T> Enum<T> {
229/// fn method(self: Pin<&mut Self>) {
230/// match self.project() {
231/// EnumProj::Struct { field } => {
232/// let _: Pin<&mut T> = field;
233/// }
234/// EnumProj::Unit => {}
235/// }
236/// }
237/// }
238/// ```
239///
240/// If you want to call the `project()` method multiple times or later use the
241/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
242/// consuming the [`Pin`].
243///
244/// ```rust
5869c6ff
XL
245/// use std::pin::Pin;
246///
6a06907d
XL
247/// use pin_project_lite::pin_project;
248///
5869c6ff
XL
249/// pin_project! {
250/// struct Struct<T> {
251/// #[pin]
252/// field: T,
253/// }
254/// }
255///
256/// impl<T> Struct<T> {
257/// fn call_project_twice(mut self: Pin<&mut Self>) {
258/// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
259/// self.as_mut().project();
260/// self.as_mut().project();
261/// }
262/// }
263/// ```
264///
265/// # `!Unpin`
266///
267/// If you want to ensure that [`Unpin`] is not implemented, use `#[pin]`
268/// attribute for a [`PhantomPinned`] field.
269///
270/// ```rust
5869c6ff
XL
271/// use std::marker::PhantomPinned;
272///
6a06907d
XL
273/// use pin_project_lite::pin_project;
274///
5869c6ff
XL
275/// pin_project! {
276/// struct Struct<T> {
277/// field: T,
278/// #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`.
279/// _pin: PhantomPinned,
280/// }
281/// }
282/// ```
283///
284/// Note that using [`PhantomPinned`] without `#[pin]` attribute has no effect.
285///
286/// [`PhantomPinned`]: core::marker::PhantomPinned
287/// [`Pin::as_mut`]: core::pin::Pin::as_mut
288/// [`Pin`]: core::pin::Pin
289/// [pin-project]: https://github.com/taiki-e/pin-project
290#[macro_export]
291macro_rules! pin_project {
6a06907d 292 ($($tt:tt)*) => {
5869c6ff 293 $crate::__pin_project_internal! {
6a06907d 294 [][][][]
5869c6ff
XL
295 $($tt)*
296 }
297 };
298}
299
300// limitations:
5099ac24
FG
301// - no support for tuple structs and tuple variant (wontfix).
302// - no support for multiple trait/lifetime bounds.
303// - no support for `Self` in where clauses. (wontfix)
304// - no support for overlapping lifetime names. (wontfix)
305// - no interoperability with other field attributes.
306// - no useful error messages. (wontfix)
5869c6ff
XL
307// etc...
308
5869c6ff
XL
309#[doc(hidden)]
310#[macro_export]
923072b8
FG
311macro_rules! __pin_project_expand {
312 (
5869c6ff
XL
313 [$($proj_mut_ident:ident)?]
314 [$($proj_ref_ident:ident)?]
315 [$($proj_replace_ident:ident)?]
316 [$proj_vis:vis]
5099ac24 317 [$(#[$attrs:meta])* $vis:vis $struct_ty_ident:ident $ident:ident]
5869c6ff
XL
318 [$($def_generics:tt)*]
319 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
320 {
5099ac24 321 $($body_data:tt)*
5869c6ff 322 }
136023e0 323 $(impl $($pinned_drop:tt)*)?
5869c6ff 324 ) => {
923072b8 325 $crate::__pin_project_reconstruct! {
5099ac24
FG
326 [$(#[$attrs])* $vis $struct_ty_ident $ident]
327 [$($def_generics)*] [$($impl_generics)*]
328 [$($ty_generics)*] [$(where $($where_clause)*)?]
329 {
330 $($body_data)*
331 }
5869c6ff
XL
332 }
333
923072b8 334 $crate::__pin_project_make_proj_ty! {
5869c6ff 335 [$($proj_mut_ident)?]
5099ac24 336 [$proj_vis $struct_ty_ident $ident]
923072b8 337 [__pin_project_make_proj_field_mut]
5869c6ff
XL
338 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
339 {
5099ac24 340 $($body_data)*
5869c6ff
XL
341 }
342 }
923072b8 343 $crate::__pin_project_make_proj_ty! {
5869c6ff 344 [$($proj_ref_ident)?]
5099ac24 345 [$proj_vis $struct_ty_ident $ident]
923072b8 346 [__pin_project_make_proj_field_ref]
5869c6ff
XL
347 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
348 {
5099ac24 349 $($body_data)*
5869c6ff
XL
350 }
351 }
923072b8 352 $crate::__pin_project_make_proj_replace_ty! {
5869c6ff 353 [$($proj_replace_ident)?]
5099ac24 354 [$proj_vis $struct_ty_ident]
923072b8 355 [__pin_project_make_proj_field_replace]
5869c6ff
XL
356 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
357 {
5099ac24 358 $($body_data)*
5869c6ff
XL
359 }
360 }
361
923072b8 362 $crate::__pin_project_constant! {
5099ac24
FG
363 [$(#[$attrs])* $vis $struct_ty_ident $ident]
364 [$($proj_mut_ident)?] [$($proj_ref_ident)?] [$($proj_replace_ident)?]
365 [$proj_vis]
366 [$($def_generics)*] [$($impl_generics)*]
367 [$($ty_generics)*] [$(where $($where_clause)*)?]
368 {
369 $($body_data)*
370 }
371 $(impl $($pinned_drop)*)?
372 }
373 };
923072b8
FG
374}
375
376#[doc(hidden)]
377#[macro_export]
378macro_rules! __pin_project_constant {
379 (
5099ac24
FG
380 [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
381 [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
382 [$proj_vis:vis]
383 [$($def_generics:tt)*]
384 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
385 {
386 $(
387 $(#[$pin:ident])?
388 $field_vis:vis $field:ident: $field_ty:ty
389 ),+ $(,)?
390 }
391 $(impl $($pinned_drop:tt)*)?
392 ) => {
5869c6ff
XL
393 #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
394 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
395 // This lint warns of `clippy::*` generated by external macros.
396 // We allow this lint for compatibility with older compilers.
397 #[allow(clippy::unknown_clippy_lints)]
398 #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
399 #[allow(clippy::used_underscore_binding)]
400 const _: () = {
923072b8 401 $crate::__pin_project_make_proj_ty! {
5099ac24
FG
402 [$($proj_mut_ident)? Projection]
403 [$proj_vis struct $ident]
923072b8 404 [__pin_project_make_proj_field_mut]
5869c6ff
XL
405 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
406 {
407 $(
408 $(#[$pin])?
409 $field_vis $field: $field_ty
410 ),+
411 }
412 }
923072b8 413 $crate::__pin_project_make_proj_ty! {
5099ac24
FG
414 [$($proj_ref_ident)? ProjectionRef]
415 [$proj_vis struct $ident]
923072b8 416 [__pin_project_make_proj_field_ref]
5869c6ff
XL
417 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
418 {
419 $(
420 $(#[$pin])?
421 $field_vis $field: $field_ty
422 ),+
423 }
424 }
425
426 impl <$($impl_generics)*> $ident <$($ty_generics)*>
427 $(where
428 $($where_clause)*)?
429 {
923072b8 430 $crate::__pin_project_struct_make_proj_method! {
5099ac24 431 [$($proj_mut_ident)? Projection]
5869c6ff 432 [$proj_vis]
5869c6ff
XL
433 [project get_unchecked_mut mut]
434 [$($ty_generics)*]
435 {
436 $(
437 $(#[$pin])?
438 $field_vis $field
439 ),+
440 }
441 }
923072b8 442 $crate::__pin_project_struct_make_proj_method! {
5099ac24 443 [$($proj_ref_ident)? ProjectionRef]
5869c6ff 444 [$proj_vis]
5869c6ff
XL
445 [project_ref get_ref]
446 [$($ty_generics)*]
447 {
448 $(
449 $(#[$pin])?
450 $field_vis $field
451 ),+
452 }
453 }
923072b8 454 $crate::__pin_project_struct_make_proj_replace_method! {
5099ac24 455 [$($proj_replace_ident)?]
5869c6ff 456 [$proj_vis]
5099ac24 457 [ProjectionReplace]
5869c6ff
XL
458 [$($ty_generics)*]
459 {
460 $(
461 $(#[$pin])?
462 $field_vis $field
463 ),+
464 }
465 }
466 }
467
923072b8 468 $crate::__pin_project_make_unpin_impl! {
5869c6ff
XL
469 [$vis $ident]
470 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
471 $(
923072b8 472 $field: $crate::__pin_project_make_unpin_bound!(
5869c6ff
XL
473 $(#[$pin])? $field_ty
474 )
475 ),+
476 }
477
923072b8 478 $crate::__pin_project_make_drop_impl! {
5869c6ff
XL
479 [$ident]
480 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
136023e0 481 $(impl $($pinned_drop)*)?
5869c6ff
XL
482 }
483
484 // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
485 //
6a06907d
XL
486 // Taking a reference to a packed field is UB, and applying
487 // `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
5869c6ff
XL
488 //
489 // If the struct ends up having #[repr(packed)] applied somehow,
490 // this will generate an (unfriendly) error message. Under all reasonable
491 // circumstances, we'll detect the #[repr(packed)] attribute, and generate
492 // a much nicer error above.
493 //
494 // See https://github.com/taiki-e/pin-project/pull/34 for more details.
6a06907d
XL
495 //
496 // Note:
497 // - Lint-based tricks aren't perfect, but they're much better than nothing:
498 // https://github.com/taiki-e/pin-project-lite/issues/26
499 //
500 // - Enable both unaligned_references and safe_packed_borrows lints
501 // because unaligned_references lint does not exist in older compilers:
502 // https://github.com/taiki-e/pin-project-lite/pull/55
503 // https://github.com/rust-lang/rust/pull/82525
504 #[forbid(unaligned_references, safe_packed_borrows)]
5869c6ff
XL
505 fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
506 $(where
507 $($where_clause)*)?
508 {
509 $(
510 let _ = &this.$field;
511 )+
512 }
513 };
514 };
923072b8 515 (
5869c6ff 516 [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
5099ac24
FG
517 [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
518 [$proj_vis:vis]
5869c6ff
XL
519 [$($def_generics:tt)*]
520 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
521 {
522 $(
523 $(#[$variant_attrs:meta])*
524 $variant:ident $({
525 $(
526 $(#[$pin:ident])?
527 $field:ident: $field_ty:ty
5099ac24 528 ),+ $(,)?
5869c6ff 529 })?
5099ac24 530 ),+ $(,)?
5869c6ff 531 }
136023e0 532 $(impl $($pinned_drop:tt)*)?
5869c6ff 533 ) => {
5869c6ff
XL
534 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
535 // This lint warns of `clippy::*` generated by external macros.
536 // We allow this lint for compatibility with older compilers.
537 #[allow(clippy::unknown_clippy_lints)]
538 #[allow(clippy::used_underscore_binding)]
539 const _: () = {
540 impl <$($impl_generics)*> $ident <$($ty_generics)*>
541 $(where
542 $($where_clause)*)?
543 {
923072b8 544 $crate::__pin_project_enum_make_proj_method! {
5869c6ff 545 [$($proj_mut_ident)?]
5099ac24 546 [$proj_vis]
5869c6ff
XL
547 [project get_unchecked_mut mut]
548 [$($ty_generics)*]
549 {
550 $(
551 $variant $({
552 $(
553 $(#[$pin])?
554 $field
555 ),+
556 })?
557 ),+
558 }
559 }
923072b8 560 $crate::__pin_project_enum_make_proj_method! {
5869c6ff 561 [$($proj_ref_ident)?]
5099ac24 562 [$proj_vis]
5869c6ff
XL
563 [project_ref get_ref]
564 [$($ty_generics)*]
565 {
566 $(
567 $variant $({
568 $(
569 $(#[$pin])?
570 $field
571 ),+
572 })?
573 ),+
574 }
575 }
923072b8 576 $crate::__pin_project_enum_make_proj_replace_method! {
5869c6ff 577 [$($proj_replace_ident)?]
5099ac24 578 [$proj_vis]
5869c6ff
XL
579 [$($ty_generics)*]
580 {
581 $(
582 $variant $({
583 $(
584 $(#[$pin])?
585 $field
586 ),+
587 })?
588 ),+
589 }
590 }
591 }
592
923072b8 593 $crate::__pin_project_make_unpin_impl! {
5869c6ff
XL
594 [$vis $ident]
595 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
596 $(
597 $variant: ($(
598 $(
923072b8 599 $crate::__pin_project_make_unpin_bound!(
5869c6ff
XL
600 $(#[$pin])? $field_ty
601 )
602 ),+
603 )?)
604 ),+
605 }
606
923072b8 607 $crate::__pin_project_make_drop_impl! {
5869c6ff
XL
608 [$ident]
609 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
136023e0 610 $(impl $($pinned_drop)*)?
5869c6ff
XL
611 }
612
613 // We don't need to check for '#[repr(packed)]',
614 // since it does not apply to enums.
615 };
616 };
923072b8 617}
5869c6ff 618
923072b8
FG
619#[doc(hidden)]
620#[macro_export]
621macro_rules! __pin_project_reconstruct {
622 (
5099ac24
FG
623 [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
624 [$($def_generics:tt)*] [$($impl_generics:tt)*]
625 [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
626 {
627 $(
628 $(#[$pin:ident])?
629 $field_vis:vis $field:ident: $field_ty:ty
630 ),+ $(,)?
631 }
5869c6ff 632 ) => {
5099ac24
FG
633 $(#[$attrs])*
634 $vis struct $ident $($def_generics)*
635 $(where
636 $($where_clause)*)?
637 {
638 $(
639 $field_vis $field: $field_ty
640 ),+
5869c6ff
XL
641 }
642 };
923072b8 643 (
5099ac24
FG
644 [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
645 [$($def_generics:tt)*] [$($impl_generics:tt)*]
646 [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
647 {
648 $(
5099ac24
FG
649 $(#[$variant_attrs:meta])*
650 $variant:ident $({
651 $(
652 $(#[$pin:ident])?
653 $field:ident: $field_ty:ty
654 ),+ $(,)?
655 })?
656 ),+ $(,)?
657 }
658 ) => {
659 $(#[$attrs])*
660 $vis enum $ident $($def_generics)*
661 $(where
662 $($where_clause)*)?
663 {
664 $(
665 $(#[$variant_attrs])*
666 $variant $({
667 $(
668 $field: $field_ty
669 ),+
670 })?
5869c6ff
XL
671 ),+
672 }
5099ac24 673 };
923072b8
FG
674}
675
676#[doc(hidden)]
677#[macro_export]
678macro_rules! __pin_project_make_proj_ty {
679 ([] $($field:tt)*) => {};
680 (
5099ac24
FG
681 [$proj_ty_ident:ident $default_ident:ident]
682 [$proj_vis:vis struct $ident:ident]
683 $($field:tt)*
684 ) => {};
923072b8 685 (
5099ac24
FG
686 [$proj_ty_ident:ident]
687 [$proj_vis:vis struct $ident:ident]
923072b8
FG
688 [$__pin_project_make_proj_field:ident]
689 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
690 {
691 $(
5099ac24
FG
692 $(#[$pin:ident])?
693 $field_vis:vis $field:ident: $field_ty:ty
694 ),+ $(,)?
695 }
696 ) => {
923072b8 697 $crate::__pin_project_make_proj_ty_body! {
5099ac24
FG
698 [$proj_ty_ident]
699 [$proj_vis struct $ident]
923072b8 700 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
5099ac24
FG
701 [
702 $(
923072b8 703 $field_vis $field: $crate::$__pin_project_make_proj_field!(
5099ac24
FG
704 $(#[$pin])? $field_ty
705 )
706 ),+
707 ]
708 }
709 };
923072b8 710 (
5869c6ff 711 [$proj_ty_ident:ident]
5099ac24 712 [$proj_vis:vis enum $ident:ident]
923072b8
FG
713 [$__pin_project_make_proj_field:ident]
714 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
715 {
716 $(
5099ac24 717 $(#[$variant_attrs:meta])*
5869c6ff
XL
718 $variant:ident $({
719 $(
720 $(#[$pin:ident])?
721 $field:ident: $field_ty:ty
5099ac24 722 ),+ $(,)?
5869c6ff 723 })?
5099ac24 724 ),+ $(,)?
5869c6ff
XL
725 }
726 ) => {
923072b8 727 $crate::__pin_project_make_proj_ty_body! {
5099ac24
FG
728 [$proj_ty_ident]
729 [$proj_vis enum $ident]
923072b8 730 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
5099ac24
FG
731 [
732 $(
733 $variant $({
734 $(
923072b8 735 $field: $crate::$__pin_project_make_proj_field!(
5099ac24
FG
736 $(#[$pin])? $field_ty
737 )
738 ),+
739 })?
740 ),+
741 ]
5869c6ff
XL
742 }
743 };
923072b8
FG
744}
745
746#[doc(hidden)]
747#[macro_export]
748macro_rules! __pin_project_make_proj_ty_body {
749 (
750 [$proj_ty_ident:ident]
751 [$proj_vis:vis $struct_ty_ident:ident $ident:ident]
752 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
753 [$($body_data:tt)+]
754 ) => {
755 #[allow(dead_code)] // This lint warns unused fields/variants.
756 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
757 // This lint warns of `clippy::*` generated by external macros.
758 // We allow this lint for compatibility with older compilers.
759 #[allow(clippy::unknown_clippy_lints)]
760 #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
761 #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
762 #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
763 #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
764 $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*>
765 where
766 $ident <$($ty_generics)*>: '__pin
767 $(, $($where_clause)*)?
768 {
769 $($body_data)+
770 }
771 };
772}
773
774#[doc(hidden)]
775#[macro_export]
776macro_rules! __pin_project_make_proj_replace_ty {
777 ([] $($field:tt)*) => {};
778 (
779 [$proj_ty_ident:ident]
780 [$proj_vis:vis struct]
781 [$__pin_project_make_proj_field:ident]
782 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
783 {
784 $(
785 $(#[$pin:ident])?
786 $field_vis:vis $field:ident: $field_ty:ty
787 ),+ $(,)?
788 }
789 ) => {
790 $crate::__pin_project_make_proj_replace_ty_body! {
791 [$proj_ty_ident]
792 [$proj_vis struct]
793 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
794 [
795 $(
796 $field_vis $field: $crate::$__pin_project_make_proj_field!(
797 $(#[$pin])? $field_ty
798 )
799 ),+
800 ]
801 }
802 };
803 (
5869c6ff 804 [$proj_ty_ident:ident]
5099ac24 805 [$proj_vis:vis enum]
923072b8
FG
806 [$__pin_project_make_proj_field:ident]
807 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
808 {
809 $(
5099ac24 810 $(#[$variant_attrs:meta])*
5869c6ff
XL
811 $variant:ident $({
812 $(
813 $(#[$pin:ident])?
814 $field:ident: $field_ty:ty
5099ac24 815 ),+ $(,)?
5869c6ff 816 })?
5099ac24 817 ),+ $(,)?
5869c6ff
XL
818 }
819 ) => {
923072b8 820 $crate::__pin_project_make_proj_replace_ty_body! {
5099ac24
FG
821 [$proj_ty_ident]
822 [$proj_vis enum]
923072b8 823 [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
5099ac24
FG
824 [
825 $(
826 $variant $({
827 $(
923072b8 828 $field: $crate::$__pin_project_make_proj_field!(
5099ac24
FG
829 $(#[$pin])? $field_ty
830 )
831 ),+
832 })?
833 ),+
834 ]
5869c6ff
XL
835 }
836 };
923072b8
FG
837}
838
839#[doc(hidden)]
840#[macro_export]
841macro_rules! __pin_project_make_proj_replace_ty_body {
842 (
843 [$proj_ty_ident:ident]
844 [$proj_vis:vis $struct_ty_ident:ident]
845 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
846 [$($body_data:tt)+]
847 ) => {
848 #[allow(dead_code)] // This lint warns unused fields/variants.
849 #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
850 #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
851 #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
852 #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
853 $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*>
854 where
855 $($($where_clause)*)?
856 {
857 $($body_data)+
858 }
859 };
860}
861
862#[doc(hidden)]
863#[macro_export]
864macro_rules! __pin_project_make_proj_replace_block {
865 (
866 [$($proj_path:tt)+]
5869c6ff
XL
867 {
868 $(
869 $(#[$pin:ident])?
870 $field_vis:vis $field:ident
871 ),+
872 }
873 ) => {
874 let result = $($proj_path)* {
875 $(
923072b8 876 $field: $crate::__pin_project_make_replace_field_proj!(
5869c6ff
XL
877 $(#[$pin])? $field
878 )
879 ),+
880 };
881
882 {
883 ( $(
923072b8 884 $crate::__pin_project_make_unsafe_drop_in_place_guard!(
5869c6ff
XL
885 $(#[$pin])? $field
886 ),
887 )* );
888 }
889
890 result
891 };
923072b8
FG
892 ([$($proj_path:tt)+]) => { $($proj_path)* };
893}
5869c6ff 894
923072b8
FG
895#[doc(hidden)]
896#[macro_export]
897macro_rules! __pin_project_struct_make_proj_method {
898 ([] $($variant:tt)*) => {};
899 (
5099ac24
FG
900 [$proj_ty_ident:ident $_ignored_default_arg:ident]
901 [$proj_vis:vis]
902 [$method_ident:ident $get_method:ident $($mut:ident)?]
903 [$($ty_generics:tt)*]
904 $($variant:tt)*
905 ) => {
923072b8 906 $crate::__pin_project_struct_make_proj_method! {
5099ac24
FG
907 [$proj_ty_ident]
908 [$proj_vis]
909 [$method_ident $get_method $($mut)?]
910 [$($ty_generics)*]
911 $($variant)*
912 }
913 };
923072b8 914 (
5099ac24 915 [$proj_ty_ident:ident]
5869c6ff 916 [$proj_vis:vis]
5869c6ff
XL
917 [$method_ident:ident $get_method:ident $($mut:ident)?]
918 [$($ty_generics:tt)*]
919 {
920 $(
921 $(#[$pin:ident])?
922 $field_vis:vis $field:ident
923 ),+
924 }
925 ) => {
926 $proj_vis fn $method_ident<'__pin>(
927 self: $crate::__private::Pin<&'__pin $($mut)? Self>,
928 ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
929 unsafe {
930 let Self { $($field),* } = self.$get_method();
931 $proj_ty_ident {
932 $(
923072b8 933 $field: $crate::__pin_project_make_unsafe_field_proj!(
5869c6ff
XL
934 $(#[$pin])? $field
935 )
936 ),+
937 }
938 }
939 }
940 };
923072b8 941}
5869c6ff 942
923072b8
FG
943#[doc(hidden)]
944#[macro_export]
945macro_rules! __pin_project_struct_make_proj_replace_method {
946 ([] $($field:tt)*) => {};
947 (
5099ac24 948 [$proj_ty_ident:ident]
5869c6ff 949 [$proj_vis:vis]
5099ac24 950 [$_proj_ty_ident:ident]
5869c6ff
XL
951 [$($ty_generics:tt)*]
952 {
953 $(
954 $(#[$pin:ident])?
955 $field_vis:vis $field:ident
956 ),+
957 }
958 ) => {
959 $proj_vis fn project_replace(
960 self: $crate::__private::Pin<&mut Self>,
961 replacement: Self,
962 ) -> $proj_ty_ident <$($ty_generics)*> {
963 unsafe {
964 let __self_ptr: *mut Self = self.get_unchecked_mut();
965
966 // Destructors will run in reverse order, so next create a guard to overwrite
967 // `self` with the replacement value without calling destructors.
5099ac24 968 let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
5869c6ff
XL
969
970 let Self { $($field),* } = &mut *__self_ptr;
971
923072b8 972 $crate::__pin_project_make_proj_replace_block! {
5869c6ff
XL
973 [$proj_ty_ident]
974 {
975 $(
976 $(#[$pin])?
977 $field
978 ),+
979 }
980 }
981 }
982 }
983 };
923072b8
FG
984}
985
986#[doc(hidden)]
987#[macro_export]
988macro_rules! __pin_project_enum_make_proj_method {
989 ([] $($variant:tt)*) => {};
990 (
5869c6ff 991 [$proj_ty_ident:ident]
5099ac24 992 [$proj_vis:vis]
5869c6ff
XL
993 [$method_ident:ident $get_method:ident $($mut:ident)?]
994 [$($ty_generics:tt)*]
995 {
996 $(
997 $variant:ident $({
998 $(
999 $(#[$pin:ident])?
1000 $field:ident
1001 ),+
1002 })?
1003 ),+
1004 }
1005 ) => {
1006 $proj_vis fn $method_ident<'__pin>(
1007 self: $crate::__private::Pin<&'__pin $($mut)? Self>,
1008 ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
1009 unsafe {
1010 match self.$get_method() {
1011 $(
1012 Self::$variant $({
1013 $($field),+
1014 })? => {
1015 $proj_ty_ident::$variant $({
1016 $(
923072b8 1017 $field: $crate::__pin_project_make_unsafe_field_proj!(
5869c6ff
XL
1018 $(#[$pin])? $field
1019 )
1020 ),+
1021 })?
1022 }
1023 ),+
1024 }
1025 }
1026 }
1027 };
923072b8
FG
1028}
1029
1030#[doc(hidden)]
1031#[macro_export]
1032macro_rules! __pin_project_enum_make_proj_replace_method {
1033 ([] $($field:tt)*) => {};
1034 (
5869c6ff 1035 [$proj_ty_ident:ident]
5099ac24 1036 [$proj_vis:vis]
5869c6ff
XL
1037 [$($ty_generics:tt)*]
1038 {
1039 $(
1040 $variant:ident $({
1041 $(
1042 $(#[$pin:ident])?
1043 $field:ident
1044 ),+
1045 })?
1046 ),+
1047 }
1048 ) => {
1049 $proj_vis fn project_replace(
1050 self: $crate::__private::Pin<&mut Self>,
1051 replacement: Self,
1052 ) -> $proj_ty_ident <$($ty_generics)*> {
1053 unsafe {
1054 let __self_ptr: *mut Self = self.get_unchecked_mut();
1055
1056 // Destructors will run in reverse order, so next create a guard to overwrite
1057 // `self` with the replacement value without calling destructors.
5099ac24 1058 let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
5869c6ff
XL
1059
1060 match &mut *__self_ptr {
1061 $(
1062 Self::$variant $({
1063 $($field),+
1064 })? => {
923072b8 1065 $crate::__pin_project_make_proj_replace_block! {
5869c6ff
XL
1066 [$proj_ty_ident :: $variant]
1067 $({
1068 $(
1069 $(#[$pin])?
1070 $field
1071 ),+
1072 })?
1073 }
1074 }
1075 ),+
1076 }
1077 }
1078 }
1079 };
923072b8
FG
1080}
1081
1082#[doc(hidden)]
1083#[macro_export]
1084macro_rules! __pin_project_make_unpin_impl {
1085 (
5869c6ff 1086 [$vis:vis $ident:ident]
923072b8 1087 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
1088 $($field:tt)*
1089 ) => {
1090 // Automatically create the appropriate conditional `Unpin` implementation.
1091 //
1092 // Basically this is equivalent to the following code:
1093 // ```rust
1094 // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
1095 // ```
1096 //
1097 // However, if struct is public and there is a private type field,
1098 // this would cause an E0446 (private type in public interface).
1099 //
1100 // When RFC 2145 is implemented (rust-lang/rust#48054),
1101 // this will become a lint, rather then a hard error.
1102 //
1103 // As a workaround for this, we generate a new struct, containing all of the pinned
136023e0 1104 // fields from our #[pin_project] type. This struct is declared within
5869c6ff 1105 // a function, which makes it impossible to be named by user code.
136023e0 1106 // This guarantees that it will use the default auto-trait impl for Unpin -
5869c6ff 1107 // that is, it will implement Unpin iff all of its fields implement Unpin.
136023e0 1108 // This type can be safely declared as 'public', satisfying the privacy
5869c6ff
XL
1109 // checker without actually allowing user code to access it.
1110 //
1111 // This allows users to apply the #[pin_project] attribute to types
1112 // regardless of the privacy of the types of their fields.
1113 //
1114 // See also https://github.com/taiki-e/pin-project/pull/53.
1115 #[allow(non_snake_case)]
1116 $vis struct __Origin <'__pin, $($impl_generics)*>
1117 $(where
1118 $($where_clause)*)?
1119 {
1120 __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
1121 $($field)*
1122 }
1123 impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
1124 where
1125 __Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin
1126 $(, $($where_clause)*)?
1127 {
1128 }
1129 };
923072b8 1130}
5869c6ff 1131
923072b8
FG
1132#[doc(hidden)]
1133#[macro_export]
1134macro_rules! __pin_project_make_drop_impl {
1135 (
136023e0 1136 [$_ident:ident]
923072b8 1137 [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]
136023e0
XL
1138 impl $(<
1139 $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1140 $( $generics:ident
1141 $(: $generics_bound:path)?
1142 $(: ?$generics_unsized_bound:path)?
1143 $(: $generics_lifetime_bound:lifetime)?
1144 ),*
1145 >)? PinnedDrop for $self_ty:ty
1146 $(where
1147 $( $where_clause_ty:ty
1148 $(: $where_clause_bound:path)?
1149 $(: ?$where_clause_unsized_bound:path)?
1150 $(: $where_clause_lifetime_bound:lifetime)?
5099ac24 1151 ),* $(,)?
136023e0
XL
1152 )?
1153 {
1154 fn drop($($arg:ident)+: Pin<&mut Self>) {
1155 $($tt:tt)*
1156 }
1157 }
1158 ) => {
1159 impl $(<
1160 $( $lifetime $(: $lifetime_bound)? ,)*
1161 $( $generics
1162 $(: $generics_bound)?
1163 $(: ?$generics_unsized_bound)?
1164 $(: $generics_lifetime_bound)?
1165 ),*
1166 >)? $crate::__private::Drop for $self_ty
1167 $(where
1168 $( $where_clause_ty
1169 $(: $where_clause_bound)?
1170 $(: ?$where_clause_unsized_bound)?
1171 $(: $where_clause_lifetime_bound)?
1172 ),*
1173 )?
1174 {
1175 fn drop(&mut self) {
1176 // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
1177 // This is because destructors can be called multiple times in safe code and
1178 // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
1179 //
1180 // `__drop_inner` is defined as a safe method, but this is fine since
1181 // `__drop_inner` is not accessible by the users and we call `__drop_inner` only
1182 // once.
1183 //
1184 // Users can implement [`Drop`] safely using `pin_project!` and can drop a
1185 // type that implements `PinnedDrop` using the [`drop`] function safely.
1186 fn __drop_inner $(<
1187 $( $lifetime $(: $lifetime_bound)? ,)*
1188 $( $generics
1189 $(: $generics_bound)?
1190 $(: ?$generics_unsized_bound)?
1191 $(: $generics_lifetime_bound)?
1192 ),*
1193 >)? (
1194 $($arg)+: $crate::__private::Pin<&mut $self_ty>,
1195 )
1196 $(where
1197 $( $where_clause_ty
1198 $(: $where_clause_bound)?
1199 $(: ?$where_clause_unsized_bound)?
1200 $(: $where_clause_lifetime_bound)?
1201 ),*
1202 )?
1203 {
1204 // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
1205 fn __drop_inner() {}
1206 $($tt)*
1207 }
1208
1209 // Safety - we're in 'drop', so we know that 'self' will
1210 // never move again.
1211 let pinned_self: $crate::__private::Pin<&mut Self>
1212 = unsafe { $crate::__private::Pin::new_unchecked(self) };
1213 // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
1214 // is not accessible by the users, it is never called again.
1215 __drop_inner(pinned_self);
1216 }
1217 }
1218 };
923072b8 1219 (
5869c6ff 1220 [$ident:ident]
923072b8 1221 [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
5869c6ff
XL
1222 ) => {
1223 // Ensure that struct does not implement `Drop`.
1224 //
1225 // There are two possible cases:
1226 // 1. The user type does not implement Drop. In this case,
1227 // the first blanked impl will not apply to it. This code
1228 // will compile, as there is only one impl of MustNotImplDrop for the user type
1229 // 2. The user type does impl Drop. This will make the blanket impl applicable,
136023e0 1230 // which will then conflict with the explicit MustNotImplDrop impl below.
5869c6ff
XL
1231 // This will result in a compilation error, which is exactly what we want.
1232 trait MustNotImplDrop {}
1233 #[allow(clippy::drop_bounds, drop_bounds)]
1234 impl<T: $crate::__private::Drop> MustNotImplDrop for T {}
1235 impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
1236 $(where
1237 $($where_clause)*)?
1238 {
1239 }
1240 };
923072b8 1241}
5869c6ff 1242
923072b8
FG
1243#[doc(hidden)]
1244#[macro_export]
1245macro_rules! __pin_project_make_unpin_bound {
1246 (#[pin] $field_ty:ty) => {
5869c6ff
XL
1247 $field_ty
1248 };
923072b8 1249 ($field_ty:ty) => {
5869c6ff
XL
1250 $crate::__private::AlwaysUnpin<$field_ty>
1251 };
923072b8 1252}
5869c6ff 1253
923072b8
FG
1254#[doc(hidden)]
1255#[macro_export]
1256macro_rules! __pin_project_make_unsafe_field_proj {
1257 (#[pin] $field:ident) => {
5869c6ff
XL
1258 $crate::__private::Pin::new_unchecked($field)
1259 };
923072b8 1260 ($field:ident) => {
5869c6ff
XL
1261 $field
1262 };
923072b8 1263}
5869c6ff 1264
923072b8
FG
1265#[doc(hidden)]
1266#[macro_export]
1267macro_rules! __pin_project_make_replace_field_proj {
1268 (#[pin] $field:ident) => {
5869c6ff
XL
1269 $crate::__private::PhantomData
1270 };
923072b8 1271 ($field:ident) => {
5869c6ff
XL
1272 $crate::__private::ptr::read($field)
1273 };
923072b8 1274}
5869c6ff 1275
923072b8
FG
1276#[doc(hidden)]
1277#[macro_export]
1278macro_rules! __pin_project_make_unsafe_drop_in_place_guard {
1279 (#[pin] $field:ident) => {
5099ac24 1280 $crate::__private::UnsafeDropInPlaceGuard::new($field)
5869c6ff 1281 };
923072b8 1282 ($field:ident) => {
5869c6ff
XL
1283 ()
1284 };
923072b8 1285}
5869c6ff 1286
923072b8
FG
1287#[doc(hidden)]
1288#[macro_export]
1289macro_rules! __pin_project_make_proj_field_mut {
1290 (#[pin] $field_ty:ty) => {
5869c6ff
XL
1291 $crate::__private::Pin<&'__pin mut ($field_ty)>
1292 };
923072b8 1293 ($field_ty:ty) => {
5869c6ff
XL
1294 &'__pin mut ($field_ty)
1295 };
923072b8
FG
1296}
1297
1298#[doc(hidden)]
1299#[macro_export]
1300macro_rules! __pin_project_make_proj_field_ref {
1301 (#[pin] $field_ty:ty) => {
5869c6ff
XL
1302 $crate::__private::Pin<&'__pin ($field_ty)>
1303 };
923072b8 1304 ($field_ty:ty) => {
5869c6ff
XL
1305 &'__pin ($field_ty)
1306 };
923072b8 1307}
5869c6ff 1308
923072b8
FG
1309#[doc(hidden)]
1310#[macro_export]
1311macro_rules! __pin_project_make_proj_field_replace {
1312 (#[pin] $field_ty:ty) => {
5869c6ff
XL
1313 $crate::__private::PhantomData<$field_ty>
1314 };
923072b8 1315 ($field_ty:ty) => {
5869c6ff
XL
1316 $field_ty
1317 };
923072b8 1318}
5869c6ff 1319
923072b8
FG
1320#[doc(hidden)]
1321#[macro_export]
1322macro_rules! __pin_project_internal {
5099ac24 1323 // parsing proj_mut_ident
6a06907d
XL
1324 (
1325 []
1326 [$($proj_ref_ident:ident)?]
1327 [$($proj_replace_ident:ident)?]
1328 [$($attrs:tt)*]
1329
1330 #[project = $proj_mut_ident:ident]
1331 $($tt:tt)*
1332 ) => {
1333 $crate::__pin_project_internal! {
1334 [$proj_mut_ident]
1335 [$($proj_ref_ident)?]
1336 [$($proj_replace_ident)?]
1337 [$($attrs)*]
1338 $($tt)*
1339 }
1340 };
5099ac24 1341 // parsing proj_ref_ident
923072b8 1342 (
6a06907d
XL
1343 [$($proj_mut_ident:ident)?]
1344 []
1345 [$($proj_replace_ident:ident)?]
1346 [$($attrs:tt)*]
1347
1348 #[project_ref = $proj_ref_ident:ident]
1349 $($tt:tt)*
923072b8 1350 ) => {
6a06907d
XL
1351 $crate::__pin_project_internal! {
1352 [$($proj_mut_ident)?]
1353 [$proj_ref_ident]
1354 [$($proj_replace_ident)?]
1355 [$($attrs)*]
1356 $($tt)*
1357 }
1358 };
5099ac24 1359 // parsing proj_replace_ident
923072b8 1360 (
6a06907d
XL
1361 [$($proj_mut_ident:ident)?]
1362 [$($proj_ref_ident:ident)?]
1363 []
1364 [$($attrs:tt)*]
1365
1366 #[project_replace = $proj_replace_ident:ident]
1367 $($tt:tt)*
923072b8 1368 ) => {
6a06907d
XL
1369 $crate::__pin_project_internal! {
1370 [$($proj_mut_ident)?]
1371 [$($proj_ref_ident)?]
1372 [$proj_replace_ident]
1373 [$($attrs)*]
1374 $($tt)*
1375 }
1376 };
5099ac24
FG
1377 // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute
1378 // there could be more to parse
923072b8 1379 (
6a06907d
XL
1380 [$($proj_mut_ident:ident)?]
1381 [$($proj_ref_ident:ident)?]
1382 [$($proj_replace_ident:ident)?]
1383 [$($attrs:tt)*]
1384
1385 #[$($attr:tt)*]
1386 $($tt:tt)*
923072b8 1387 ) => {
6a06907d
XL
1388 $crate::__pin_project_internal! {
1389 [$($proj_mut_ident)?]
1390 [$($proj_ref_ident)?]
1391 [$($proj_replace_ident)?]
1392 [$($attrs)* #[$($attr)*]]
1393 $($tt)*
1394 }
1395 };
5099ac24
FG
1396 // now determine visibility
1397 // if public, downgrade
923072b8 1398 (
5869c6ff
XL
1399 [$($proj_mut_ident:ident)?]
1400 [$($proj_ref_ident:ident)?]
1401 [$($proj_replace_ident:ident)?]
6a06907d 1402 [$($attrs:tt)*]
5099ac24
FG
1403 pub $struct_ty_ident:ident $ident:ident
1404 $($tt:tt)*
923072b8
FG
1405 ) => {
1406 $crate::__pin_project_parse_generics! {
5869c6ff
XL
1407 [$($proj_mut_ident)?]
1408 [$($proj_ref_ident)?]
1409 [$($proj_replace_ident)?]
5099ac24
FG
1410 [$($attrs)*]
1411 [pub $struct_ty_ident $ident pub(crate)]
1412 $($tt)*
5869c6ff
XL
1413 }
1414 };
923072b8 1415 (
5869c6ff
XL
1416 [$($proj_mut_ident:ident)?]
1417 [$($proj_ref_ident:ident)?]
1418 [$($proj_replace_ident:ident)?]
6a06907d 1419 [$($attrs:tt)*]
5099ac24
FG
1420 $vis:vis $struct_ty_ident:ident $ident:ident
1421 $($tt:tt)*
923072b8
FG
1422 ) => {
1423 $crate::__pin_project_parse_generics! {
5869c6ff
XL
1424 [$($proj_mut_ident)?]
1425 [$($proj_ref_ident)?]
1426 [$($proj_replace_ident)?]
5099ac24
FG
1427 [$($attrs)*]
1428 [$vis $struct_ty_ident $ident $vis]
1429 $($tt)*
5869c6ff
XL
1430 }
1431 };
923072b8
FG
1432}
1433
1434#[doc(hidden)]
1435#[macro_export]
1436macro_rules! __pin_project_parse_generics {
5869c6ff
XL
1437 (
1438 [$($proj_mut_ident:ident)?]
1439 [$($proj_ref_ident:ident)?]
1440 [$($proj_replace_ident:ident)?]
6a06907d 1441 [$($attrs:tt)*]
5099ac24
FG
1442 [$vis:vis $struct_ty_ident:ident $ident:ident $proj_ty_vis:vis]
1443 $(<
5869c6ff
XL
1444 $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
1445 $( $generics:ident
1446 $(: $generics_bound:path)?
1447 $(: ?$generics_unsized_bound:path)?
1448 $(: $generics_lifetime_bound:lifetime)?
1449 $(= $generics_default:ty)?
1450 ),* $(,)?
1451 >)?
1452 $(where
1453 $( $where_clause_ty:ty
1454 $(: $where_clause_bound:path)?
1455 $(: ?$where_clause_unsized_bound:path)?
1456 $(: $where_clause_lifetime_bound:lifetime)?
1457 ),* $(,)?
1458 )?
1459 {
5099ac24 1460 $($body_data:tt)*
5869c6ff 1461 }
136023e0 1462 $(impl $($pinned_drop:tt)*)?
5869c6ff 1463 ) => {
923072b8 1464 $crate::__pin_project_expand! {
5869c6ff
XL
1465 [$($proj_mut_ident)?]
1466 [$($proj_ref_ident)?]
1467 [$($proj_replace_ident)?]
5099ac24
FG
1468 [$proj_ty_vis]
1469 [$($attrs)* $vis $struct_ty_ident $ident]
5869c6ff
XL
1470 [$(<
1471 $( $lifetime $(: $lifetime_bound)? ,)*
1472 $( $generics
1473 $(: $generics_bound)?
1474 $(: ?$generics_unsized_bound)?
1475 $(: $generics_lifetime_bound)?
1476 $(= $generics_default)?
1477 ),*
1478 >)?]
1479 [$(
1480 $( $lifetime $(: $lifetime_bound)? ,)*
1481 $( $generics
1482 $(: $generics_bound)?
1483 $(: ?$generics_unsized_bound)?
1484 $(: $generics_lifetime_bound)?
1485 ),*
1486 )?]
1487 [$( $( $lifetime ,)* $( $generics ),* )?]
1488 [$(where $( $where_clause_ty
1489 $(: $where_clause_bound)?
1490 $(: ?$where_clause_unsized_bound)?
1491 $(: $where_clause_lifetime_bound)?
1492 ),* )?]
1493 {
5099ac24 1494 $($body_data)*
5869c6ff 1495 }
136023e0 1496 $(impl $($pinned_drop)*)?
5869c6ff
XL
1497 }
1498 };
1499}
1500
5869c6ff
XL
1501#[doc(hidden)]
1502pub mod __private {
5099ac24 1503 use core::mem::ManuallyDrop;
5869c6ff
XL
1504 #[doc(hidden)]
1505 pub use core::{
1506 marker::{PhantomData, Unpin},
5869c6ff
XL
1507 ops::Drop,
1508 pin::Pin,
1509 ptr,
1510 };
1511
1512 // This is an internal helper struct used by `pin_project!`.
1513 #[doc(hidden)]
1514 pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
1515
1516 impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
1517
1518 // This is an internal helper used to ensure a value is dropped.
1519 #[doc(hidden)]
5099ac24
FG
1520 pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);
1521
1522 impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {
1523 #[doc(hidden)]
1524 pub unsafe fn new(ptr: *mut T) -> Self {
1525 Self(ptr)
1526 }
1527 }
5869c6ff
XL
1528
1529 impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
1530 fn drop(&mut self) {
1531 unsafe {
1532 ptr::drop_in_place(self.0);
1533 }
1534 }
1535 }
1536
1537 // This is an internal helper used to ensure a value is overwritten without
1538 // its destructor being called.
1539 #[doc(hidden)]
1540 pub struct UnsafeOverwriteGuard<T> {
5099ac24
FG
1541 target: *mut T,
1542 value: ManuallyDrop<T>,
1543 }
1544
1545 impl<T> UnsafeOverwriteGuard<T> {
1546 #[doc(hidden)]
1547 pub unsafe fn new(target: *mut T, value: T) -> Self {
1548 Self { target, value: ManuallyDrop::new(value) }
1549 }
5869c6ff
XL
1550 }
1551
1552 impl<T> Drop for UnsafeOverwriteGuard<T> {
1553 fn drop(&mut self) {
1554 unsafe {
1555 ptr::write(self.target, ptr::read(&*self.value));
1556 }
1557 }
1558 }
1559}