@@ -345,19 +345,20 @@ fn test_arena_destructors_fail() {
345345/// run again for these objects.
346346pub struct TypedArena < T > {
347347 /// A pointer to the next object to be allocated.
348- ptr : * T ,
348+ ptr : Cell < * T > ,
349349
350350 /// A pointer to the end of the allocated area. When this pointer is
351351 /// reached, a new chunk is allocated.
352- end : * T ,
352+ end : Cell < * T > ,
353353
354354 /// A pointer to the first arena segment.
355- first : Option < Box < TypedArenaChunk < T > > > ,
355+ first : RefCell < TypedArenaChunkRef < T > > ,
356356}
357+ type TypedArenaChunkRef < T > = Option < Box < TypedArenaChunk < T > > > ;
357358
358359struct TypedArenaChunk < T > {
359360 /// Pointer to the next arena segment.
360- next : Option < Box < TypedArenaChunk < T > > > ,
361+ next : TypedArenaChunkRef < T > ,
361362
362363 /// The number of elements that this chunk can hold.
363364 capacity : uint ,
@@ -443,53 +444,52 @@ impl<T> TypedArena<T> {
443444 pub fn with_capacity ( capacity : uint ) -> TypedArena < T > {
444445 let chunk = TypedArenaChunk :: < T > :: new ( None , capacity) ;
445446 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) ) ,
449450 }
450451 }
451452
452453 /// Allocates an object in the TypedArena, returning a reference to it.
453454 #[ inline]
454455 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+ }
461459
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 ) ;
463462 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 ) ) ;
466464 ptr
467- }
465+ } ;
466+
467+ ptr
468468 }
469469
470470 /// Grows the arena.
471471 #[ 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 ( ) ;
474474 let new_capacity = chunk. capacity . checked_mul ( & 2 ) . unwrap ( ) ;
475475 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)
479479 }
480480}
481481
482482#[ unsafe_destructor]
483483impl < T > Drop for TypedArena < T > {
484484 fn drop ( & mut self ) {
485485 // 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 ;
488488 let diff = ( end - start) / mem:: size_of :: < T > ( ) ;
489489
490490 // Pass that to the `destroy` method.
491491 unsafe {
492- self . first . get_mut_ref ( ) . destroy ( diff)
492+ self . first . borrow_mut ( ) . get_mut_ref ( ) . destroy ( diff)
493493 }
494494 }
495495}
0 commit comments