macros.rs (674b1c7aed6082e1ce329bb3bcb49e7eb9913e79) macros.rs (4af84c6a85c63bec24611e46bb3de2c0a6602a51)
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3//! This module provides the macros that actually implement the proc-macros `pin_data` and
4//! `pinned_drop`. It also contains `__init_internal` the implementation of the `{try_}{pin_}init!`
5//! macros.
6//!
7//! These macros should never be called directly, since they expect their input to be
8//! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in

--- 31 unchanged lines hidden (view full) ---

40//! a: usize,
41//! #[pin]
42//! b: Bar<u32>,
43//! }
44//!
45//! #[pinned_drop]
46//! impl PinnedDrop for Foo {
47//! fn drop(self: Pin<&mut Self>) {
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3//! This module provides the macros that actually implement the proc-macros `pin_data` and
4//! `pinned_drop`. It also contains `__init_internal` the implementation of the `{try_}{pin_}init!`
5//! macros.
6//!
7//! These macros should never be called directly, since they expect their input to be
8//! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in

--- 31 unchanged lines hidden (view full) ---

40//! a: usize,
41//! #[pin]
42//! b: Bar<u32>,
43//! }
44//!
45//! #[pinned_drop]
46//! impl PinnedDrop for Foo {
47//! fn drop(self: Pin<&mut Self>) {
48//! println!("{self:p} is getting dropped.");
48//! pr_info!("{self:p} is getting dropped.");
49//! }
50//! }
51//!
52//! let a = 42;
53//! let initializer = pin_init!(Foo {
54//! a,
55//! b <- Bar::new(36),
56//! });

--- 108 unchanged lines hidden (view full) ---

165//! #[allow(dead_code)]
166//! struct __Unpin<'__pin, T> {
167//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
168//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
169//! // Our only `#[pin]` field is `t`.
170//! t: T,
171//! }
172//! #[doc(hidden)]
49//! }
50//! }
51//!
52//! let a = 42;
53//! let initializer = pin_init!(Foo {
54//! a,
55//! b <- Bar::new(36),
56//! });

--- 108 unchanged lines hidden (view full) ---

165//! #[allow(dead_code)]
166//! struct __Unpin<'__pin, T> {
167//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
168//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
169//! // Our only `#[pin]` field is `t`.
170//! t: T,
171//! }
172//! #[doc(hidden)]
173//! impl<'__pin, T>
174//! ::core::marker::Unpin for Bar<T> where __Unpin<'__pin, T>: ::core::marker::Unpin {}
173//! impl<'__pin, T> ::core::marker::Unpin for Bar<T>
174//! where
175//! __Unpin<'__pin, T>: ::core::marker::Unpin,
176//! {}
175//! // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users
176//! // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to
177//! // UB with only safe code, so we disallow this by giving a trait implementation error using
178//! // a direct impl and a blanket implementation.
179//! trait MustNotImplDrop {}
180//! // Normally `Drop` bounds do not have the correct semantics, but for this purpose they do
181//! // (normally people want to know if a type has any kind of drop glue at all, here we want
182//! // to know if it has any kind of custom drop glue, which is exactly what this bound does).
183//! #[allow(drop_bounds)]
184//! impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
185//! impl<T> MustNotImplDrop for Bar<T> {}
186//! // Here comes a convenience check, if one implemented `PinnedDrop`, but forgot to add it to
187//! // `#[pin_data]`, then this will error with the same mechanic as above, this is not needed
188//! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.
189//! #[allow(non_camel_case_types)]
190//! trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
177//! // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users
178//! // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to
179//! // UB with only safe code, so we disallow this by giving a trait implementation error using
180//! // a direct impl and a blanket implementation.
181//! trait MustNotImplDrop {}
182//! // Normally `Drop` bounds do not have the correct semantics, but for this purpose they do
183//! // (normally people want to know if a type has any kind of drop glue at all, here we want
184//! // to know if it has any kind of custom drop glue, which is exactly what this bound does).
185//! #[allow(drop_bounds)]
186//! impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
187//! impl<T> MustNotImplDrop for Bar<T> {}
188//! // Here comes a convenience check, if one implemented `PinnedDrop`, but forgot to add it to
189//! // `#[pin_data]`, then this will error with the same mechanic as above, this is not needed
190//! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.
191//! #[allow(non_camel_case_types)]
192//! trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {}
191//! impl<T: ::kernel::init::PinnedDrop>
192//! UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
193//! impl<
194//! T: ::kernel::init::PinnedDrop,
195//! > UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {}
193//! impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}
194//! };
195//! ```
196//!
197//! ## `pin_init!` in `impl Bar`
198//!
199//! This macro creates an pin-initializer for the given struct. It requires that the struct is
200//! annotated by `#[pin_data]`.

--- 13 unchanged lines hidden (view full) ---

214//! ```rust,ignore
215//! impl<T> Bar<T> {
216//! fn new(t: T) -> impl PinInit<Self> {
217//! {
218//! // We do not want to allow arbitrary returns, so we declare this type as the `Ok`
219//! // return type and shadow it later when we insert the arbitrary user code. That way
220//! // there will be no possibility of returning without `unsafe`.
221//! struct __InitOk;
196//! impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}
197//! };
198//! ```
199//!
200//! ## `pin_init!` in `impl Bar`
201//!
202//! This macro creates an pin-initializer for the given struct. It requires that the struct is
203//! annotated by `#[pin_data]`.

--- 13 unchanged lines hidden (view full) ---

217//! ```rust,ignore
218//! impl<T> Bar<T> {
219//! fn new(t: T) -> impl PinInit<Self> {
220//! {
221//! // We do not want to allow arbitrary returns, so we declare this type as the `Ok`
222//! // return type and shadow it later when we insert the arbitrary user code. That way
223//! // there will be no possibility of returning without `unsafe`.
224//! struct __InitOk;
222//! // Get the pin-data type from the initialized type.
225//! // Get the data about fields from the supplied type.
223//! // - the function is unsafe, hence the unsafe block
224//! // - we `use` the `HasPinData` trait in the block, it is only available in that
225//! // scope.
226//! let data = unsafe {
227//! use ::kernel::init::__internal::HasPinData;
228//! Self::__pin_data()
229//! };
226//! // - the function is unsafe, hence the unsafe block
227//! // - we `use` the `HasPinData` trait in the block, it is only available in that
228//! // scope.
229//! let data = unsafe {
230//! use ::kernel::init::__internal::HasPinData;
231//! Self::__pin_data()
232//! };
230//! // Use `data` to help with type inference, the closure supplied will have the type
231//! // `FnOnce(*mut Self) -> Result<__InitOk, Infallible>`.
233//! // Ensure that `data` really is of type `PinData` and help with type inference:
232//! let init = ::kernel::init::__internal::PinData::make_closure::<
233//! _,
234//! __InitOk,
235//! ::core::convert::Infallible,
236//! >(data, move |slot| {
237//! {
238//! // Shadow the structure so it cannot be used to return early. If a user
234//! let init = ::kernel::init::__internal::PinData::make_closure::<
235//! _,
236//! __InitOk,
237//! ::core::convert::Infallible,
238//! >(data, move |slot| {
239//! {
240//! // Shadow the structure so it cannot be used to return early. If a user
239//! // tries to write `return Ok(__InitOk)`, then they get a type error, since
240//! // that will refer to this struct instead of the one defined above.
241//! // tries to write `return Ok(__InitOk)`, then they get a type error,
242//! // since that will refer to this struct instead of the one defined
243//! // above.
241//! struct __InitOk;
242//! // This is the expansion of `t,`, which is syntactic sugar for `t: t,`.
244//! struct __InitOk;
245//! // This is the expansion of `t,`, which is syntactic sugar for `t: t,`.
243//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).t), t) };
244//! // Since initialization could fail later (not in this case, since the error
245//! // type is `Infallible`) we will need to drop this field if there is an
246//! // error later. This `DropGuard` will drop the field when it gets dropped
247//! // and has not yet been forgotten. We make a reference to it, so users
248//! // cannot `mem::forget` it from the initializer, since the name is the same
249//! // as the field (including hygiene).
250//! let t = &unsafe {
251//! ::kernel::init::__internal::DropGuard::new(
252//! ::core::addr_of_mut!((*slot).t),
253//! )
246//! {
247//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).t), t) };
248//! }
249//! // Since initialization could fail later (not in this case, since the
250//! // error type is `Infallible`) we will need to drop this field if there
251//! // is an error later. This `DropGuard` will drop the field when it gets
252//! // dropped and has not yet been forgotten.
253//! let t = unsafe {
254//! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).t))
254//! };
255//! // Expansion of `x: 0,`:
255//! };
256//! // Expansion of `x: 0,`:
256//! // Since this can be an arbitrary expression we cannot place it inside of
257//! // the `unsafe` block, so we bind it here.
258//! let x = 0;
259//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) };
257//! // Since this can be an arbitrary expression we cannot place it inside
258//! // of the `unsafe` block, so we bind it here.
259//! {
260//! let x = 0;
261//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) };
262//! }
260//! // We again create a `DropGuard`.
263//! // We again create a `DropGuard`.
261//! let x = &unsafe {
262//! ::kernel::init::__internal::DropGuard::new(
263//! ::core::addr_of_mut!((*slot).x),
264//! )
264//! let x = unsafe {
265//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).x))
265//! };
266//! };
266//!
267//! // Since initialization has successfully completed, we can now forget
268//! // the guards. This is not `mem::forget`, since we only have
269//! // `&DropGuard`.
270//! ::core::mem::forget(x);
271//! ::core::mem::forget(t);
267//! // Here we use the type checker to ensure that every field has been
268//! // initialized exactly once, since this is `if false` it will never get
269//! // executed, but still type-checked.
272//! // Here we use the type checker to ensure that every field has been
273//! // initialized exactly once, since this is `if false` it will never get
274//! // executed, but still type-checked.
270//! // Additionally we abuse `slot` to automatically infer the correct type for
271//! // the struct. This is also another check that every field is accessible
272//! // from this scope.
275//! // Additionally we abuse `slot` to automatically infer the correct type
276//! // for the struct. This is also another check that every field is
277//! // accessible from this scope.
273//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
278//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
274//! if false {
279//! let _ = || {
275//! unsafe {
276//! ::core::ptr::write(
277//! slot,
278//! Self {
280//! unsafe {
281//! ::core::ptr::write(
282//! slot,
283//! Self {
279//! // We only care about typecheck finding every field here,
280//! // the expression does not matter, just conjure one using
281//! // `panic!()`:
284//! // We only care about typecheck finding every field
285//! // here, the expression does not matter, just conjure
286//! // one using `panic!()`:
282//! t: ::core::panic!(),
283//! x: ::core::panic!(),
284//! },
285//! );
286//! };
287//! t: ::core::panic!(),
288//! x: ::core::panic!(),
289//! },
290//! );
291//! };
287//! }
288//! // Since initialization has successfully completed, we can now forget the
289//! // guards. This is not `mem::forget`, since we only have `&DropGuard`.
290//! unsafe { ::kernel::init::__internal::DropGuard::forget(t) };
291//! unsafe { ::kernel::init::__internal::DropGuard::forget(x) };
292//! };
292//! }
293//! // We leave the scope above and gain access to the previously shadowed
294//! // `__InitOk` that we need to return.
295//! Ok(__InitOk)
296//! });
297//! // Change the return type from `__InitOk` to `()`.
293//! }
294//! // We leave the scope above and gain access to the previously shadowed
295//! // `__InitOk` that we need to return.
296//! Ok(__InitOk)
297//! });
298//! // Change the return type from `__InitOk` to `()`.
298//! let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
299//! let init = move |
300//! slot,
301//! | -> ::core::result::Result<(), ::core::convert::Infallible> {
299//! init(slot).map(|__InitOk| ())
300//! };
301//! // Construct the initializer.
302//! let init = unsafe {
302//! init(slot).map(|__InitOk| ())
303//! };
304//! // Construct the initializer.
305//! let init = unsafe {
303//! ::kernel::init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)
306//! ::kernel::init::pin_init_from_closure::<
307//! _,
308//! ::core::convert::Infallible,
309//! >(init)
304//! };
305//! init
306//! }
307//! }
308//! }
309//! ```
310//!
311//! ## `#[pin_data]` on `Foo`

--- 57 unchanged lines hidden (view full) ---

369//! }
370//! #[allow(dead_code)]
371//! struct __Unpin<'__pin> {
372//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
373//! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
374//! b: Bar<u32>,
375//! }
376//! #[doc(hidden)]
310//! };
311//! init
312//! }
313//! }
314//! }
315//! ```
316//!
317//! ## `#[pin_data]` on `Foo`

--- 57 unchanged lines hidden (view full) ---

375//! }
376//! #[allow(dead_code)]
377//! struct __Unpin<'__pin> {
378//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
379//! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
380//! b: Bar<u32>,
381//! }
382//! #[doc(hidden)]
377//! impl<'__pin> ::core::marker::Unpin for Foo where __Unpin<'__pin>: ::core::marker::Unpin {}
383//! impl<'__pin> ::core::marker::Unpin for Foo
384//! where
385//! __Unpin<'__pin>: ::core::marker::Unpin,
386//! {}
378//! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
379//! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
380//! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
381//! impl ::core::ops::Drop for Foo {
382//! fn drop(&mut self) {
383//! // Since we are getting dropped, no one else has a reference to `self` and thus we
384//! // can assume that we never move.
385//! let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };

--- 12 unchanged lines hidden (view full) ---

398//! extra parameter that should not be used at all. The macro hides that parameter.
399//!
400//! Here is the `PinnedDrop` impl for `Foo`:
401//!
402//! ```rust,ignore
403//! #[pinned_drop]
404//! impl PinnedDrop for Foo {
405//! fn drop(self: Pin<&mut Self>) {
387//! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
388//! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
389//! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
390//! impl ::core::ops::Drop for Foo {
391//! fn drop(&mut self) {
392//! // Since we are getting dropped, no one else has a reference to `self` and thus we
393//! // can assume that we never move.
394//! let pinned = unsafe { ::core::pin::Pin::new_unchecked(self) };

--- 12 unchanged lines hidden (view full) ---

407//! extra parameter that should not be used at all. The macro hides that parameter.
408//!
409//! Here is the `PinnedDrop` impl for `Foo`:
410//!
411//! ```rust,ignore
412//! #[pinned_drop]
413//! impl PinnedDrop for Foo {
414//! fn drop(self: Pin<&mut Self>) {
406//! println!("{self:p} is getting dropped.");
415//! pr_info!("{self:p} is getting dropped.");
407//! }
408//! }
409//! ```
410//!
411//! This expands to the following code:
412//!
413//! ```rust,ignore
414//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
415//! unsafe impl ::kernel::init::PinnedDrop for Foo {
416//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
416//! }
417//! }
418//! ```
419//!
420//! This expands to the following code:
421//!
422//! ```rust,ignore
423//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
424//! unsafe impl ::kernel::init::PinnedDrop for Foo {
425//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
417//! println!("{self:p} is getting dropped.");
426//! pr_info!("{self:p} is getting dropped.");
418//! }
419//! }
420//! ```
421//!
422//! ## `pin_init!` on `Foo`
423//!
424//! Since we already took a look at `pin_init!` on `Bar`, this section will only show the expansion
425//! of `pin_init!` on `Foo`:

--- 18 unchanged lines hidden (view full) ---

444//! };
445//! let init = ::kernel::init::__internal::PinData::make_closure::<
446//! _,
447//! __InitOk,
448//! ::core::convert::Infallible,
449//! >(data, move |slot| {
450//! {
451//! struct __InitOk;
427//! }
428//! }
429//! ```
430//!
431//! ## `pin_init!` on `Foo`
432//!
433//! Since we already took a look at `pin_init!` on `Bar`, this section will only show the expansion
434//! of `pin_init!` on `Foo`:

--- 18 unchanged lines hidden (view full) ---

453//! };
454//! let init = ::kernel::init::__internal::PinData::make_closure::<
455//! _,
456//! __InitOk,
457//! ::core::convert::Infallible,
458//! >(data, move |slot| {
459//! {
460//! struct __InitOk;
452//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) };
453//! let a = &unsafe {
461//! {
462//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) };
463//! }
464//! let a = unsafe {
454//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
455//! };
465//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
466//! };
456//! let b = Bar::new(36);
467//! let init = Bar::new(36);
457//! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
468//! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
458//! let b = &unsafe {
469//! let b = unsafe {
459//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
460//! };
470//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
471//! };
461//!
472//! ::core::mem::forget(b);
473//! ::core::mem::forget(a);
462//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
474//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
463//! if false {
475//! let _ = || {
464//! unsafe {
465//! ::core::ptr::write(
466//! slot,
467//! Foo {
468//! a: ::core::panic!(),
469//! b: ::core::panic!(),
470//! },
471//! );
472//! };
476//! unsafe {
477//! ::core::ptr::write(
478//! slot,
479//! Foo {
480//! a: ::core::panic!(),
481//! b: ::core::panic!(),
482//! },
483//! );
484//! };
473//! }
474//! unsafe { ::kernel::init::__internal::DropGuard::forget(a) };
475//! unsafe { ::kernel::init::__internal::DropGuard::forget(b) };
485//! };
476//! }
477//! Ok(__InitOk)
478//! });
486//! }
487//! Ok(__InitOk)
488//! });
479//! let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
489//! let init = move |
490//! slot,
491//! | -> ::core::result::Result<(), ::core::convert::Infallible> {
480//! init(slot).map(|__InitOk| ())
481//! };
482//! let init = unsafe {
483//! ::kernel::init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)
484//! };
485//! init
486//! };
487//! ```

--- 884 unchanged lines hidden ---
492//! init(slot).map(|__InitOk| ())
493//! };
494//! let init = unsafe {
495//! ::kernel::init::pin_init_from_closure::<_, ::core::convert::Infallible>(init)
496//! };
497//! init
498//! };
499//! ```

--- 884 unchanged lines hidden ---