|
45 | 45 | //! #[pinned_drop]
|
46 | 46 | //! impl PinnedDrop for Foo {
|
47 | 47 | //! fn drop(self: Pin<&mut Self>) {
|
48 |
| -//! println!("{self:p} is getting dropped."); |
| 48 | +//! pr_info!("{self:p} is getting dropped."); |
49 | 49 | //! }
|
50 | 50 | //! }
|
51 | 51 | //!
|
|
170 | 170 | //! t: T,
|
171 | 171 | //! }
|
172 | 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 | 177 | //! // Now we need to ensure that `Bar` does not implement `Drop`, since that would give users
|
176 | 178 | //! // access to `&mut self` inside of `drop` even if the struct was pinned. This could lead to
|
177 | 179 | //! // UB with only safe code, so we disallow this by giving a trait implementation error using
|
|
188 | 190 | //! // for safety, but a good sanity check, since no normal code calls `PinnedDrop::drop`.
|
189 | 191 | //! #[allow(non_camel_case_types)]
|
190 | 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 | 196 | //! impl<T> UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for Bar<T> {}
|
194 | 197 | //! };
|
195 | 198 | //! ```
|
|
219 | 222 | //! // return type and shadow it later when we insert the arbitrary user code. That way
|
220 | 223 | //! // there will be no possibility of returning without `unsafe`.
|
221 | 224 | //! struct __InitOk;
|
222 |
| -//! // Get the pin-data type from the initialized type. |
| 225 | +//! // Get the data about fields from the supplied type. |
223 | 226 | //! // - the function is unsafe, hence the unsafe block
|
224 | 227 | //! // - we `use` the `HasPinData` trait in the block, it is only available in that
|
225 | 228 | //! // scope.
|
226 | 229 | //! let data = unsafe {
|
227 | 230 | //! use ::kernel::init::__internal::HasPinData;
|
228 | 231 | //! Self::__pin_data()
|
229 | 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 | 234 | //! let init = ::kernel::init::__internal::PinData::make_closure::<
|
233 | 235 | //! _,
|
234 | 236 | //! __InitOk,
|
235 | 237 | //! ::core::convert::Infallible,
|
236 | 238 | //! >(data, move |slot| {
|
237 | 239 | //! {
|
238 | 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 | 244 | //! struct __InitOk;
|
242 | 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 | //! };
|
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 | 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 | 272 | //! // Here we use the type checker to ensure that every field has been
|
268 | 273 | //! // initialized exactly once, since this is `if false` it will never get
|
269 | 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 | 278 | //! #[allow(unreachable_code, clippy::diverging_sub_expression)]
|
274 |
| -//! if false { |
| 279 | +//! let _ = || { |
275 | 280 | //! unsafe {
|
276 | 281 | //! ::core::ptr::write(
|
277 | 282 | //! slot,
|
278 | 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 | 287 | //! t: ::core::panic!(),
|
283 | 288 | //! x: ::core::panic!(),
|
284 | 289 | //! },
|
285 | 290 | //! );
|
286 | 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 | //! }
|
293 | 294 | //! // We leave the scope above and gain access to the previously shadowed
|
294 | 295 | //! // `__InitOk` that we need to return.
|
295 | 296 | //! Ok(__InitOk)
|
296 | 297 | //! });
|
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 | 302 | //! init(slot).map(|__InitOk| ())
|
300 | 303 | //! };
|
301 | 304 | //! // Construct the initializer.
|
302 | 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 | 310 | //! };
|
305 | 311 | //! init
|
306 | 312 | //! }
|
|
374 | 380 | //! b: Bar<u32>,
|
375 | 381 | //! }
|
376 | 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 | 387 | //! // Since we specified `PinnedDrop` as the argument to `#[pin_data]`, we expect `Foo` to
|
379 | 388 | //! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` implementations like
|
380 | 389 | //! // before, instead we implement `Drop` here and delegate to `PinnedDrop`.
|
|
403 | 412 | //! #[pinned_drop]
|
404 | 413 | //! impl PinnedDrop for Foo {
|
405 | 414 | //! fn drop(self: Pin<&mut Self>) {
|
406 |
| -//! println!("{self:p} is getting dropped."); |
| 415 | +//! pr_info!("{self:p} is getting dropped."); |
407 | 416 | //! }
|
408 | 417 | //! }
|
409 | 418 | //! ```
|
|
414 | 423 | //! // `unsafe`, full path and the token parameter are added, everything else stays the same.
|
415 | 424 | //! unsafe impl ::kernel::init::PinnedDrop for Foo {
|
416 | 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 | 427 | //! }
|
419 | 428 | //! }
|
420 | 429 | //! ```
|
|
449 | 458 | //! >(data, move |slot| {
|
450 | 459 | //! {
|
451 | 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 | 465 | //! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a))
|
455 | 466 | //! };
|
456 |
| -//! let b = Bar::new(36); |
| 467 | +//! let init = Bar::new(36); |
457 | 468 | //! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? };
|
458 |
| -//! let b = &unsafe { |
| 469 | +//! let b = unsafe { |
459 | 470 | //! ::kernel::init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b))
|
460 | 471 | //! };
|
461 |
| -//! |
| 472 | +//! ::core::mem::forget(b); |
| 473 | +//! ::core::mem::forget(a); |
462 | 474 | //! #[allow(unreachable_code, clippy::diverging_sub_expression)]
|
463 |
| -//! if false { |
| 475 | +//! let _ = || { |
464 | 476 | //! unsafe {
|
465 | 477 | //! ::core::ptr::write(
|
466 | 478 | //! slot,
|
|
470 | 482 | //! },
|
471 | 483 | //! );
|
472 | 484 | //! };
|
473 |
| -//! } |
474 |
| -//! unsafe { ::kernel::init::__internal::DropGuard::forget(a) }; |
475 |
| -//! unsafe { ::kernel::init::__internal::DropGuard::forget(b) }; |
| 485 | +//! }; |
476 | 486 | //! }
|
477 | 487 | //! Ok(__InitOk)
|
478 | 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 | 492 | //! init(slot).map(|__InitOk| ())
|
481 | 493 | //! };
|
482 | 494 | //! let init = unsafe {
|
|
0 commit comments