1919#![ feature( rustc_attrs) ]
2020#![ cfg_attr( test, feature( test) ) ]
2121
22- use rustc_data_structures:: sync;
2322use smallvec:: SmallVec ;
2423
2524use std:: alloc:: Layout ;
@@ -517,130 +516,12 @@ impl DroplessArena {
517516 }
518517}
519518
520- /// Calls the destructor for an object when dropped.
521- struct DropType {
522- drop_fn : unsafe fn ( * mut u8 ) ,
523- obj : * mut u8 ,
524- }
525-
526- // SAFETY: we require `T: Send` before type-erasing into `DropType`.
527- #[ cfg( parallel_compiler) ]
528- unsafe impl sync:: Send for DropType { }
529-
530- impl DropType {
531- #[ inline]
532- unsafe fn new < T : sync:: Send > ( obj : * mut T ) -> Self {
533- unsafe fn drop_for_type < T > ( to_drop : * mut u8 ) {
534- std:: ptr:: drop_in_place ( to_drop as * mut T )
535- }
536-
537- DropType { drop_fn : drop_for_type :: < T > , obj : obj as * mut u8 }
538- }
539- }
540-
541- impl Drop for DropType {
542- fn drop ( & mut self ) {
543- unsafe { ( self . drop_fn ) ( self . obj ) }
544- }
545- }
546-
547- /// An arena which can be used to allocate any type.
548- ///
549- /// # Safety
550- ///
551- /// Allocating in this arena is unsafe since the type system
552- /// doesn't know which types it contains. In order to
553- /// allocate safely, you must store a `PhantomData<T>`
554- /// alongside this arena for each type `T` you allocate.
555- #[ derive( Default ) ]
556- pub struct DropArena {
557- /// A list of destructors to run when the arena drops.
558- /// Ordered so `destructors` gets dropped before the arena
559- /// since its destructor can reference memory in the arena.
560- destructors : RefCell < Vec < DropType > > ,
561- arena : DroplessArena ,
562- }
563-
564- impl DropArena {
565- #[ inline]
566- pub unsafe fn alloc < T > ( & self , object : T ) -> & mut T
567- where
568- T : sync:: Send ,
569- {
570- let mem = self . arena . alloc_raw ( Layout :: new :: < T > ( ) ) as * mut T ;
571- // Write into uninitialized memory.
572- ptr:: write ( mem, object) ;
573- let result = & mut * mem;
574- // Record the destructor after doing the allocation as that may panic
575- // and would cause `object`'s destructor to run twice if it was recorded before.
576- self . destructors . borrow_mut ( ) . push ( DropType :: new ( result) ) ;
577- result
578- }
579-
580- #[ inline]
581- pub unsafe fn alloc_from_iter < T , I > ( & self , iter : I ) -> & mut [ T ]
582- where
583- T : sync:: Send ,
584- I : IntoIterator < Item = T > ,
585- {
586- let mut vec: SmallVec < [ _ ; 8 ] > = iter. into_iter ( ) . collect ( ) ;
587- if vec. is_empty ( ) {
588- return & mut [ ] ;
589- }
590- let len = vec. len ( ) ;
591-
592- let start_ptr = self . arena . alloc_raw ( Layout :: array :: < T > ( len) . unwrap ( ) ) as * mut T ;
593-
594- let mut destructors = self . destructors . borrow_mut ( ) ;
595- // Reserve space for the destructors so we can't panic while adding them.
596- destructors. reserve ( len) ;
597-
598- // Move the content to the arena by copying it and then forgetting
599- // the content of the SmallVec.
600- vec. as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
601- mem:: forget ( vec. drain ( ..) ) ;
602-
603- // Record the destructors after doing the allocation as that may panic
604- // and would cause `object`'s destructor to run twice if it was recorded before.
605- for i in 0 ..len {
606- destructors. push ( DropType :: new ( start_ptr. add ( i) ) ) ;
607- }
608-
609- slice:: from_raw_parts_mut ( start_ptr, len)
610- }
611- }
612-
613- pub macro arena_for_type {
614- ( [ ] [ $ty: ty] ) => {
615- $crate:: TypedArena <$ty>
616- } ,
617- ( [ few $( , $attrs: ident) * ] [ $ty: ty] ) => {
618- :: std:: marker:: PhantomData <$ty>
619- } ,
620- ( [ $ignore: ident $( , $attrs: ident) * ] $args: tt) => {
621- $crate:: arena_for_type!( [ $( $attrs) , * ] $args)
622- } ,
623- }
624-
625- pub macro which_arena_for_type {
626- ( [ ] [ $arena: expr] ) => {
627- :: std:: option:: Option :: Some ( $arena)
628- } ,
629- ( [ few $( , $attrs: ident) * ] [ $arena: expr] ) => {
630- :: std:: option:: Option :: None
631- } ,
632- ( [ $ignore: ident$( , $attrs: ident) * ] $args: tt) => {
633- $crate:: which_arena_for_type!( [ $( $attrs) , * ] $args)
634- } ,
635- }
636-
637519#[ rustc_macro_transparency = "semitransparent" ]
638520pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] , $tcx: lifetime) {
639521 #[ derive( Default ) ]
640522 pub struct Arena < $tcx> {
641523 pub dropless : $crate:: DroplessArena ,
642- drop : $crate:: DropArena ,
643- $( $name: $crate:: arena_for_type!( $a[ $ty] ) , ) *
524+ $( $name: $crate:: TypedArena <$ty>, ) *
644525 }
645526
646527 pub trait ArenaAllocatable < ' tcx , T = Self > : Sized {
@@ -670,13 +551,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
670551 #[ inline]
671552 fn allocate_on < ' a > ( self , arena : & ' a Arena < $tcx> ) -> & ' a mut Self {
672553 if !:: std:: mem:: needs_drop :: < Self > ( ) {
673- return arena. dropless . alloc ( self ) ;
674- }
675- match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
676- :: std:: option:: Option :: < & $crate:: TypedArena < Self > > :: Some ( ty_arena) => {
677- ty_arena. alloc ( self )
678- }
679- :: std:: option:: Option :: None => unsafe { arena. drop . alloc ( self ) } ,
554+ arena. dropless . alloc ( self )
555+ } else {
556+ arena. $name. alloc ( self )
680557 }
681558 }
682559
@@ -686,13 +563,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
686563 iter : impl :: std:: iter:: IntoIterator < Item = Self > ,
687564 ) -> & ' a mut [ Self ] {
688565 if !:: std:: mem:: needs_drop :: < Self > ( ) {
689- return arena. dropless . alloc_from_iter ( iter) ;
690- }
691- match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
692- :: std:: option:: Option :: < & $crate:: TypedArena < Self > > :: Some ( ty_arena) => {
693- ty_arena. alloc_from_iter ( iter)
694- }
695- :: std:: option:: Option :: None => unsafe { arena. drop . alloc_from_iter ( iter) } ,
566+ arena. dropless . alloc_from_iter ( iter)
567+ } else {
568+ arena. $name. alloc_from_iter ( iter)
696569 }
697570 }
698571 }
0 commit comments