17
17
#![ feature( min_specialization) ]
18
18
#![ cfg_attr( test, feature( test) ) ]
19
19
20
+ use rustc_data_structures:: sync;
20
21
use smallvec:: SmallVec ;
21
22
22
23
use std:: alloc:: Layout ;
@@ -556,8 +557,19 @@ struct DropType {
556
557
obj : * mut u8 ,
557
558
}
558
559
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
+ }
561
573
}
562
574
563
575
impl Drop for DropType {
@@ -585,21 +597,26 @@ pub struct DropArena {
585
597
586
598
impl DropArena {
587
599
#[ 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
+ {
589
604
let mem = self . arena . alloc_raw ( Layout :: new :: < T > ( ) ) as * mut T ;
590
605
// Write into uninitialized memory.
591
606
ptr:: write ( mem, object) ;
592
607
let result = & mut * mem;
593
608
// Record the destructor after doing the allocation as that may panic
594
609
// 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) ) ;
598
611
result
599
612
}
600
613
601
614
#[ 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
+ {
603
620
let mut vec: SmallVec < [ _ ; 8 ] > = iter. into_iter ( ) . collect ( ) ;
604
621
if vec. is_empty ( ) {
605
622
return & mut [ ] ;
@@ -620,8 +637,7 @@ impl DropArena {
620
637
// Record the destructors after doing the allocation as that may panic
621
638
// and would cause `object`'s destructor to run twice if it was recorded before.
622
639
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) ) ) ;
625
641
}
626
642
627
643
slice:: from_raw_parts_mut ( start_ptr, len)
0 commit comments