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