|
16 | 16 | //!
|
17 | 17 | //! We will look at the following example:
|
18 | 18 | //!
|
19 |
| -//! ```rust |
| 19 | +//! ```rust,ignore |
20 | 20 | //! # use kernel::init::*;
|
| 21 | +//! # use core::pin::Pin; |
21 | 22 | //! #[pin_data]
|
22 | 23 | //! #[repr(C)]
|
23 | 24 | //! struct Bar<T> {
|
|
71 | 72 | //!
|
72 | 73 | //! Here is the definition of `Bar` from our example:
|
73 | 74 | //!
|
74 |
| -//! ```rust |
| 75 | +//! ```rust,ignore |
75 | 76 | //! # use kernel::init::*;
|
76 | 77 | //! #[pin_data]
|
77 | 78 | //! #[repr(C)]
|
78 | 79 | //! struct Bar<T> {
|
| 80 | +//! #[pin] |
79 | 81 | //! t: T,
|
80 | 82 | //! pub x: usize,
|
81 | 83 | //! }
|
82 | 84 | //! ```
|
83 | 85 | //!
|
84 | 86 | //! This expands to the following code:
|
85 | 87 | //!
|
86 |
| -//! ```rust |
| 88 | +//! ```rust,ignore |
87 | 89 | //! // Firstly the normal definition of the struct, attributes are preserved:
|
88 | 90 | //! #[repr(C)]
|
89 | 91 | //! struct Bar<T> {
|
|
116 | 118 | //! unsafe fn t<E>(
|
117 | 119 | //! self,
|
118 | 120 | //! 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>, |
120 | 123 | //! ) -> ::core::result::Result<(), E> {
|
121 |
| -//! unsafe { ::kernel::init::Init::__init(init, slot) } |
| 124 | +//! unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) } |
122 | 125 | //! }
|
123 | 126 | //! pub unsafe fn x<E>(
|
124 | 127 | //! self,
|
125 | 128 | //! slot: *mut usize,
|
| 129 | +//! // Since `x` is not `#[pin]`, this is `Init`. |
126 | 130 | //! init: impl ::kernel::init::Init<usize, E>,
|
127 | 131 | //! ) -> ::core::result::Result<(), E> {
|
128 | 132 | //! unsafe { ::kernel::init::Init::__init(init, slot) }
|
129 | 133 | //! }
|
130 | 134 | //! }
|
131 | 135 | //! // Implement the internal `HasPinData` trait that associates `Bar` with the pin-data struct
|
132 |
| -//! // that we constructed beforehand. |
| 136 | +//! // that we constructed above. |
133 | 137 | //! unsafe impl<T> ::kernel::init::__internal::HasPinData for Bar<T> {
|
134 | 138 | //! type PinData = __ThePinData<T>;
|
135 | 139 | //! unsafe fn __pin_data() -> Self::PinData {
|
|
160 | 164 | //! struct __Unpin<'__pin, T> {
|
161 | 165 | //! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
|
162 | 166 | //! __phantom: ::core::marker::PhantomData<fn(Bar<T>) -> Bar<T>>,
|
| 167 | +//! // Our only `#[pin]` field is `t`. |
| 168 | +//! t: T, |
163 | 169 | //! }
|
164 | 170 | //! #[doc(hidden)]
|
165 | 171 | //! impl<'__pin, T>
|
|
193 | 199 | //!
|
194 | 200 | //! Here is the impl on `Bar` defining the new function:
|
195 | 201 | //!
|
196 |
| -//! ```rust |
| 202 | +//! ```rust,ignore |
197 | 203 | //! impl<T> Bar<T> {
|
198 | 204 | //! fn new(t: T) -> impl PinInit<Self> {
|
199 | 205 | //! pin_init!(Self { t, x: 0 })
|
|
203 | 209 | //!
|
204 | 210 | //! This expands to the following code:
|
205 | 211 | //!
|
206 |
| -//! ```rust |
| 212 | +//! ```rust,ignore |
207 | 213 | //! impl<T> Bar<T> {
|
208 | 214 | //! fn new(t: T) -> impl PinInit<Self> {
|
209 | 215 | //! {
|
|
232 | 238 | //! // that will refer to this struct instead of the one defined above.
|
233 | 239 | //! struct __InitOk;
|
234 | 240 | //! // 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) }; |
236 | 242 | //! // 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). |
241 | 248 | //! 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 | +//! ) |
243 | 252 | //! };
|
244 | 253 | //! // Expansion of `x: 0,`:
|
245 | 254 | //! // Since this can be an arbitrary expression we cannot place it inside of
|
246 | 255 | //! // the `unsafe` block, so we bind it here.
|
247 | 256 | //! 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`. |
249 | 259 | //! 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 | +//! ) |
251 | 263 | //! };
|
252 | 264 | //!
|
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 |
254 | 266 | //! // initialized exactly once, since this is `if false` it will never get
|
255 | 267 | //! // executed, but still type-checked.
|
256 | 268 | //! // Additionally we abuse `slot` to automatically infer the correct type for
|
|
272 | 284 | //! };
|
273 | 285 | //! }
|
274 | 286 | //! // Since initialization has successfully completed, we can now forget the
|
275 |
| -//! // guards. |
| 287 | +//! // guards. This is not `mem::forget`, since we only have `&DropGuard`. |
276 | 288 | //! unsafe { ::kernel::init::__internal::DropGuard::forget(t) };
|
277 | 289 | //! unsafe { ::kernel::init::__internal::DropGuard::forget(x) };
|
278 | 290 | //! }
|
279 | 291 | //! // We leave the scope above and gain access to the previously shadowed
|
280 | 292 | //! // `__InitOk` that we need to return.
|
281 | 293 | //! Ok(__InitOk)
|
282 | 294 | //! });
|
283 |
| -//! // Change the return type of the closure. |
| 295 | +//! // Change the return type from `__InitOk` to `()`. |
284 | 296 | //! let init = move |slot| -> ::core::result::Result<(), ::core::convert::Infallible> {
|
285 | 297 | //! init(slot).map(|__InitOk| ())
|
286 | 298 | //! };
|
|
299 | 311 | //! Since we already took a look at `#[pin_data]` on `Bar`, this section will only explain the
|
300 | 312 | //! differences/new things in the expansion of the `Foo` definition:
|
301 | 313 | //!
|
302 |
| -//! ```rust |
| 314 | +//! ```rust,ignore |
303 | 315 | //! #[pin_data(PinnedDrop)]
|
304 | 316 | //! struct Foo {
|
305 | 317 | //! a: usize,
|
|
310 | 322 | //!
|
311 | 323 | //! This expands to the following code:
|
312 | 324 | //!
|
313 |
| -//! ```rust |
| 325 | +//! ```rust,ignore |
314 | 326 | //! struct Foo {
|
315 | 327 | //! a: usize,
|
316 | 328 | //! b: Bar<u32>,
|
|
330 | 342 | //! unsafe fn b<E>(
|
331 | 343 | //! self,
|
332 | 344 | //! 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. |
335 | 345 | //! init: impl ::kernel::init::PinInit<Bar<u32>, E>,
|
336 | 346 | //! ) -> ::core::result::Result<(), E> {
|
337 | 347 | //! unsafe { ::kernel::init::PinInit::__pinned_init(init, slot) }
|
|
359 | 369 | //! struct __Unpin<'__pin> {
|
360 | 370 | //! __phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
|
361 | 371 | //! __phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
|
362 |
| -//! // Since this field is `#[pin]`, it is listed here. |
363 | 372 | //! b: Bar<u32>,
|
364 | 373 | //! }
|
365 | 374 | //! #[doc(hidden)]
|
366 | 375 | //! impl<'__pin> ::core::marker::Unpin for Foo where __Unpin<'__pin>: ::core::marker::Unpin {}
|
367 | 376 | //! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
|
368 | 377 | //! // 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`. |
370 | 379 | //! impl ::core::ops::Drop for Foo {
|
371 | 380 | //! fn drop(&mut self) {
|
372 | 381 | //! // Since we are getting dropped, no one else has a reference to `self` and thus we
|
|
388 | 397 | //!
|
389 | 398 | //! Here is the `PinnedDrop` impl for `Foo`:
|
390 | 399 | //!
|
391 |
| -//! ```rust |
| 400 | +//! ```rust,ignore |
392 | 401 | //! #[pinned_drop]
|
393 | 402 | //! impl PinnedDrop for Foo {
|
394 | 403 | //! fn drop(self: Pin<&mut Self>) {
|
|
399 | 408 | //!
|
400 | 409 | //! This expands to the following code:
|
401 | 410 | //!
|
402 |
| -//! ```rust |
| 411 | +//! ```rust,ignore |
403 | 412 | //! // `unsafe`, full path and the token parameter are added, everything else stays the same.
|
404 | 413 | //! unsafe impl ::kernel::init::PinnedDrop for Foo {
|
405 | 414 | //! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
|
|
410 | 419 | //!
|
411 | 420 | //! ## `pin_init!` on `Foo`
|
412 | 421 | //!
|
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`: |
415 | 424 | //!
|
416 |
| -//! ```rust |
| 425 | +//! ```rust,ignore |
417 | 426 | //! let a = 42;
|
418 | 427 | //! let initializer = pin_init!(Foo {
|
419 | 428 | //! a,
|
|
423 | 432 | //!
|
424 | 433 | //! This expands to the following code:
|
425 | 434 | //!
|
426 |
| -//! ```rust |
| 435 | +//! ```rust,ignore |
427 | 436 | //! let a = 42;
|
428 | 437 | //! let initializer = {
|
429 | 438 | //! struct __InitOk;
|
|
438 | 447 | //! >(data, move |slot| {
|
439 | 448 | //! {
|
440 | 449 | //! 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 | +//! }; |
443 | 454 | //! 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 | +//! }; |
448 | 459 | //!
|
449 | 460 | //! #[allow(unreachable_code, clippy::diverging_sub_expression)]
|
450 | 461 | //! if false {
|
|
0 commit comments