@@ -4,8 +4,7 @@ use std::hash::{Hash, Hasher};
44use std:: ops:: Deref ;
55use std:: { fmt, iter, mem, ptr, slice} ;
66
7- use rustc_data_structures:: aligned:: { Aligned , align_of} ;
8- use rustc_data_structures:: sync:: DynSync ;
7+ use rustc_data_structures:: aligned:: align_of;
98use rustc_serialize:: { Encodable , Encoder } ;
109use rustc_type_ir:: FlagComputation ;
1110
@@ -36,14 +35,6 @@ pub type List<T> = RawList<(), T>;
3635/// [`Hash`] and [`Encodable`].
3736#[ repr( C ) ]
3837pub struct RawList < H , T > {
39- skel : ListSkeleton < H , T > ,
40- opaque : OpaqueListContents ,
41- }
42-
43- /// A [`RawList`] without the unsized tail. This type is used for layout computation
44- /// and constructing empty lists.
45- #[ repr( C ) ]
46- struct ListSkeleton < H , T > {
4738 header : H ,
4839 len : usize ,
4940 /// Although this claims to be a zero-length array, in practice `len`
@@ -57,16 +48,10 @@ impl<T> Default for &List<T> {
5748 }
5849}
5950
60- unsafe extern "C" {
61- /// A dummy type used to force `List` to be unsized while not requiring
62- /// references to it be wide pointers.
63- type OpaqueListContents ;
64- }
65-
6651impl < H , T > RawList < H , T > {
6752 #[ inline( always) ]
6853 pub fn len ( & self ) -> usize {
69- self . skel . len
54+ self . len
7055 }
7156
7257 #[ inline( always) ]
@@ -97,18 +82,18 @@ impl<H, T> RawList<H, T> {
9782 assert ! ( !slice. is_empty( ) ) ;
9883
9984 let ( layout, _offset) =
100- Layout :: new :: < ListSkeleton < H , T > > ( ) . extend ( Layout :: for_value :: < [ T ] > ( slice) ) . unwrap ( ) ;
85+ Layout :: new :: < RawList < H , T > > ( ) . extend ( Layout :: for_value :: < [ T ] > ( slice) ) . unwrap ( ) ;
10186
10287 let mem = arena. dropless . alloc_raw ( layout) as * mut RawList < H , T > ;
10388 unsafe {
10489 // Write the header
105- ( & raw mut ( * mem) . skel . header ) . write ( header) ;
90+ ( & raw mut ( * mem) . header ) . write ( header) ;
10691
10792 // Write the length
108- ( & raw mut ( * mem) . skel . len ) . write ( slice. len ( ) ) ;
93+ ( & raw mut ( * mem) . len ) . write ( slice. len ( ) ) ;
10994
11095 // Write the elements
111- ( & raw mut ( * mem) . skel . data )
96+ ( & raw mut ( * mem) . data )
11297 . cast :: < T > ( )
11398 . copy_from_nonoverlapping ( slice. as_ptr ( ) , slice. len ( ) ) ;
11499
@@ -152,8 +137,8 @@ macro_rules! impl_list_empty {
152137 #[ repr( align( 64 ) ) ]
153138 struct MaxAlign ;
154139
155- static EMPTY : ListSkeleton <$header_ty, MaxAlign > =
156- ListSkeleton { header: $header_init, len: 0 , data: [ ] } ;
140+ static EMPTY : RawList <$header_ty, MaxAlign > =
141+ RawList { header: $header_init, len: 0 , data: [ ] } ;
157142
158143 assert!( align_of:: <T >( ) <= align_of:: <MaxAlign >( ) ) ;
159144
@@ -237,12 +222,12 @@ impl<H, T> Deref for RawList<H, T> {
237222impl < H , T > AsRef < [ T ] > for RawList < H , T > {
238223 #[ inline( always) ]
239224 fn as_ref ( & self ) -> & [ T ] {
240- let data_ptr = ( & raw const self . skel . data ) . cast :: < T > ( ) ;
225+ let data_ptr = ( & raw const self . data ) . cast :: < T > ( ) ;
241226 // SAFETY: `data_ptr` has the same provenance as `self` and can therefore
242227 // access the `self.skel.len` elements stored at `self.skel.data`.
243228 // Note that we specifically don't reborrow `&self.skel.data`, because that
244229 // would give us a pointer with provenance over 0 bytes.
245- unsafe { slice:: from_raw_parts ( data_ptr, self . skel . len ) }
230+ unsafe { slice:: from_raw_parts ( data_ptr, self . len ) }
246231 }
247232}
248233
@@ -257,29 +242,19 @@ impl<'a, H, T: Copy> IntoIterator for &'a RawList<H, T> {
257242
258243unsafe impl < H : Sync , T : Sync > Sync for RawList < H , T > { }
259244
260- // We need this since `List` uses extern type `OpaqueListContents`.
261- unsafe impl < H : DynSync , T : DynSync > DynSync for RawList < H , T > { }
262-
263- // Safety:
264- // Layouts of `ListSkeleton<H, T>` and `RawList<H, T>` are the same, modulo opaque tail,
265- // thus aligns of `ListSkeleton<H, T>` and `RawList<H, T>` must be the same.
266- unsafe impl < H , T > Aligned for RawList < H , T > {
267- const ALIGN : ptr:: Alignment = align_of :: < ListSkeleton < H , T > > ( ) ;
268- }
269-
270245/// A [`List`] that additionally stores type information inline to speed up
271246/// [`TypeVisitableExt`](super::TypeVisitableExt) operations.
272247pub type ListWithCachedTypeInfo < T > = RawList < TypeInfo , T > ;
273248
274249impl < T > ListWithCachedTypeInfo < T > {
275250 #[ inline( always) ]
276251 pub fn flags ( & self ) -> TypeFlags {
277- self . skel . header . flags
252+ self . header . flags
278253 }
279254
280255 #[ inline( always) ]
281256 pub fn outer_exclusive_binder ( & self ) -> DebruijnIndex {
282- self . skel . header . outer_exclusive_binder
257+ self . header . outer_exclusive_binder
283258 }
284259}
285260
@@ -307,3 +282,18 @@ impl<'tcx> From<FlagComputation<TyCtxt<'tcx>>> for TypeInfo {
307282 }
308283 }
309284}
285+
286+ #[ cfg( target_pointer_width = "64" ) ]
287+ mod size_asserts {
288+ use rustc_data_structures:: static_assert_size;
289+
290+ use super :: * ;
291+ // tidy-alphabetical-start
292+ static_assert_size ! ( & List <u32 >, 8 ) ;
293+ static_assert_size ! ( & RawList <u8 , u32 >, 8 ) ;
294+ static_assert_size ! ( List <u8 >, 8 ) ;
295+ static_assert_size ! ( List <u32 >, 8 ) ;
296+ static_assert_size ! ( RawList <u8 , u32 >, 16 ) ;
297+ static_assert_size ! ( RawList <usize , u32 >, 16 ) ;
298+ // tidy-alphabetical-end
299+ }
0 commit comments