1use 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"]
36pub trait CoerceUnsized<T: ?Sized> {
37 // Empty.
38}
39
40// &mut T -> &mut U
41#[unstable(feature = "coerce_unsized", issue = "18598")]
42impl<'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")]
45impl<'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")]
48impl<'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")]
51impl<'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")]
55impl<'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")]
58impl<'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")]
62impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
63// *mut T -> *const U
64#[unstable(feature = "coerce_unsized", issue = "18598")]
65impl<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")]
69impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
70
71/// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
72/// 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 object-safe 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#[unstable(feature = "dispatch_from_dyn", issue = "none")]
116#[lang = "dispatch_from_dyn"]
117pub trait DispatchFromDyn<T> {
118 // Empty.
119}
120
121// &T -> &U
122#[unstable(feature = "dispatch_from_dyn", issue = "none")]
123impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
124// &mut T -> &mut U
125#[unstable(feature = "dispatch_from_dyn", issue = "none")]
126impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
127// *const T -> *const U
128#[unstable(feature = "dispatch_from_dyn", issue = "none")]
129impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
130// *mut T -> *mut U
131#[unstable(feature = "dispatch_from_dyn", issue = "none")]
132impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
133