1717#![ feature( min_specialization) ]
1818#![ cfg_attr( test, feature( test) ) ]
1919
20+ use rustc_data_structures:: sync;
2021use smallvec:: SmallVec ;
2122
2223use std:: alloc:: Layout ;
@@ -556,8 +557,19 @@ struct DropType {
556557 obj : * mut u8 ,
557558}
558559
559- unsafe fn drop_for_type < T > ( to_drop : * mut u8 ) {
560- std:: ptr:: drop_in_place ( to_drop as * mut T )
560+ // SAFETY: we require `T: Send` before type-erasing into `DropType`.
561+ #[ cfg( parallel_compiler) ]
562+ unsafe impl sync:: Send for DropType { }
563+
564+ impl DropType {
565+ #[ inline]
566+ unsafe fn new < T : sync:: Send > ( obj : * mut T ) -> Self {
567+ unsafe fn drop_for_type < T > ( to_drop : * mut u8 ) {
568+ std:: ptr:: drop_in_place ( to_drop as * mut T )
569+ }
570+
571+ DropType { drop_fn : drop_for_type :: < T > , obj : obj as * mut u8 }
572+ }
561573}
562574
563575impl Drop for DropType {
@@ -585,21 +597,26 @@ pub struct DropArena {
585597
586598impl DropArena {
587599 #[ inline]
588- pub unsafe fn alloc < T > ( & self , object : T ) -> & mut T {
600+ pub unsafe fn alloc < T > ( & self , object : T ) -> & mut T
601+ where
602+ T : sync:: Send ,
603+ {
589604 let mem = self . arena . alloc_raw ( Layout :: new :: < T > ( ) ) as * mut T ;
590605 // Write into uninitialized memory.
591606 ptr:: write ( mem, object) ;
592607 let result = & mut * mem;
593608 // Record the destructor after doing the allocation as that may panic
594609 // and would cause `object`'s destructor to run twice if it was recorded before.
595- self . destructors
596- . borrow_mut ( )
597- . push ( DropType { drop_fn : drop_for_type :: < T > , obj : result as * mut T as * mut u8 } ) ;
610+ self . destructors . borrow_mut ( ) . push ( DropType :: new ( result) ) ;
598611 result
599612 }
600613
601614 #[ inline]
602- pub unsafe fn alloc_from_iter < T , I : IntoIterator < Item = T > > ( & self , iter : I ) -> & mut [ T ] {
615+ pub unsafe fn alloc_from_iter < T , I > ( & self , iter : I ) -> & mut [ T ]
616+ where
617+ T : sync:: Send ,
618+ I : IntoIterator < Item = T > ,
619+ {
603620 let mut vec: SmallVec < [ _ ; 8 ] > = iter. into_iter ( ) . collect ( ) ;
604621 if vec. is_empty ( ) {
605622 return & mut [ ] ;
@@ -620,8 +637,7 @@ impl DropArena {
620637 // Record the destructors after doing the allocation as that may panic
621638 // and would cause `object`'s destructor to run twice if it was recorded before.
622639 for i in 0 ..len {
623- destructors
624- . push ( DropType { drop_fn : drop_for_type :: < T > , obj : start_ptr. add ( i) as * mut u8 } ) ;
640+ destructors. push ( DropType :: new ( start_ptr. add ( i) ) ) ;
625641 }
626642
627643 slice:: from_raw_parts_mut ( start_ptr, len)
0 commit comments