core/ops/
unsize.rs

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 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"]
119pub trait DispatchFromDyn<T> {
120    // Empty.
121}
122
123// &T -> &U
124#[unstable(feature = "dispatch_from_dyn", issue = "none")]
125impl<'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")]
128impl<'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")]
131impl<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")]
134impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy