]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/unsize.rs
Remove GlobalArenas and use Arena instead
[rust.git] / src / libcore / ops / unsize.rs
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]: ../marker/trait.Unsize.html
33 /// [nomicon-coerce]: ../../nomicon/coercions.html
34 #[unstable(feature = "coerce_unsized", issue = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
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 = "27732")]
69 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
70
71
72 /// This is used for object safety, to check that a method's receiver type can be dispatched on.
73 ///
74 /// example impl:
75 ///
76 /// ```
77 /// # #![feature(dispatch_from_dyn, unsize)]
78 /// # use std::{ops::DispatchFromDyn, marker::Unsize};
79 /// # struct Rc<T: ?Sized>(::std::rc::Rc<T>);
80 /// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
81 /// where
82 ///     T: Unsize<U>,
83 /// {}
84 /// ```
85 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
86 #[lang = "dispatch_from_dyn"]
87 pub trait DispatchFromDyn<T> {
88     // Empty.
89 }
90
91 // &T -> &U
92 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
93 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
94 // &mut T -> &mut U
95 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
96 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
97 // *const T -> *const U
98 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
99 impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
100 // *mut T -> *mut U
101 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
102 impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}