| 1 | use crate::marker::Unsize; |
| 2 | |
| 3 | /// Trait that indicates that this is a pointer or a wrapper for one, |
| 4 | /// where unsizing can be performed on the pointee. |
| 5 | /// |
| 6 | /// See the [DST coercion RFC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce] |
| 7 | /// for more details. |
| 8 | /// |
| 9 | /// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>` |
| 10 | /// by converting from a thin pointer to a fat pointer. |
| 11 | /// |
| 12 | /// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>` |
| 13 | /// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists. |
| 14 | /// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata |
| 15 | /// field involving `T`. If the type of that field is `Bar<T>`, an implementation |
| 16 | /// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by |
| 17 | /// coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields |
| 18 | /// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer |
| 19 | /// field and coerce that. |
| 20 | /// |
| 21 | /// Generally, for smart pointers you will implement |
| 22 | /// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an |
| 23 | /// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T` |
| 24 | /// like `Cell<T>` and `RefCell<T>`, you |
| 25 | /// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`. |
| 26 | /// This will let coercions of types like `Cell<Box<T>>` work. |
| 27 | /// |
| 28 | /// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind |
| 29 | /// pointers. It is implemented automatically by the compiler. |
| 30 | /// |
| 31 | /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md |
| 32 | /// [unsize]: crate::marker::Unsize |
| 33 | /// [nomicon-coerce]: ../../nomicon/coercions.html |
| 34 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 35 | #[lang = "coerce_unsized" ] |
| 36 | pub trait CoerceUnsized<T: ?Sized> { |
| 37 | // Empty. |
| 38 | } |
| 39 | |
| 40 | // &mut T -> &mut U |
| 41 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 42 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} |
| 43 | // &mut T -> &U |
| 44 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 45 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} |
| 46 | // &mut T -> *mut U |
| 47 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 48 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} |
| 49 | // &mut T -> *const U |
| 50 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 51 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} |
| 52 | |
| 53 | // &T -> &U |
| 54 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 55 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
| 56 | // &T -> *const U |
| 57 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 58 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} |
| 59 | |
| 60 | // *mut T -> *mut U |
| 61 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 62 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
| 63 | // *mut T -> *const U |
| 64 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 65 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} |
| 66 | |
| 67 | // *const T -> *const U |
| 68 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
| 69 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} |
| 70 | |
| 71 | /// `DispatchFromDyn` is used in the implementation of dyn-compatibility[^1] checks (specifically |
| 72 | /// allowing arbitrary self types), to guarantee that a method's receiver type can be dispatched on. |
| 73 | /// |
| 74 | /// Note: `DispatchFromDyn` was briefly named `CoerceSized` (and had a slightly different |
| 75 | /// interpretation). |
| 76 | /// |
| 77 | /// Imagine we have a trait object `t` with type `&dyn Tr`, where `Tr` is some trait with a method |
| 78 | /// `m` defined as `fn m(&self);`. When calling `t.m()`, the receiver `t` is a wide pointer, but an |
| 79 | /// implementation of `m` will expect a narrow pointer as `&self` (a reference to the concrete |
| 80 | /// type). The compiler must generate an implicit conversion from the trait object/wide pointer to |
| 81 | /// the concrete reference/narrow pointer. Implementing `DispatchFromDyn` indicates that that |
| 82 | /// conversion is allowed and thus that the type implementing `DispatchFromDyn` is safe to use as |
| 83 | /// the self type in an dyn-compatible method. (in the above example, the compiler will require |
| 84 | /// `DispatchFromDyn` is implemented for `&'a U`). |
| 85 | /// |
| 86 | /// `DispatchFromDyn` does not specify the conversion from wide pointer to narrow pointer; the |
| 87 | /// conversion is hard-wired into the compiler. For the conversion to work, the following |
| 88 | /// properties must hold (i.e., it is only safe to implement `DispatchFromDyn` for types which have |
| 89 | /// these properties, these are also checked by the compiler): |
| 90 | /// |
| 91 | /// * EITHER `Self` and `T` are either both references or both raw pointers; in either case, with |
| 92 | /// the same mutability. |
| 93 | /// * OR, all of the following hold |
| 94 | /// - `Self` and `T` must have the same type constructor, and only vary in a single type parameter |
| 95 | /// formal (the *coerced type*, e.g., `impl DispatchFromDyn<Rc<T>> for Rc<U>` is ok and the |
| 96 | /// single type parameter (instantiated with `T` or `U`) is the coerced type, |
| 97 | /// `impl DispatchFromDyn<Arc<T>> for Rc<U>` is not ok). |
| 98 | /// - The definition for `Self` must be a struct. |
| 99 | /// - The definition for `Self` must not be `#[repr(packed)]` or `#[repr(C)]`. |
| 100 | /// - Other than one-aligned, zero-sized fields, the definition for `Self` must have exactly one |
| 101 | /// field and that field's type must be the coerced type. Furthermore, `Self`'s field type must |
| 102 | /// implement `DispatchFromDyn<F>` where `F` is the type of `T`'s field type. |
| 103 | /// |
| 104 | /// An example implementation of the trait: |
| 105 | /// |
| 106 | /// ``` |
| 107 | /// # #![feature (dispatch_from_dyn, unsize)] |
| 108 | /// # use std::{ops::DispatchFromDyn, marker::Unsize}; |
| 109 | /// # struct Rc<T: ?Sized>(std::rc::Rc<T>); |
| 110 | /// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> |
| 111 | /// where |
| 112 | /// T: Unsize<U>, |
| 113 | /// {} |
| 114 | /// ``` |
| 115 | /// |
| 116 | /// [^1]: Formerly known as *object safety*. |
| 117 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
| 118 | #[lang = "dispatch_from_dyn" ] |
| 119 | pub trait DispatchFromDyn<T> { |
| 120 | // Empty. |
| 121 | } |
| 122 | |
| 123 | // &T -> &U |
| 124 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
| 125 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} |
| 126 | // &mut T -> &mut U |
| 127 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
| 128 | impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} |
| 129 | // *const T -> *const U |
| 130 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
| 131 | impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} |
| 132 | // *mut T -> *mut U |
| 133 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
| 134 | impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} |
| 135 | |