// SPDX-License-Identifier: Apache-2.0 OR MIT
//! This module provides the macros that actually implement the proc-macros `pin_data` and
//! `pinned_drop`. It also contains `__init_internal` the implementation of the `{try_}{pin_}init!`
//! macros.
//!
//! These macros should never be called directly, since they expect their input to be
//! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in
//! safe code! Use the public facing macros instead.
//!
//! This architecture has been chosen because the kernel does not yet have access to `syn` which
//! would make matters a lot easier for implementing these as proc-macros.
//!
//! # Macro expansion example
//!
//! This section is intended for readers trying to understand the macros in this module and the
//! `pin_init!` macros from `init.rs`.
//!
//! We will look at the following example:
//!
//! ```rust,ignore
//! # use kernel::init::*;
//! # use core::pin::Pin;
//! #[pin_data]
//! #[repr(C)]
//! struct Bar<T> {
//! #[pin]
//! t: T,
//! pub x: usize,
//! }
//!
//! impl<T> Bar<T> {
//! fn new(t: T) -> impl PinInit<Self> {
//! pin_init!(Self { t, x: 0 })
//! }
//! }
//!
//! #[pin_data(PinnedDrop)]
//! struct Foo {
//! a: usize,
//! #[pin]
//! b: Bar<u32>,
//! }
//!
//! #[pinned_drop]
//! impl PinnedDrop for Foo {
//! fn drop(self: Pin<&mut Self>) {
//! pr_info!("{self:p} is getting dropped.");
//! }
//! }
//!
//! let a = 42;
//! let initializer = pin_init!(Foo {
//! a,
//! b <- Bar::new(36),
//! });
//! ```
//!
//! This example includes the most common and important features of the pin-init API.
//!
//! Below you can find individual section about the different macro invocations. Here are some
//! general things we need to take into account when designing macros:
//! - use global paths, similarly to file paths, these start with the separator: `::core::panic!()`
//! this ensures that the correct item is used, since users could define their own `mod core {}`
//! and then their own `panic!` inside to execute arbitrary code inside of our macro.
//! - macro `unsafe` hygiene: we need to ensure that we do not expand arbitrary, user-supplied
//! expressions inside of an `unsafe` block in the macro, because this would allow users to do
//! `unsafe` operations without an associated `unsafe` block.
//!
//! ## `#[pin_data]` on `Bar`
//!
//! This macro is used to specify which fields are structurally pinned and which fields are not. It
//! is placed on the struct definition and allows `#[pin]` to be placed on the fields.
//!
//! Here is the definition of `Bar` from our example:
//!
//! ```rust,ignore
//! # use kernel::init::*;
//! #[pin_data]
//! #[repr(C)]
//! struct Bar<T> {
//! #[pin]
//! t: T,
//! pub x: usize,
//! }
//! ```
//!
//! This expands to the following code:
//!
//! ```rust,ignore
//! // Firstly the normal definition of the struct, attributes are preserved:
//! #[repr(C)]
//! struct Bar<T> {
//! t: T,
//! pub x: usize,
//! }
//! // Then an anonymous constant is defined, this is because we do not want any code to access the
//! // types that we define inside:
//! const _: () = {
//! // We define the pin-data carrying struct, it is a ZST and needs to have the same generics,
//! // since we need to implement access functions for each field and thus need to know its
//! // type.
//! struct __ThePinData<T> {
//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
//! }
//! // We implement `Copy` for the pin-data struct, since all functions it defines will take
//! // `self` by value.
//! impl<T> ::core::clone::Clone for __ThePinData<T> {
//! fn clone(&self) -> Self {
//! *self
//! }
//! }
//! impl<T> ::core::marker::Copy for __ThePinData<T> {}
//! // For every field of `Bar`, the pin-data struct will define a function with the same name
//! // and accessor (`pub` or `pub(crate)` etc.). This function will take a pointer to the
//! // field (`slot`) and a `PinInit` or `Init` depending on the projection kind of the field
//! // (if pinning is structural for the field, then `PinInit` otherwise `Init`).
//! #[allow(dead_code)]
//! impl<T> __ThePinData<T> {
//! unsafe fn t<E>(
//! self,
//! slot: *mut T,
//! // Since `t` is `#[pin]`, this is `PinInit`.
//! init: impl ::kernel::init::PinInit<T, E>,
//! ) -> ::core::result::Result<(), E> {
//! unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
//! }
//! pub unsafe fn x<E>(
//! self,
//! slot: *mut usize,
//! // Since `x` is not `#[pin]`, this is `Init`.
//! init: impl ::kernel::init::Init<usize, E>,
//! ) -> ::core::result::Result<(), E> {
//! unsafe { ::kernel::init::Init::__init(init, slot) }
//! }
//! }
//! // Implement the internal `HasPinData` trait that associates `Bar` with the pin-data struct