@@ -345,19 +345,20 @@ fn test_arena_destructors_fail() {
345
345
/// run again for these objects.
346
346
pub struct TypedArena < T > {
347
347
/// A pointer to the next object to be allocated.
348
- ptr : * T ,
348
+ ptr : Cell < * T > ,
349
349
350
350
/// A pointer to the end of the allocated area. When this pointer is
351
351
/// reached, a new chunk is allocated.
352
- end : * T ,
352
+ end : Cell < * T > ,
353
353
354
354
/// A pointer to the first arena segment.
355
- first : Option < Box < TypedArenaChunk < T > > > ,
355
+ first : RefCell < TypedArenaChunkRef < T > > ,
356
356
}
357
+ type TypedArenaChunkRef < T > = Option < Box < TypedArenaChunk < T > > > ;
357
358
358
359
struct TypedArenaChunk < T > {
359
360
/// Pointer to the next arena segment.
360
- next : Option < Box < TypedArenaChunk < T > > > ,
361
+ next : TypedArenaChunkRef < T > ,
361
362
362
363
/// The number of elements that this chunk can hold.
363
364
capacity : uint ,
@@ -443,53 +444,52 @@ impl<T> TypedArena<T> {
443
444
pub fn with_capacity ( capacity : uint ) -> TypedArena < T > {
444
445
let chunk = TypedArenaChunk :: < T > :: new ( None , capacity) ;
445
446
TypedArena {
446
- ptr : chunk. start ( ) as * T ,
447
- end : chunk. end ( ) as * T ,
448
- first : Some ( chunk) ,
447
+ ptr : Cell :: new ( chunk. start ( ) as * T ) ,
448
+ end : Cell :: new ( chunk. end ( ) as * T ) ,
449
+ first : RefCell :: new ( Some ( chunk) ) ,
449
450
}
450
451
}
451
452
452
453
/// Allocates an object in the TypedArena, returning a reference to it.
453
454
#[ inline]
454
455
pub fn alloc < ' a > ( & ' a self , object : T ) -> & ' a T {
455
- unsafe {
456
- // FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes
457
- let this: & mut TypedArena < T > = mem:: transmute :: < & _ , & mut _ > ( self ) ;
458
- if this. ptr == this. end {
459
- this. grow ( )
460
- }
456
+ if self . ptr == self . end {
457
+ self . grow ( )
458
+ }
461
459
462
- let ptr: & ' a mut T = mem:: transmute ( this. ptr ) ;
460
+ let ptr: & ' a T = unsafe {
461
+ let ptr: & ' a mut T = mem:: transmute ( self . ptr ) ;
463
462
ptr:: write ( ptr, object) ;
464
- this. ptr = this. ptr . offset ( 1 ) ;
465
- let ptr: & ' a T = ptr;
463
+ self . ptr . set ( self . ptr . get ( ) . offset ( 1 ) ) ;
466
464
ptr
467
- }
465
+ } ;
466
+
467
+ ptr
468
468
}
469
469
470
470
/// Grows the arena.
471
471
#[ inline( never) ]
472
- fn grow ( & mut self ) {
473
- let chunk = self . first . take_unwrap ( ) ;
472
+ fn grow ( & self ) {
473
+ let chunk = self . first . borrow_mut ( ) . take_unwrap ( ) ;
474
474
let new_capacity = chunk. capacity . checked_mul ( & 2 ) . unwrap ( ) ;
475
475
let chunk = TypedArenaChunk :: < T > :: new ( Some ( chunk) , new_capacity) ;
476
- self . ptr = chunk. start ( ) as * T ;
477
- self . end = chunk. end ( ) as * T ;
478
- self . first = Some ( chunk)
476
+ self . ptr . set ( chunk. start ( ) as * T ) ;
477
+ self . end . set ( chunk. end ( ) as * T ) ;
478
+ * self . first . borrow_mut ( ) = Some ( chunk)
479
479
}
480
480
}
481
481
482
482
#[ unsafe_destructor]
483
483
impl < T > Drop for TypedArena < T > {
484
484
fn drop ( & mut self ) {
485
485
// Determine how much was filled.
486
- let start = self . first . get_ref ( ) . start ( ) as uint ;
487
- let end = self . ptr as uint ;
486
+ let start = self . first . borrow ( ) . get_ref ( ) . start ( ) as uint ;
487
+ let end = self . ptr . get ( ) as uint ;
488
488
let diff = ( end - start) / mem:: size_of :: < T > ( ) ;
489
489
490
490
// Pass that to the `destroy` method.
491
491
unsafe {
492
- self . first . get_mut_ref ( ) . destroy ( diff)
492
+ self . first . borrow_mut ( ) . get_mut_ref ( ) . destroy ( diff)
493
493
}
494
494
}
495
495
}
0 commit comments