]> git.lizzy.rs Git - rust.git/blob - src/libcore/ops/unsize.rs
Bump to 1.33.0
[rust.git] / src / libcore / ops / unsize.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use marker::Unsize;
12
13 /// Trait that indicates that this is a pointer or a wrapper for one,
14 /// where unsizing can be performed on the pointee.
15 ///
16 /// See the [DST coercion RFC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
17 /// for more details.
18 ///
19 /// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
20 /// by converting from a thin pointer to a fat pointer.
21 ///
22 /// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
23 /// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
24 /// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
25 /// field involving `T`. If the type of that field is `Bar<T>`, an implementation
26 /// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
27 /// coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
28 /// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
29 /// field and coerce that.
30 ///
31 /// Generally, for smart pointers you will implement
32 /// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
33 /// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
34 /// like `Cell<T>` and `RefCell<T>`, you
35 /// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
36 /// This will let coercions of types like `Cell<Box<T>>` work.
37 ///
38 /// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
39 /// pointers. It is implemented automatically by the compiler.
40 ///
41 /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
42 /// [unsize]: ../marker/trait.Unsize.html
43 /// [nomicon-coerce]: ../../nomicon/coercions.html
44 #[unstable(feature = "coerce_unsized", issue = "27732")]
45 #[lang = "coerce_unsized"]
46 pub trait CoerceUnsized<T: ?Sized> {
47     // Empty.
48 }
49
50 // &mut T -> &mut U
51 #[unstable(feature = "coerce_unsized", issue = "27732")]
52 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
53 // &mut 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 mut T {}
56 // &mut T -> *mut U
57 #[unstable(feature = "coerce_unsized", issue = "27732")]
58 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
59 // &mut T -> *const U
60 #[unstable(feature = "coerce_unsized", issue = "27732")]
61 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
62
63 // &T -> &U
64 #[unstable(feature = "coerce_unsized", issue = "27732")]
65 impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
66 // &T -> *const U
67 #[unstable(feature = "coerce_unsized", issue = "27732")]
68 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
69
70 // *mut T -> *mut U
71 #[unstable(feature = "coerce_unsized", issue = "27732")]
72 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
73 // *mut T -> *const U
74 #[unstable(feature = "coerce_unsized", issue = "27732")]
75 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
76
77 // *const T -> *const U
78 #[unstable(feature = "coerce_unsized", issue = "27732")]
79 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
80
81
82 /// This is used for object safety, to check that a method's receiver type can be dispatched on.
83 ///
84 /// example impl:
85 ///
86 /// ```
87 /// # #![feature(dispatch_from_dyn, unsize)]
88 /// # use std::{ops::DispatchFromDyn, marker::Unsize};
89 /// # struct Rc<T: ?Sized>(::std::rc::Rc<T>);
90 /// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
91 /// where
92 ///     T: Unsize<U>,
93 /// {}
94 /// ```
95 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
96 #[lang = "dispatch_from_dyn"]
97 pub trait DispatchFromDyn<T> {
98     // Empty.
99 }
100
101 // &T -> &U
102 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
103 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
104 // &mut T -> &mut U
105 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
106 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
107 // *const T -> *const U
108 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
109 impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
110 // *mut T -> *mut U
111 #[unstable(feature = "dispatch_from_dyn", issue = "0")]
112 impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
113