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 --- |