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