@@ -111,7 +111,7 @@ impl<T> Default for TypedArena<T> {
111111 // alloc() will trigger a grow().
112112 ptr : Cell :: new ( ptr:: null_mut ( ) ) ,
113113 end : Cell :: new ( ptr:: null_mut ( ) ) ,
114- chunks : RefCell :: new ( vec ! [ ] ) ,
114+ chunks : Default :: default ( ) ,
115115 _own : PhantomData ,
116116 }
117117 }
@@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
325325
326326unsafe impl < T : Send > Send for TypedArena < T > { }
327327
328+ /// An arena that can hold objects of multiple different types that impl `Copy`
329+ /// and/or satisfy `!mem::needs_drop`.
328330pub struct DroplessArena {
329331 /// A pointer to the start of the free space.
330332 start : Cell < * mut u8 > ,
331333
332334 /// A pointer to the end of free space.
333335 ///
334- /// The allocation proceeds from the end of the chunk towards the start.
336+ /// The allocation proceeds downwards from the end of the chunk towards the
337+ /// start. (This is slightly simpler and faster than allocating upwards,
338+ /// see <https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html>.)
335339 /// When this pointer crosses the start pointer, a new chunk is allocated.
336340 end : Cell < * mut u8 > ,
337341
@@ -516,6 +520,10 @@ impl DroplessArena {
516520 }
517521}
518522
523+ // Declare an `Arena` containing one dropless arena and many typed arenas (the
524+ // types of the typed arenas are specified by the arguments). The dropless
525+ // arena will be used for any types that impl `Copy`, and also for any of the
526+ // specified types that satisfy `!mem::needs_drop`.
519527#[ rustc_macro_transparency = "semitransparent" ]
520528pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] ) {
521529 #[ derive( Default ) ]
@@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
532540 ) -> & ' a mut [ Self ] ;
533541 }
534542
543+ // Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
535544 impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx , ( ) > for T {
536545 #[ inline]
537546 fn allocate_on < ' a > ( self , arena : & ' a Arena < ' tcx > ) -> & ' a mut Self {
@@ -544,7 +553,6 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
544553 ) -> & ' a mut [ Self ] {
545554 arena. dropless . alloc_from_iter ( iter)
546555 }
547-
548556 }
549557 $(
550558 impl<' tcx> ArenaAllocatable <' tcx, $ty> for $ty {
@@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
577585 value. allocate_on ( self )
578586 }
579587
588+ // Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`.
580589 #[ inline]
581590 pub fn alloc_slice < T : :: std:: marker:: Copy > ( & self , value : & [ T ] ) -> & mut [ T ] {
582591 if value. is_empty ( ) {
0 commit comments