// HACK(eddyb) this is a copy of `syntax::ptr`, minus the mutation (the HIR is // frozen anyway). The only reason for doing this instead of replacing `P` // with `Box` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`. use std::fmt::{self, Display, Debug}; use std::iter::FromIterator; use std::ops::Deref; use std::{slice, vec}; use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; /// An owned smart pointer. #[derive(Hash, PartialEq, Eq)] pub struct P { ptr: Box } /// Construct a `P` from a `T` value. #[allow(non_snake_case)] pub fn P(value: T) -> P { P { ptr: box value } } impl P { // HACK(eddyb) used by HIR lowering in a few places still. // NOTE: do not make this more public than `pub(super)`. pub(super) fn into_inner(self) -> T { *self.ptr } } impl Deref for P { type Target = T; fn deref(&self) -> &T { &self.ptr } } impl Debug for P { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Debug::fmt(&self.ptr, f) } } impl Display for P { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(&**self, f) } } impl Decodable for P { fn decode(d: &mut D) -> Result, D::Error> { Decodable::decode(d).map(P) } } impl Encodable for P { fn encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).encode(s) } } impl P<[T]> { pub const fn new() -> P<[T]> { // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` // (as trait methods, `default` in this case, can't be `const fn` yet). P { ptr: unsafe { use std::ptr::NonNull; std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) }, } } #[inline(never)] pub fn from_vec(v: Vec) -> P<[T]> { P { ptr: v.into_boxed_slice() } } // HACK(eddyb) used by HIR lowering in a few places still. // NOTE: do not make this more public than `pub(super)`, // and do not make this into an `IntoIterator` impl. pub(super) fn into_iter(self) -> vec::IntoIter { self.ptr.into_vec().into_iter() } } impl Default for P<[T]> { /// Creates an empty `P<[T]>`. fn default() -> P<[T]> { P::new() } } impl From> for P<[T]> { fn from(v: Vec) -> Self { P::from_vec(v) } } impl FromIterator for P<[T]> { fn from_iter>(iter: I) -> P<[T]> { P::from_vec(iter.into_iter().collect()) } } impl<'a, T> IntoIterator for &'a P<[T]> { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.ptr.into_iter() } } impl Encodable for P<[T]> { fn encode(&self, s: &mut S) -> Result<(), S::Error> { Encodable::encode(&**self, s) } } impl Decodable for P<[T]> { fn decode(d: &mut D) -> Result, D::Error> { Ok(P::from_vec(Decodable::decode(d)?)) } } impl HashStable for P where T: ?Sized + HashStable { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { (**self).hash_stable(hcx, hasher); } }