Skip to content

core::ops::unsize: improve docs for DispatchFromDyn #91587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 5, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion library/core/src/ops/unsize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,38 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}

/// This is used for object safety, to check that a method's receiver type can be dispatched on.
/// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
/// arbitrary self types), to guarantee that a method's receiver type can be dispatched on.
///
/// Note: `DispatchFromDyn` was briefly named `CoerceSized` (and had a slightly different
/// interpretation).
///
/// Imagine we have a trait object `t` with type `&dyn Tr`, where `Tr` is some trait with a method
/// `m` defined as `fn m(&self);`. When calling `t.m()`, the receiver `t` is a wide pointer, but an
/// implementation of `m` will expect a narrow pointer as `&self` (a reference to the concrete
/// type). The compiler must generate an implicit conversion from the trait object/wide pointer to
/// the concrete reference/narrow pointer. Implementing `DispatchFromDyn` indicates that that
/// conversion is allowed and thus that the type implementing `DispatchFromDyn` is safe to use as
/// the self type in an object-safe method. (in the above example, the compiler will require
/// `DispatchFromDyn` is implemented for `&'a U`).
///
/// `DispatchFromDyn` does not specify the conversion from wide pointer to narrow pointer; the
/// conversion is hard-wired into the compiler. For the conversion to work, the following
/// properties must hold (i.e., it is only safe to implement `DispatchFromDyn` for types which have
/// these properties, these are also checked by the compiler):
///
/// * EITHER `Self` and `T` are either both references or both raw pointers; in either case, with
/// the same mutability.
/// * OR, all of the following hold
/// - `Self` and `T` must have the same type constructor, and only vary in a single type parameter
/// formal (the *coerced type*, e.g., `impl DispatchFromDyn<Rc<T>> for Rc<U>` is ok and the
/// single type parameter (instantiated with `T` or `U`) is the coerced type,
/// `impl DispatchFromDyn<Arc<T>> for Rc<U>` is not ok).
/// - The definition for `Self` must be a struct.
/// - The definition for `Self` must not be `#[repr(packed)]` or `#[repr(C)]`.
/// - Other than one-aligned, zero-sized fields, the definition for `Self` must have exactly one
/// field and that field's type must be the coerced type. Furthermore, `Self`'s field type must
/// implement `DispatchFromDyn<F>` where `F` is the type of `T`'s field type.
///
/// An example implementation of the trait:
///
Expand Down