about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-04 21:23:05 +0100
committerGitHub <noreply@github.com>2022-01-04 21:23:05 +0100
commitd49c692eeba97381570f0a0f3167b4c44c80bc0a (patch)
tree7092086977493ce0513adcb22730aac8204cc65b
parent2b681ac06b1a6b7ea39525e59363ffee0d1a68e5 (diff)
parentb3573c5e6383242828972874614f80bac7ce8726 (diff)
downloadrust-d49c692eeba97381570f0a0f3167b4c44c80bc0a.tar.gz
rust-d49c692eeba97381570f0a0f3167b4c44c80bc0a.zip
Rollup merge of #91587 - nrc:dispatchfromdyn-docs, r=yaahc
core::ops::unsize: improve docs for DispatchFromDyn

Docs-only PR, improves documentation for DispatchFromDyn.
-rw-r--r--library/core/src/ops/unsize.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
index 483362023b2..a920b9165c1 100644
--- a/library/core/src/ops/unsize.rs
+++ b/library/core/src/ops/unsize.rs
@@ -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:
 ///