1 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
2 | |
3 | //! Implementation detail of the `pin-project` crate. - **do not use directly** |
4 | |
5 | #![doc (test( |
6 | no_crate_inject, |
7 | attr( |
8 | deny(warnings, rust_2018_idioms, single_use_lifetimes), |
9 | allow(dead_code, unused_variables) |
10 | ) |
11 | ))] |
12 | #![forbid (unsafe_code)] |
13 | #![allow (clippy::needless_doctest_main)] |
14 | |
15 | #[macro_use ] |
16 | mod error; |
17 | |
18 | #[macro_use ] |
19 | mod utils; |
20 | |
21 | mod pin_project; |
22 | mod pinned_drop; |
23 | |
24 | use proc_macro::TokenStream; |
25 | |
26 | /// An attribute that creates projection types covering all the fields of |
27 | /// struct or enum. |
28 | /// |
29 | /// This attribute creates projection types according to the following rules: |
30 | /// |
31 | /// - For the fields that use `#[pin]` attribute, create the pinned reference to |
32 | /// the field. |
33 | /// - For the other fields, create a normal reference to the field. |
34 | /// |
35 | /// And the following methods are implemented on the original type: |
36 | /// |
37 | /// ``` |
38 | /// # use std::pin::Pin; |
39 | /// # type Projection<'a> = &'a (); |
40 | /// # type ProjectionRef<'a> = &'a (); |
41 | /// # trait Dox { |
42 | /// fn project(self: Pin<&mut Self>) -> Projection<'_>; |
43 | /// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; |
44 | /// # } |
45 | /// ``` |
46 | /// |
47 | /// By passing an argument with the same name as the method to the attribute, |
48 | /// you can name the projection type returned from the method. This allows you |
49 | /// to use pattern matching on the projected types. |
50 | /// |
51 | /// ``` |
52 | /// # use pin_project::pin_project; |
53 | /// # use std::pin::Pin; |
54 | /// #[pin_project(project = EnumProj)] |
55 | /// enum Enum<T> { |
56 | /// Variant(#[pin] T), |
57 | /// } |
58 | /// |
59 | /// impl<T> Enum<T> { |
60 | /// fn method(self: Pin<&mut Self>) { |
61 | /// let this: EnumProj<'_, T> = self.project(); |
62 | /// match this { |
63 | /// EnumProj::Variant(x) => { |
64 | /// let _: Pin<&mut T> = x; |
65 | /// } |
66 | /// } |
67 | /// } |
68 | /// } |
69 | /// ``` |
70 | /// |
71 | /// Note that the projection types returned by `project` and `project_ref` have |
72 | /// an additional lifetime at the beginning of generics. |
73 | /// |
74 | /// ```text |
75 | /// let this: EnumProj<'_, T> = self.project(); |
76 | /// ^^ |
77 | /// ``` |
78 | /// |
79 | /// The visibility of the projected types and projection methods is based on the |
80 | /// original type. However, if the visibility of the original type is `pub`, the |
81 | /// visibility of the projected types and the projection methods is downgraded |
82 | /// to `pub(crate)`. |
83 | /// |
84 | /// # Safety |
85 | /// |
86 | /// This attribute is completely safe. In the absence of other `unsafe` code |
87 | /// *that you write*, it is impossible to cause [undefined |
88 | /// behavior][undefined-behavior] with this attribute. |
89 | /// |
90 | /// This is accomplished by enforcing the four requirements for pin projection |
91 | /// stated in [the Rust documentation][pin-projection]: |
92 | /// |
93 | /// 1. The struct must only be [`Unpin`] if all the structural fields are |
94 | /// [`Unpin`]. |
95 | /// |
96 | /// To enforce this, this attribute will automatically generate an [`Unpin`] |
97 | /// implementation for you, which will require that all structurally pinned |
98 | /// fields be [`Unpin`]. |
99 | /// |
100 | /// If you attempt to provide an [`Unpin`] impl, the blanket impl will then |
101 | /// apply to your type, causing a compile-time error due to the conflict with |
102 | /// the second impl. |
103 | /// |
104 | /// If you wish to provide a manual [`Unpin`] impl, you can do so via the |
105 | /// [`UnsafeUnpin`][unsafe-unpin] argument. |
106 | /// |
107 | /// 2. The destructor of the struct must not move structural fields out of its |
108 | /// argument. |
109 | /// |
110 | /// To enforce this, this attribute will generate code like this: |
111 | /// |
112 | /// ``` |
113 | /// struct MyStruct {} |
114 | /// trait MyStructMustNotImplDrop {} |
115 | /// # #[allow (unknown_lints, drop_bounds)] |
116 | /// impl<T: Drop> MyStructMustNotImplDrop for T {} |
117 | /// impl MyStructMustNotImplDrop for MyStruct {} |
118 | /// ``` |
119 | /// |
120 | /// If you attempt to provide an [`Drop`] impl, the blanket impl will then |
121 | /// apply to your type, causing a compile-time error due to the conflict with |
122 | /// the second impl. |
123 | /// |
124 | /// If you wish to provide a custom [`Drop`] impl, you can annotate an impl |
125 | /// with [`#[pinned_drop]`][pinned-drop]. This impl takes a pinned version of |
126 | /// your struct - that is, [`Pin`]`<&mut MyStruct>` where `MyStruct` is the |
127 | /// type of your struct. |
128 | /// |
129 | /// You can call `.project()` on this type as usual, along with any other |
130 | /// methods you have defined. Because your code is never provided with |
131 | /// a `&mut MyStruct`, it is impossible to move out of pin-projectable |
132 | /// fields in safe code in your destructor. |
133 | /// |
134 | /// 3. You must make sure that you uphold the [`Drop` |
135 | /// guarantee][drop-guarantee]: once your struct is pinned, the memory that |
136 | /// contains the content is not overwritten or deallocated without calling |
137 | /// the content's destructors. |
138 | /// |
139 | /// Safe code doesn't need to worry about this - the only way to violate |
140 | /// this requirement is to manually deallocate memory (which is `unsafe`), |
141 | /// or to overwrite a field with something else. |
142 | /// Because your custom destructor takes [`Pin`]`<&mut MyStruct>`, it's |
143 | /// impossible to obtain a mutable reference to a pin-projected field in safe |
144 | /// code. |
145 | /// |
146 | /// 4. You must not offer any other operations that could lead to data being |
147 | /// moved out of the structural fields when your type is pinned. |
148 | /// |
149 | /// As with requirement 3, it is impossible for safe code to violate this. |
150 | /// This crate ensures that safe code can never obtain a mutable reference to |
151 | /// `#[pin]` fields, which prevents you from ever moving out of them in safe |
152 | /// code. |
153 | /// |
154 | /// Pin projections are also incompatible with [`#[repr(packed)]`][repr-packed] |
155 | /// types. Attempting to use this attribute on a `#[repr(packed)]` type results |
156 | /// in a compile-time error. |
157 | /// |
158 | /// # Examples |
159 | /// |
160 | /// `#[pin_project]` can be used on structs and enums. |
161 | /// |
162 | /// ``` |
163 | /// use std::pin::Pin; |
164 | /// |
165 | /// use pin_project::pin_project; |
166 | /// |
167 | /// #[pin_project] |
168 | /// struct Struct<T, U> { |
169 | /// #[pin] |
170 | /// pinned: T, |
171 | /// unpinned: U, |
172 | /// } |
173 | /// |
174 | /// impl<T, U> Struct<T, U> { |
175 | /// fn method(self: Pin<&mut Self>) { |
176 | /// let this = self.project(); |
177 | /// let _: Pin<&mut T> = this.pinned; |
178 | /// let _: &mut U = this.unpinned; |
179 | /// } |
180 | /// } |
181 | /// ``` |
182 | /// |
183 | /// ``` |
184 | /// use std::pin::Pin; |
185 | /// |
186 | /// use pin_project::pin_project; |
187 | /// |
188 | /// #[pin_project] |
189 | /// struct TupleStruct<T, U>(#[pin] T, U); |
190 | /// |
191 | /// impl<T, U> TupleStruct<T, U> { |
192 | /// fn method(self: Pin<&mut Self>) { |
193 | /// let this = self.project(); |
194 | /// let _: Pin<&mut T> = this.0; |
195 | /// let _: &mut U = this.1; |
196 | /// } |
197 | /// } |
198 | /// ``` |
199 | /// |
200 | /// To use `#[pin_project]` on enums, you need to name the projection type |
201 | /// returned from the method. |
202 | /// |
203 | /// ``` |
204 | /// use std::pin::Pin; |
205 | /// |
206 | /// use pin_project::pin_project; |
207 | /// |
208 | /// #[pin_project(project = EnumProj)] |
209 | /// enum Enum<T, U> { |
210 | /// Tuple(#[pin] T), |
211 | /// Struct { field: U }, |
212 | /// Unit, |
213 | /// } |
214 | /// |
215 | /// impl<T, U> Enum<T, U> { |
216 | /// fn method(self: Pin<&mut Self>) { |
217 | /// match self.project() { |
218 | /// EnumProj::Tuple(x) => { |
219 | /// let _: Pin<&mut T> = x; |
220 | /// } |
221 | /// EnumProj::Struct { field } => { |
222 | /// let _: &mut U = field; |
223 | /// } |
224 | /// EnumProj::Unit => {} |
225 | /// } |
226 | /// } |
227 | /// } |
228 | /// ``` |
229 | /// |
230 | /// When `#[pin_project]` is used on enums, only named projection types and |
231 | /// methods are generated because there is no way to access variants of |
232 | /// projected types without naming it. |
233 | /// For example, in the above example, only the `project` method is generated, |
234 | /// and the `project_ref` method is not generated. |
235 | /// (When `#[pin_project]` is used on structs, both methods are always generated.) |
236 | /// |
237 | /// ```compile_fail,E0599 |
238 | /// # use pin_project::pin_project; |
239 | /// # use std::pin::Pin; |
240 | /// # |
241 | /// # #[pin_project(project = EnumProj)] |
242 | /// # enum Enum<T, U> { |
243 | /// # Tuple(#[pin] T), |
244 | /// # Struct { field: U }, |
245 | /// # Unit, |
246 | /// # } |
247 | /// # |
248 | /// impl<T, U> Enum<T, U> { |
249 | /// fn call_project_ref(self: Pin<&Self>) { |
250 | /// let _this = self.project_ref(); |
251 | /// //~^ ERROR no method named `project_ref` found for struct `Pin<&Enum<T, U>>` in the current scope |
252 | /// } |
253 | /// } |
254 | /// ``` |
255 | /// |
256 | /// If you want to call `.project()` multiple times or later use the |
257 | /// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid |
258 | /// consuming the [`Pin`]. |
259 | /// |
260 | /// ``` |
261 | /// use std::pin::Pin; |
262 | /// |
263 | /// use pin_project::pin_project; |
264 | /// |
265 | /// #[pin_project] |
266 | /// struct Struct<T> { |
267 | /// #[pin] |
268 | /// field: T, |
269 | /// } |
270 | /// |
271 | /// impl<T> Struct<T> { |
272 | /// fn call_project_twice(mut self: Pin<&mut Self>) { |
273 | /// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`. |
274 | /// self.as_mut().project(); |
275 | /// self.as_mut().project(); |
276 | /// } |
277 | /// } |
278 | /// ``` |
279 | /// |
280 | /// # `!Unpin` |
281 | /// |
282 | /// If you want to ensure that [`Unpin`] is not implemented, use the `!Unpin` |
283 | /// argument to `#[pin_project]`. |
284 | /// |
285 | /// ``` |
286 | /// use pin_project::pin_project; |
287 | /// |
288 | /// #[pin_project(!Unpin)] |
289 | /// struct Struct<T> { |
290 | /// field: T, |
291 | /// } |
292 | /// ``` |
293 | /// |
294 | /// This is equivalent to using `#[pin]` attribute for the [`PhantomPinned`] |
295 | /// field. |
296 | /// |
297 | /// ``` |
298 | /// use std::marker::PhantomPinned; |
299 | /// |
300 | /// use pin_project::pin_project; |
301 | /// |
302 | /// #[pin_project] |
303 | /// struct Struct<T> { |
304 | /// field: T, |
305 | /// #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`. |
306 | /// _pin: PhantomPinned, |
307 | /// } |
308 | /// ``` |
309 | /// |
310 | /// Note that using [`PhantomPinned`] without `#[pin]` attribute has no effect. |
311 | /// |
312 | /// # `UnsafeUnpin` |
313 | /// |
314 | /// If you want to implement [`Unpin`] manually, you must use the `UnsafeUnpin` |
315 | /// argument to `#[pin_project]`. |
316 | /// |
317 | /// ``` |
318 | /// use pin_project::{pin_project, UnsafeUnpin}; |
319 | /// |
320 | /// #[pin_project(UnsafeUnpin)] |
321 | /// struct Struct<T, U> { |
322 | /// #[pin] |
323 | /// pinned: T, |
324 | /// unpinned: U, |
325 | /// } |
326 | /// |
327 | /// unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {} |
328 | /// ``` |
329 | /// |
330 | /// Note the usage of the unsafe [`UnsafeUnpin`] trait, instead of the usual |
331 | /// [`Unpin`] trait. [`UnsafeUnpin`] behaves exactly like [`Unpin`], except that |
332 | /// is unsafe to implement. This unsafety comes from the fact that pin |
333 | /// projections are being used. If you implement [`UnsafeUnpin`], you must |
334 | /// ensure that it is only implemented when all pin-projected fields implement |
335 | /// [`Unpin`]. |
336 | /// |
337 | /// See [`UnsafeUnpin`] trait for more details. |
338 | /// |
339 | /// # `#[pinned_drop]` |
340 | /// |
341 | /// In order to correctly implement pin projections, a type's [`Drop`] impl must |
342 | /// not move out of any structurally pinned fields. Unfortunately, |
343 | /// [`Drop::drop`] takes `&mut Self`, not [`Pin`]`<&mut Self>`. |
344 | /// |
345 | /// To ensure that this requirement is upheld, the `#[pin_project]` attribute |
346 | /// will provide a [`Drop`] impl for you. This [`Drop`] impl will delegate to |
347 | /// an impl block annotated with `#[pinned_drop]` if you use the `PinnedDrop` |
348 | /// argument to `#[pin_project]`. |
349 | /// |
350 | /// This impl block acts just like a normal [`Drop`] impl, |
351 | /// except for the following two: |
352 | /// |
353 | /// - `drop` method takes [`Pin`]`<&mut Self>` |
354 | /// - Name of the trait is `PinnedDrop`. |
355 | /// |
356 | /// ``` |
357 | /// # use std::pin::Pin; |
358 | /// pub trait PinnedDrop { |
359 | /// fn drop(self: Pin<&mut Self>); |
360 | /// } |
361 | /// ``` |
362 | /// |
363 | /// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you |
364 | /// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`] |
365 | /// function just like dropping a type that directly implements [`Drop`]. |
366 | /// |
367 | /// In particular, it will never be called more than once, just like |
368 | /// [`Drop::drop`]. |
369 | /// |
370 | /// For example: |
371 | /// |
372 | /// ``` |
373 | /// use std::{fmt::Debug, pin::Pin}; |
374 | /// |
375 | /// use pin_project::{pin_project, pinned_drop}; |
376 | /// |
377 | /// #[pin_project(PinnedDrop)] |
378 | /// struct PrintOnDrop<T: Debug, U: Debug> { |
379 | /// #[pin] |
380 | /// pinned_field: T, |
381 | /// unpin_field: U, |
382 | /// } |
383 | /// |
384 | /// #[pinned_drop] |
385 | /// impl<T: Debug, U: Debug> PinnedDrop for PrintOnDrop<T, U> { |
386 | /// fn drop(self: Pin<&mut Self>) { |
387 | /// println!("Dropping pinned field: {:?}" , self.pinned_field); |
388 | /// println!("Dropping unpin field: {:?}" , self.unpin_field); |
389 | /// } |
390 | /// } |
391 | /// |
392 | /// fn main() { |
393 | /// let _x = PrintOnDrop { pinned_field: true, unpin_field: 40 }; |
394 | /// } |
395 | /// ``` |
396 | /// |
397 | /// See also [`#[pinned_drop]`][macro@pinned_drop] attribute. |
398 | /// |
399 | /// # `project_replace` method |
400 | /// |
401 | /// In addition to the `project` and `project_ref` methods which are always |
402 | /// provided when you use the `#[pin_project]` attribute, there is a third |
403 | /// method, `project_replace` which can be useful in some situations. It is |
404 | /// equivalent to [`Pin::set`], except that the unpinned fields are moved and |
405 | /// returned, instead of being dropped in-place. |
406 | /// |
407 | /// ``` |
408 | /// # use std::pin::Pin; |
409 | /// # type ProjectionOwned = (); |
410 | /// # trait Dox { |
411 | /// fn project_replace(self: Pin<&mut Self>, other: Self) -> ProjectionOwned; |
412 | /// # } |
413 | /// ``` |
414 | /// |
415 | /// The `ProjectionOwned` type is identical to the `Self` type, except that |
416 | /// all pinned fields have been replaced by equivalent [`PhantomData`] types. |
417 | /// |
418 | /// This method is opt-in, because it is only supported for [`Sized`] types, and |
419 | /// because it is incompatible with the [`#[pinned_drop]`][pinned-drop] |
420 | /// attribute described above. It can be enabled by using |
421 | /// `#[pin_project(project_replace)]`. |
422 | /// |
423 | /// For example: |
424 | /// |
425 | /// ``` |
426 | /// use std::{marker::PhantomData, pin::Pin}; |
427 | /// |
428 | /// use pin_project::pin_project; |
429 | /// |
430 | /// #[pin_project(project_replace)] |
431 | /// struct Struct<T, U> { |
432 | /// #[pin] |
433 | /// pinned_field: T, |
434 | /// unpinned_field: U, |
435 | /// } |
436 | /// |
437 | /// impl<T, U> Struct<T, U> { |
438 | /// fn method(self: Pin<&mut Self>, other: Self) { |
439 | /// let this = self.project_replace(other); |
440 | /// let _: U = this.unpinned_field; |
441 | /// let _: PhantomData<T> = this.pinned_field; |
442 | /// } |
443 | /// } |
444 | /// ``` |
445 | /// |
446 | /// By passing the value to the `project_replace` argument, you can name the |
447 | /// returned type of the `project_replace` method. This is necessary whenever |
448 | /// destructuring the return type of the `project_replace` method, and work in exactly |
449 | /// the same way as the `project` and `project_ref` arguments. |
450 | /// |
451 | /// ``` |
452 | /// use pin_project::pin_project; |
453 | /// |
454 | /// #[pin_project(project_replace = EnumProjOwn)] |
455 | /// enum Enum<T, U> { |
456 | /// A { |
457 | /// #[pin] |
458 | /// pinned_field: T, |
459 | /// unpinned_field: U, |
460 | /// }, |
461 | /// B, |
462 | /// } |
463 | /// |
464 | /// let mut x = Box::pin(Enum::A { pinned_field: 42, unpinned_field: "hello" }); |
465 | /// |
466 | /// match x.as_mut().project_replace(Enum::B) { |
467 | /// EnumProjOwn::A { unpinned_field, .. } => assert_eq!(unpinned_field, "hello" ), |
468 | /// EnumProjOwn::B => unreachable!(), |
469 | /// } |
470 | /// ``` |
471 | /// |
472 | /// [`PhantomData`]: core::marker::PhantomData |
473 | /// [`PhantomPinned`]: core::marker::PhantomPinned |
474 | /// [`Pin::as_mut`]: core::pin::Pin::as_mut |
475 | /// [`Pin::set`]: core::pin::Pin::set |
476 | /// [`Pin`]: core::pin::Pin |
477 | /// [`UnsafeUnpin`]: https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html |
478 | /// [drop-guarantee]: core::pin#drop-guarantee |
479 | /// [pin-projection]: core::pin#projections-and-structural-pinning |
480 | /// [pinned-drop]: macro@pin_project#pinned_drop |
481 | /// [repr-packed]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked |
482 | /// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html |
483 | /// [unsafe-unpin]: macro@pin_project#unsafeunpin |
484 | #[proc_macro_attribute ] |
485 | pub fn pin_project (args: TokenStream, input: TokenStream) -> TokenStream { |
486 | pin_project::attribute(&args.into(), input:input.into()).into() |
487 | } |
488 | |
489 | /// An attribute used for custom implementations of [`Drop`]. |
490 | /// |
491 | /// This attribute is used in conjunction with the `PinnedDrop` argument to |
492 | /// the [`#[pin_project]`][macro@pin_project] attribute. |
493 | /// |
494 | /// The impl block annotated with this attribute acts just like a normal |
495 | /// [`Drop`] impl, except for the following two: |
496 | /// |
497 | /// - `drop` method takes [`Pin`]`<&mut Self>` |
498 | /// - Name of the trait is `PinnedDrop`. |
499 | /// |
500 | /// ``` |
501 | /// # use std::pin::Pin; |
502 | /// pub trait PinnedDrop { |
503 | /// fn drop(self: Pin<&mut Self>); |
504 | /// } |
505 | /// ``` |
506 | /// |
507 | /// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you |
508 | /// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`] |
509 | /// function just like dropping a type that directly implements [`Drop`]. |
510 | /// |
511 | /// In particular, it will never be called more than once, just like |
512 | /// [`Drop::drop`]. |
513 | /// |
514 | /// # Examples |
515 | /// |
516 | /// ``` |
517 | /// use std::pin::Pin; |
518 | /// |
519 | /// use pin_project::{pin_project, pinned_drop}; |
520 | /// |
521 | /// #[pin_project(PinnedDrop)] |
522 | /// struct PrintOnDrop { |
523 | /// #[pin] |
524 | /// field: u8, |
525 | /// } |
526 | /// |
527 | /// #[pinned_drop] |
528 | /// impl PinnedDrop for PrintOnDrop { |
529 | /// fn drop(self: Pin<&mut Self>) { |
530 | /// println!("Dropping: {}" , self.field); |
531 | /// } |
532 | /// } |
533 | /// |
534 | /// fn main() { |
535 | /// let _x = PrintOnDrop { field: 50 }; |
536 | /// } |
537 | /// ``` |
538 | /// |
539 | /// See also ["pinned-drop" section of `#[pin_project]` attribute][pinned-drop]. |
540 | /// |
541 | /// # Why `#[pinned_drop]` attribute is needed? |
542 | /// |
543 | /// Implementing `PinnedDrop::drop` is safe, but calling it is not safe. |
544 | /// This is because destructors can be called multiple times in safe code and |
545 | /// [double dropping is unsound][rust-lang/rust#62360]. |
546 | /// |
547 | /// Ideally, it would be desirable to be able to forbid manual calls in |
548 | /// the same way as [`Drop::drop`], but the library cannot do it. So, by using |
549 | /// macros and replacing them with private traits like the following, |
550 | /// this crate prevent users from calling `PinnedDrop::drop` in safe code. |
551 | /// |
552 | /// ``` |
553 | /// # use std::pin::Pin; |
554 | /// pub trait PinnedDrop { |
555 | /// unsafe fn drop(self: Pin<&mut Self>); |
556 | /// } |
557 | /// ``` |
558 | /// |
559 | /// This allows implementing [`Drop`] safely using `#[pinned_drop]`. |
560 | /// Also by using the [`drop`] function just like dropping a type that directly |
561 | /// implements [`Drop`], can drop safely a type that implements `PinnedDrop`. |
562 | /// |
563 | /// [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360 |
564 | /// [`Pin`]: core::pin::Pin |
565 | /// [pinned-drop]: macro@pin_project#pinned_drop |
566 | #[proc_macro_attribute ] |
567 | pub fn pinned_drop (args: TokenStream, input: TokenStream) -> TokenStream { |
568 | let input: ItemImpl = syn::parse_macro_input!(input); |
569 | pinned_drop::attribute(&args.into(), input).into() |
570 | } |
571 | |
572 | // Not public API. |
573 | #[doc (hidden)] |
574 | #[proc_macro_derive (__PinProjectInternalDerive, attributes(pin))] |
575 | pub fn __pin_project_internal_derive(input: TokenStream) -> TokenStream { |
576 | pin_project::derive(input:input.into()).into() |
577 | } |
578 | |