Skip to content

Commit 309786c

Browse files
BennoLossinojeda
authored andcommitted
rust: init: update macro expansion example in docs
Also improve the explaining comments. Signed-off-by: Benno Lossin <[email protected]> Reviewed-by: Gary Guo <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 52b7bb4 commit 309786c

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

rust/kernel/init/macros.rs

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
//!
1717
//! We will look at the following example:
1818
//!
19-
//! ```rust
19+
//! ```rust,ignore
2020
//! # use kernel::init::*;
21+
//! # use core::pin::Pin;
2122
//! #[pin_data]
2223
//! #[repr(C)]
2324
//! struct Bar<T> {
@@ -71,19 +72,20 @@
7172
//!
7273
//! Here is the definition of `Bar` from our example:
7374
//!
74-
//! ```rust
75+
//! ```rust,ignore
7576
//! # use kernel::init::*;
7677
//! #[pin_data]
7778
//! #[repr(C)]
7879
//! struct Bar<T> {
80+
//! #[pin]
7981
//! t: T,
8082
//! pub x: usize,
8183
//! }
8284
//! ```
8385
//!
8486
//! This expands to the following code:
8587
//!
86-
//! ```rust
88+
//! ```rust,ignore
8789
//! // Firstly the normal definition of the struct, attributes are preserved:
8890
//! #[repr(C)]
8991
//! struct Bar<T> {
@@ -116,20 +118,22 @@
116118
//! unsafe fn t<E>(
117119
//! self,
118120
//! slot: *mut T,
119-
//! init: impl ::kernel::init::Init<T, E>,
121+
//! // Since `t` is `#[pin]`, this is `PinInit`.
122+
//! init: impl ::kernel::init::PinInit<T, E>,
120123
//! ) -> ::core::result::Result<(), E> {
121-
//! unsafe { ::kernel::init::Init::__init(init, slot) }
124+
//! unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
122125
//! }
123126
//! pub unsafe fn x<E>(
124127
//! self,
125128
//! slot: *mut usize,
129+
//! // Since `x` is not `#[pin]`, this is `Init`.
126130
//! init: impl ::kernel::init::Init<usize, E>,
127131
//! ) -> ::core::result::Result<(), E> {
128132
//! unsafe { ::kernel::init::Init::__init(init, slot) }
129133
//! }
130134
//! }
131135
//! // Implement the internal `HasPinData` trait that associates `Bar` with the pin-data struct
132-
//! // that we constructed beforehand.
136+
//! // that we constructed above.
133137
//! unsafe impl<T> ::kernel::init::__internal::HasPinData for Bar<T> {
134138
//! type PinData = __ThePinData<T>;
135139
//! unsafe fn __pin_data() -> Self::PinData {
@@ -160,6 +164,8 @@
160164
//! struct __Unpin<'__pin, T> {
161165
//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
162166
//! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
167+
//! // Our only `#[pin]` field is `t`.
168+
//! t: T,
163169
//! }
164170
//! #[doc(hidden)]
165171
//! impl<'__pin, T>
@@ -193,7 +199,7 @@
193199
//!
194200
//! Here is the impl on `Bar` defining the new function:
195201
//!
196-
//! ```rust
202+
//! ```rust,ignore
197203
//! impl<T> Bar<T> {
198204
//! fn new(t: T) -> impl PinInit<Self> {
199205
//! pin_init!(Self { t, x: 0 })
@@ -203,7 +209,7 @@
203209
//!
204210
//! This expands to the following code:
205211
//!
206-
//! ```rust
212+
//! ```rust,ignore
207213
//! impl<T> Bar<T> {
208214
//! fn new(t: T) -> impl PinInit<Self> {
209215
//! {
@@ -232,25 +238,31 @@
232238
//! // that will refer to this struct instead of the one defined above.
233239
//! struct __InitOk;
234240
//! // This is the expansion of `t,`, which is syntactic sugar for `t: t,`.
235-
//! unsafe { ::core::ptr::write(&raw mut (*slot).t, t) };
241+
//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).t), t) };
236242
//! // Since initialization could fail later (not in this case, since the error
237-
//! // type is `Infallible`) we will need to drop this field if it fails. This
238-
//! // `DropGuard` will drop the field when it gets dropped and has not yet
239-
//! // been forgotten. We make a reference to it, so users cannot `mem::forget`
240-
//! // it from the initializer, since the name is the same as the field.
243+
//! // type is `Infallible`) we will need to drop this field if there is an
244+
//! // error later. This `DropGuard` will drop the field when it gets dropped
245+
//! // and has not yet been forgotten. We make a reference to it, so users
246+
//! // cannot `mem::forget` it from the initializer, since the name is the same
247+
//! // as the field (including hygiene).
241248
//! let t = &unsafe {
242-
//! ::kernel::init::__internal::DropGuard::new(&raw mut (*slot).t)
249+
//! ::kernel::init::__internal::DropGuard::new(
250+
//! ::core::addr_of_mut!((*slot).t),
251+
//! )
243252
//! };
244253
//! // Expansion of `x: 0,`:
245254
//! // Since this can be an arbitrary expression we cannot place it inside of
246255
//! // the `unsafe` block, so we bind it here.
247256
//! let x = 0;
248-
//! unsafe { ::core::ptr::write(&raw mut (*slot).x, x) };
257+
//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) };
258+
//! // We again create a `DropGuard`.
249259
//! let x = &unsafe {
250-
//! ::kernel::init::__internal::DropGuard::new(&raw mut (*slot).x)
260+
//! ::kernel::init::__internal::DropGuard::new(
261+
//! ::core::addr_of_mut!((*slot).x),
262+
//! )
251263
//! };
252264
//!
253-
//! // Here we use the type checker to ensuer that every field has been
265+
//! // Here we use the type checker to ensure that every field has been
254266
//! // initialized exactly once, since this is `if false` it will never get
255267
//! // executed, but still type-checked.
256268
//! // Additionally we abuse `slot` to automatically infer the correct type for
@@ -272,15 +284,15 @@
272284
//! };
273285
//! }
274286
//! // Since initialization has successfully completed, we can now forget the
275-
//! // guards.
287+
//! // guards. This is not `mem::forget`, since we only have `&DropGuard`.
276288
//! unsafe { ::kernel::init::__internal::DropGuard::forget(t) };
277289
//! unsafe { ::kernel::init::__internal::DropGuard::forget(x) };
278290
//! }
279291
//! // We leave the scope above and gain access to the previously shadowed
280292
//! // `__InitOk` that we need to return.
281293
//! Ok(__InitOk)
282294
//! });
283-
//! // Change the return type of the closure.
295+
//! // Change the return type from `__InitOk` to `()`.
284296
//! let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
285297
//! init(slot).map(|__InitOk| ())
286298
//! };
@@ -299,7 +311,7 @@
299311
//! Since we already took a look at `#[pin_data]` on `Bar`, this section will only explain the
300312
//! differences/new things in the expansion of the `Foo` definition:
301313
//!
302-
//! ```rust
314+
//! ```rust,ignore
303315
//! #[pin_data(PinnedDrop)]
304316
//! struct Foo {
305317
//! a: usize,
@@ -310,7 +322,7 @@
310322
//!
311323
//! This expands to the following code:
312324
//!
313-
//! ```rust
325+
//! ```rust,ignore
314326
//! struct Foo {
315327
//! a: usize,
316328
//! b: Bar<u32>,
@@ -330,8 +342,6 @@
330342
//! unsafe fn b<E>(
331343
//! self,
332344
//! slot: *mut Bar<u32>,
333-
//! // Note that this is `PinInit` instead of `Init`, this is because `b` is
334-
//! // structurally pinned, as marked by the `#[pin]` attribute.
335345
//! init: impl ::kernel::init::PinInit<Bar<u32>, E>,
336346
//! ) -> ::core::result::Result<(), E> {
337347
//! unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
@@ -359,14 +369,13 @@
359369
//! struct __Unpin<'__pin> {
360370
//! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
361371
//! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
362-
//! // Since this field is `#[pin]`, it is listed here.
363372
//! b: Bar<u32>,
364373
//! }
365374
//! #[doc(hidden)]
366375
//! impl<'__pin> ::core::marker::Unpin for Foo where __Unpin<'__pin>: ::core::marker::Unpin {}
367376
//! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
368377
//! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
369-
//! // before, instead we implement it here and delegate to `PinnedDrop`.
378+
//! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
370379
//! impl ::core::ops::Drop for Foo {
371380
//! fn drop(&mut self) {
372381
//! // Since we are getting dropped, no one else has a reference to `self` and thus we
@@ -388,7 +397,7 @@
388397
//!
389398
//! Here is the `PinnedDrop` impl for `Foo`:
390399
//!
391-
//! ```rust
400+
//! ```rust,ignore
392401
//! #[pinned_drop]
393402
//! impl PinnedDrop for Foo {
394403
//! fn drop(self: Pin<&mut Self>) {
@@ -399,7 +408,7 @@
399408
//!
400409
//! This expands to the following code:
401410
//!
402-
//! ```rust
411+
//! ```rust,ignore
403412
//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
404413
//! unsafe impl ::kernel::init::PinnedDrop for Foo {
405414
//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
@@ -410,10 +419,10 @@
410419
//!
411420
//! ## `pin_init!` on `Foo`
412421
//!
413-
//! Since we already took a look at `pin_init!` on `Bar`, this section will only explain the
414-
//! differences/new things in the expansion of `pin_init!` on `Foo`:
422+
//! Since we already took a look at `pin_init!` on `Bar`, this section will only show the expansion
423+
//! of `pin_init!` on `Foo`:
415424
//!
416-
//! ```rust
425+
//! ```rust,ignore
417426
//! let a = 42;
418427
//! let initializer = pin_init!(Foo {
419428
//! a,
@@ -423,7 +432,7 @@
423432
//!
424433
//! This expands to the following code:
425434
//!
426-
//! ```rust
435+
//! ```rust,ignore
427436
//! let a = 42;
428437
//! let initializer = {
429438
//! struct __InitOk;
@@ -438,13 +447,15 @@
438447
//! >(data, move |slot| {
439448
//! {
440449
//! struct __InitOk;
441-
//! unsafe { ::core::ptr::write(&raw mut (*slot).a, a) };
442-
//! let a = &unsafe { ::kernel::init::__internal::DropGuard::new(&raw mut (*slot).a) };
450+
//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) };
451+
//! let a = &unsafe {
452+
//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
453+
//! };
443454
//! let b = Bar::new(36);
444-
//! // Here we use `data` to access the correct field and require that `b` is of type
445-
//! // `PinInit<Bar<u32>, Infallible>`.
446-
//! unsafe { data.b(&raw mut (*slot).b, b)? };
447-
//! let b = &unsafe { ::kernel::init::__internal::DropGuard::new(&raw mut (*slot).b) };
455+
//! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
456+
//! let b = &unsafe {
457+
//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
458+
//! };
448459
//!
449460
//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
450461
//! if false {

0 commit comments

Comments
 (0)