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