Skip to content

Commit 71004ce

Browse files
y86-devojeda
authored andcommitted
rust: init: update expanded macro explanation
The previous patches changed the internals of the macros resulting in the example expanded code being outdated. This patch updates the example and only changes documentation. Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Signed-off-by: Benno Lossin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Alice Ryhl <[email protected]> Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 5bf7f50 commit 71004ce

File tree

1 file changed

+69
-57
lines changed

1 file changed

+69
-57
lines changed

rust/kernel/init/macros.rs

+69-57
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
//! #[pinned_drop]
4646
//! impl PinnedDrop for Foo {
4747
//! fn drop(self: Pin<&mut Self>) {
48-
//! println!("{self:p} is getting dropped.");
48+
//! pr_info!("{self:p} is getting dropped.");
4949
//! }
5050
//! }
5151
//!
@@ -170,8 +170,10 @@
170170
//! t: T,
171171
//! }
172172
//! #[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+
//! {}
175177
//! // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users
176178
//! // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to
177179
//! // UB with only safe code, so we disallow this by giving a trait implementation error using
@@ -188,8 +190,9 @@
188190
//! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.
189191
//! #[allow(non_camel_case_types)]
190192
//! 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 {}
193196
//! impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}
194197
//! };
195198
//! ```
@@ -219,88 +222,91 @@
219222
//! // return type and shadow it later when we insert the arbitrary user code. That way
220223
//! // there will be no possibility of returning without `unsafe`.
221224
//! struct __InitOk;
222-
//! // Get the pin-data type from the initialized type.
225+
//! // Get the data about fields from the supplied type.
223226
//! // - the function is unsafe, hence the unsafe block
224227
//! // - we `use` the `HasPinData` trait in the block, it is only available in that
225228
//! // scope.
226229
//! let data = unsafe {
227230
//! use ::kernel::init::__internal::HasPinData;
228231
//! Self::__pin_data()
229232
//! };
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:
232234
//! let init = ::kernel::init::__internal::PinData::make_closure::<
233235
//! _,
234236
//! __InitOk,
235237
//! ::core::convert::Infallible,
236238
//! >(data, move |slot| {
237239
//! {
238240
//! // 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.
241244
//! struct __InitOk;
242245
//! // 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))
254255
//! };
255256
//! // 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+
//! }
260263
//! // 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))
265266
//! };
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);
267272
//! // Here we use the type checker to ensure that every field has been
268273
//! // initialized exactly once, since this is `if false` it will never get
269274
//! // 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.
273278
//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
274-
//! if false {
279+
//! let _ = || {
275280
//! unsafe {
276281
//! ::core::ptr::write(
277282
//! slot,
278283
//! 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!()`:
282287
//! t: ::core::panic!(),
283288
//! x: ::core::panic!(),
284289
//! },
285290
//! );
286291
//! };
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+
//! };
292293
//! }
293294
//! // We leave the scope above and gain access to the previously shadowed
294295
//! // `__InitOk` that we need to return.
295296
//! Ok(__InitOk)
296297
//! });
297298
//! // 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> {
299302
//! init(slot).map(|__InitOk| ())
300303
//! };
301304
//! // Construct the initializer.
302305
//! 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)
304310
//! };
305311
//! init
306312
//! }
@@ -374,7 +380,10 @@
374380
//! b: Bar<u32>,
375381
//! }
376382
//! #[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+
//! {}
378387
//! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
379388
//! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
380389
//! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
@@ -403,7 +412,7 @@
403412
//! #[pinned_drop]
404413
//! impl PinnedDrop for Foo {
405414
//! fn drop(self: Pin<&mut Self>) {
406-
//! println!("{self:p} is getting dropped.");
415+
//! pr_info!("{self:p} is getting dropped.");
407416
//! }
408417
//! }
409418
//! ```
@@ -414,7 +423,7 @@
414423
//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
415424
//! unsafe impl ::kernel::init::PinnedDrop for Foo {
416425
//! 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.");
418427
//! }
419428
//! }
420429
//! ```
@@ -449,18 +458,21 @@
449458
//! >(data, move |slot| {
450459
//! {
451460
//! 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 {
454465
//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
455466
//! };
456-
//! let b = Bar::new(36);
467+
//! let init = Bar::new(36);
457468
//! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
458-
//! let b = &unsafe {
469+
//! let b = unsafe {
459470
//! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
460471
//! };
461-
//!
472+
//! ::core::mem::forget(b);
473+
//! ::core::mem::forget(a);
462474
//! #[allow(unreachable_code, clippy::diverging_sub_expression)]
463-
//! if false {
475+
//! let _ = || {
464476
//! unsafe {
465477
//! ::core::ptr::write(
466478
//! slot,
@@ -470,13 +482,13 @@
470482
//! },
471483
//! );
472484
//! };
473-
//! }
474-
//! unsafe { ::kernel::init::__internal::DropGuard::forget(a) };
475-
//! unsafe { ::kernel::init::__internal::DropGuard::forget(b) };
485+
//! };
476486
//! }
477487
//! Ok(__InitOk)
478488
//! });
479-
//! let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
489+
//! let init = move |
490+
//! slot,
491+
//! | -> ::core::result::Result<(), ::core::convert::Infallible> {
480492
//! init(slot).map(|__InitOk| ())
481493
//! };
482494
//! let init = unsafe {

0 commit comments

Comments
 (0)