|
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