diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index c8702c42c47f6..ce8300331b846 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -45,7 +45,6 @@ #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] -#![feature(ptr_alignment_type)] #![feature(range_bounds_is_empty)] #![feature(rustc_attrs)] #![feature(sized_hierarchy)] diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 81c3c7baa07af..409f0ff2c37dd 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -119,14 +119,6 @@ impl Erasable for &'_ [T] { type Storage = [u8; size_of::<&'_ [()]>()]; } -impl Erasable for &'_ ty::List { - type Storage = [u8; size_of::<&'_ ty::List<()>>()]; -} - -impl Erasable for &'_ ty::ListWithCachedTypeInfo { - type Storage = [u8; size_of::<&'_ ty::ListWithCachedTypeInfo<()>>()]; -} - impl Erasable for Result<&'_ T, traits::query::NoSolution> { type Storage = [u8; size_of::>()]; } diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 82c23abefce45..c22c7a4700215 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -4,8 +4,7 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::{fmt, iter, mem, ptr, slice}; -use rustc_data_structures::aligned::{Aligned, align_of}; -use rustc_data_structures::sync::DynSync; +use rustc_data_structures::aligned::align_of; use rustc_serialize::{Encodable, Encoder}; use rustc_type_ir::FlagComputation; @@ -36,14 +35,6 @@ pub type List = RawList<(), T>; /// [`Hash`] and [`Encodable`]. #[repr(C)] pub struct RawList { - skel: ListSkeleton, - opaque: OpaqueListContents, -} - -/// A [`RawList`] without the unsized tail. This type is used for layout computation -/// and constructing empty lists. -#[repr(C)] -struct ListSkeleton { header: H, len: usize, /// Although this claims to be a zero-length array, in practice `len` @@ -57,16 +48,10 @@ impl Default for &List { } } -unsafe extern "C" { - /// A dummy type used to force `List` to be unsized while not requiring - /// references to it be wide pointers. - type OpaqueListContents; -} - impl RawList { #[inline(always)] pub fn len(&self) -> usize { - self.skel.len + self.len } #[inline(always)] @@ -97,18 +82,18 @@ impl RawList { assert!(!slice.is_empty()); let (layout, _offset) = - Layout::new::>().extend(Layout::for_value::<[T]>(slice)).unwrap(); + Layout::new::>().extend(Layout::for_value::<[T]>(slice)).unwrap(); let mem = arena.dropless.alloc_raw(layout) as *mut RawList; unsafe { // Write the header - (&raw mut (*mem).skel.header).write(header); + (&raw mut (*mem).header).write(header); // Write the length - (&raw mut (*mem).skel.len).write(slice.len()); + (&raw mut (*mem).len).write(slice.len()); // Write the elements - (&raw mut (*mem).skel.data) + (&raw mut (*mem).data) .cast::() .copy_from_nonoverlapping(slice.as_ptr(), slice.len()); @@ -152,8 +137,8 @@ macro_rules! impl_list_empty { #[repr(align(64))] struct MaxAlign; - static EMPTY: ListSkeleton<$header_ty, MaxAlign> = - ListSkeleton { header: $header_init, len: 0, data: [] }; + static EMPTY: RawList<$header_ty, MaxAlign> = + RawList { header: $header_init, len: 0, data: [] }; assert!(align_of::() <= align_of::()); @@ -237,12 +222,12 @@ impl Deref for RawList { impl AsRef<[T]> for RawList { #[inline(always)] fn as_ref(&self) -> &[T] { - let data_ptr = (&raw const self.skel.data).cast::(); + let data_ptr = (&raw const self.data).cast::(); // SAFETY: `data_ptr` has the same provenance as `self` and can therefore // access the `self.skel.len` elements stored at `self.skel.data`. // Note that we specifically don't reborrow `&self.skel.data`, because that // would give us a pointer with provenance over 0 bytes. - unsafe { slice::from_raw_parts(data_ptr, self.skel.len) } + unsafe { slice::from_raw_parts(data_ptr, self.len) } } } @@ -257,19 +242,6 @@ impl<'a, H, T: Copy> IntoIterator for &'a RawList { unsafe impl Sync for RawList {} -// We need this since `List` uses extern type `OpaqueListContents`. -unsafe impl DynSync for RawList {} - -// Safety: -// Layouts of `ListSkeleton` and `RawList` are the same, modulo opaque tail, -// thus aligns of `ListSkeleton` and `RawList` must be the same. -unsafe impl Aligned for RawList { - #[cfg(bootstrap)] - const ALIGN: ptr::Alignment = align_of::>(); - #[cfg(not(bootstrap))] - const ALIGN: mem::Alignment = align_of::>(); -} - /// A [`List`] that additionally stores type information inline to speed up /// [`TypeVisitableExt`](super::TypeVisitableExt) operations. pub type ListWithCachedTypeInfo = RawList; @@ -277,12 +249,12 @@ pub type ListWithCachedTypeInfo = RawList; impl ListWithCachedTypeInfo { #[inline(always)] pub fn flags(&self) -> TypeFlags { - self.skel.header.flags + self.header.flags } #[inline(always)] pub fn outer_exclusive_binder(&self) -> DebruijnIndex { - self.skel.header.outer_exclusive_binder + self.header.outer_exclusive_binder } } @@ -310,3 +282,18 @@ impl<'tcx> From>> for TypeInfo { } } } + +#[cfg(target_pointer_width = "64")] +mod size_asserts { + use rustc_data_structures::static_assert_size; + + use super::*; + // tidy-alphabetical-start + static_assert_size!(&List, 8); + static_assert_size!(&RawList, 8); + static_assert_size!(List, 8); + static_assert_size!(List, 8); + static_assert_size!(RawList, 16); + static_assert_size!(RawList, 16); + // tidy-alphabetical-end +}