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