@@ -111,7 +111,7 @@ impl<T> Default for TypedArena<T> {
111
111
// alloc() will trigger a grow().
112
112
ptr : Cell :: new ( ptr:: null_mut ( ) ) ,
113
113
end : Cell :: new ( ptr:: null_mut ( ) ) ,
114
- chunks : RefCell :: new ( vec ! [ ] ) ,
114
+ chunks : Default :: default ( ) ,
115
115
_own : PhantomData ,
116
116
}
117
117
}
@@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
325
325
326
326
unsafe impl < T : Send > Send for TypedArena < T > { }
327
327
328
+ /// An arena that can hold objects of multiple different types that impl `Copy`
329
+ /// and/or satisfy `!mem::needs_drop`.
328
330
pub struct DroplessArena {
329
331
/// A pointer to the start of the free space.
330
332
start : Cell < * mut u8 > ,
331
333
332
334
/// A pointer to the end of free space.
333
335
///
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>.)
335
339
/// When this pointer crosses the start pointer, a new chunk is allocated.
336
340
end : Cell < * mut u8 > ,
337
341
@@ -516,6 +520,10 @@ impl DroplessArena {
516
520
}
517
521
}
518
522
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`.
519
527
#[ rustc_macro_transparency = "semitransparent" ]
520
528
pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] ) {
521
529
#[ derive( Default ) ]
@@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
532
540
) -> & ' a mut [ Self ] ;
533
541
}
534
542
543
+ // Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
535
544
impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx , ( ) > for T {
536
545
#[ inline]
537
546
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,)*]) {
544
553
) -> & ' a mut [ Self ] {
545
554
arena. dropless . alloc_from_iter ( iter)
546
555
}
547
-
548
556
}
549
557
$(
550
558
impl<' tcx> ArenaAllocatable <' tcx, $ty> for $ty {
@@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
577
585
value. allocate_on ( self )
578
586
}
579
587
588
+ // Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`.
580
589
#[ inline]
581
590
pub fn alloc_slice < T : :: std:: marker:: Copy > ( & self , value : & [ T ] ) -> & mut [ T ] {
582
591
if value. is_empty ( ) {
0 commit comments