| 1 | //! Various traits used to restrict intrinsics to not-completely-wrong types. |
| 2 | |
| 3 | /// Types with a built-in dereference operator in runtime MIR, |
| 4 | /// aka references and raw pointers. |
| 5 | /// |
| 6 | /// # Safety |
| 7 | /// Must actually *be* such a type. |
| 8 | pub unsafe trait BuiltinDeref: Sized { |
| 9 | type Pointee: ?Sized; |
| 10 | } |
| 11 | |
| 12 | unsafe impl<T: ?Sized> BuiltinDeref for &mut T { |
| 13 | type Pointee = T; |
| 14 | } |
| 15 | unsafe impl<T: ?Sized> BuiltinDeref for &T { |
| 16 | type Pointee = T; |
| 17 | } |
| 18 | unsafe impl<T: ?Sized> BuiltinDeref for *mut T { |
| 19 | type Pointee = T; |
| 20 | } |
| 21 | unsafe impl<T: ?Sized> BuiltinDeref for *const T { |
| 22 | type Pointee = T; |
| 23 | } |
| 24 | |
| 25 | pub trait ChangePointee<U: ?Sized>: BuiltinDeref { |
| 26 | type Output; |
| 27 | } |
| 28 | impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a mut T { |
| 29 | type Output = &'a mut U; |
| 30 | } |
| 31 | impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a T { |
| 32 | type Output = &'a U; |
| 33 | } |
| 34 | impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *mut T { |
| 35 | type Output = *mut U; |
| 36 | } |
| 37 | impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *const T { |
| 38 | type Output = *const U; |
| 39 | } |
| 40 | |