diff options
| author | Ralf Jung <post@ralfj.de> | 2020-05-16 19:46:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-16 19:46:34 +0200 |
| commit | ae66c62245240eda5a60d0cf8b564f2b6c4e3875 (patch) | |
| tree | 2182fe7c6f4d881f0f1ca02d18a6f05565b2e663 | |
| parent | ec5610ff8c41eb0664dab868dc9186a21e2f13b0 (diff) | |
| parent | bb6a6e08325a38f735b4806f5146e0d6a3fa687f (diff) | |
| download | rust-ae66c62245240eda5a60d0cf8b564f2b6c4e3875.tar.gz rust-ae66c62245240eda5a60d0cf8b564f2b6c4e3875.zip | |
Rollup merge of #72060 - lcnr:move-list, r=estebank
move `ty::List` into a new submodule `rustc_middle/ty` is currently right below the 3000 lines tidy file length limit. Moves `rustc_middle::ty::List` to the private module `rustc_middle::ty::list` and adds a `pub use self::list::List` at its previous location.
| -rw-r--r-- | src/librustc_middle/ty/list.rs | 149 | ||||
| -rw-r--r-- | src/librustc_middle/ty/mod.rs | 151 |
2 files changed, 155 insertions, 145 deletions
diff --git a/src/librustc_middle/ty/list.rs b/src/librustc_middle/ty/list.rs new file mode 100644 index 00000000000..6427c547a8f --- /dev/null +++ b/src/librustc_middle/ty/list.rs @@ -0,0 +1,149 @@ +use crate::arena::Arena; + +use rustc_serialize::{Encodable, Encoder}; + +use std::cmp::{self, Ordering}; +use std::fmt; +use std::hash::{Hash, Hasher}; +use std::mem; +use std::ops::Deref; +use std::ptr; +use std::slice; + +extern "C" { + /// A dummy type used to force `List` to be unsized while not requiring references to it be wide + /// pointers. + type OpaqueListContents; +} + +/// A wrapper for slices with the additional invariant +/// that the slice is interned and no other slice with +/// the same contents can exist in the same context. +/// This means we can use pointer for both +/// equality comparisons and hashing. +/// Note: `Slice` was already taken by the `Ty`. +#[repr(C)] +pub struct List<T> { + len: usize, + data: [T; 0], + opaque: OpaqueListContents, +} + +unsafe impl<T: Sync> Sync for List<T> {} + +impl<T: Copy> List<T> { + #[inline] + pub(super) fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> { + assert!(!mem::needs_drop::<T>()); + assert!(mem::size_of::<T>() != 0); + assert!(!slice.is_empty()); + + // Align up the size of the len (usize) field + let align = mem::align_of::<T>(); + let align_mask = align - 1; + let offset = mem::size_of::<usize>(); + let offset = (offset + align_mask) & !align_mask; + + let size = offset + slice.len() * mem::size_of::<T>(); + + let mem = arena + .dropless + .alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>())); + unsafe { + let result = &mut *(mem.as_mut_ptr() as *mut List<T>); + // Write the length + result.len = slice.len(); + + // Write the elements + let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len); + arena_slice.copy_from_slice(slice); + + result + } + } +} + +impl<T: fmt::Debug> fmt::Debug for List<T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (**self).fmt(f) + } +} + +impl<T: Encodable> Encodable for List<T> { + #[inline] + fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { + (**self).encode(s) + } +} + +impl<T> Ord for List<T> +where + T: Ord, +{ + fn cmp(&self, other: &List<T>) -> Ordering { + if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) } + } +} + +impl<T> PartialOrd for List<T> +where + T: PartialOrd, +{ + fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> { + if self == other { + Some(Ordering::Equal) + } else { + <[T] as PartialOrd>::partial_cmp(&**self, &**other) + } + } +} + +impl<T: PartialEq> PartialEq for List<T> { + #[inline] + fn eq(&self, other: &List<T>) -> bool { + ptr::eq(self, other) + } +} +impl<T: Eq> Eq for List<T> {} + +impl<T> Hash for List<T> { + #[inline] + fn hash<H: Hasher>(&self, s: &mut H) { + (self as *const List<T>).hash(s) + } +} + +impl<T> Deref for List<T> { + type Target = [T]; + #[inline(always)] + fn deref(&self) -> &[T] { + self.as_ref() + } +} + +impl<T> AsRef<[T]> for List<T> { + #[inline(always)] + fn as_ref(&self) -> &[T] { + unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) } + } +} + +impl<'a, T> IntoIterator for &'a List<T> { + type Item = &'a T; + type IntoIter = <&'a [T] as IntoIterator>::IntoIter; + #[inline(always)] + fn into_iter(self) -> Self::IntoIter { + self[..].iter() + } +} + +impl<T> List<T> { + #[inline(always)] + pub fn empty<'a>() -> &'a List<T> { + #[repr(align(64), C)] + struct EmptySlice([u8; 64]); + static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]); + assert!(mem::align_of::<T>() <= 64); + unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) } + } +} diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 4f9b87997db..6d6e1699feb 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -4,7 +4,6 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::Variance::*; -use crate::arena::Arena; use crate::hir::exports::ExportMap; use crate::ich::StableHashingContext; use crate::infer::canonical::Canonical; @@ -43,13 +42,11 @@ use rustc_span::Span; use rustc_target::abi::{Align, VariantIdx}; use std::cell::RefCell; -use std::cmp::{self, Ordering}; +use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; -use std::ops::Deref; use std::ops::Range; -use std::slice; -use std::{mem, ptr}; +use std::ptr; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; @@ -81,6 +78,8 @@ pub use self::context::{ pub use self::instance::{Instance, InstanceDef}; +pub use self::list::List; + pub use self::trait_def::TraitDef; pub use self::query::queries; @@ -112,6 +111,7 @@ pub mod walk; mod context; mod diagnostics; mod instance; +mod list; mod structural_impls; mod sty; @@ -663,148 +663,9 @@ pub type Ty<'tcx> = &'tcx TyS<'tcx>; impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {} impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {} - -pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; - -extern "C" { - /// A dummy type used to force `List` to be unsized while not requiring references to it be wide - /// pointers. - type OpaqueListContents; -} - -/// A wrapper for slices with the additional invariant -/// that the slice is interned and no other slice with -/// the same contents can exist in the same context. -/// This means we can use pointer for both -/// equality comparisons and hashing. -/// Note: `Slice` was already taken by the `Ty`. -#[repr(C)] -pub struct List<T> { - len: usize, - data: [T; 0], - opaque: OpaqueListContents, -} - -unsafe impl<T: Sync> Sync for List<T> {} - -impl<T: Copy> List<T> { - #[inline] - fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> { - assert!(!mem::needs_drop::<T>()); - assert!(mem::size_of::<T>() != 0); - assert!(!slice.is_empty()); - - // Align up the size of the len (usize) field - let align = mem::align_of::<T>(); - let align_mask = align - 1; - let offset = mem::size_of::<usize>(); - let offset = (offset + align_mask) & !align_mask; - - let size = offset + slice.len() * mem::size_of::<T>(); - - let mem = arena - .dropless - .alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>())); - unsafe { - let result = &mut *(mem.as_mut_ptr() as *mut List<T>); - // Write the length - result.len = slice.len(); - - // Write the elements - let arena_slice = slice::from_raw_parts_mut(result.data.as_mut_ptr(), result.len); - arena_slice.copy_from_slice(slice); - - result - } - } -} - -impl<T: fmt::Debug> fmt::Debug for List<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -impl<T: Encodable> Encodable for List<T> { - #[inline] - fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl<T> Ord for List<T> -where - T: Ord, -{ - fn cmp(&self, other: &List<T>) -> Ordering { - if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) } - } -} - -impl<T> PartialOrd for List<T> -where - T: PartialOrd, -{ - fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> { - if self == other { - Some(Ordering::Equal) - } else { - <[T] as PartialOrd>::partial_cmp(&**self, &**other) - } - } -} - -impl<T: PartialEq> PartialEq for List<T> { - #[inline] - fn eq(&self, other: &List<T>) -> bool { - ptr::eq(self, other) - } -} -impl<T: Eq> Eq for List<T> {} - -impl<T> Hash for List<T> { - #[inline] - fn hash<H: Hasher>(&self, s: &mut H) { - (self as *const List<T>).hash(s) - } -} - -impl<T> Deref for List<T> { - type Target = [T]; - #[inline(always)] - fn deref(&self) -> &[T] { - self.as_ref() - } -} - -impl<T> AsRef<[T]> for List<T> { - #[inline(always)] - fn as_ref(&self) -> &[T] { - unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) } - } -} - -impl<'a, T> IntoIterator for &'a List<T> { - type Item = &'a T; - type IntoIter = <&'a [T] as IntoIterator>::IntoIter; - #[inline(always)] - fn into_iter(self) -> Self::IntoIter { - self[..].iter() - } -} - impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<Ty<'tcx>> {} -impl<T> List<T> { - #[inline(always)] - pub fn empty<'a>() -> &'a List<T> { - #[repr(align(64), C)] - struct EmptySlice([u8; 64]); - static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]); - assert!(mem::align_of::<T>() <= 64); - unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) } - } -} +pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)] pub struct UpvarPath { |
