Skip to content

Commit 47b72e3

Browse files
committed
Remove & -> &mut transmute from TypedArena
1 parent a535cfb commit 47b72e3

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

src/libarena/lib.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -345,19 +345,20 @@ fn test_arena_destructors_fail() {
345345
/// run again for these objects.
346346
pub 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

358359
struct 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]
483483
impl<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

Comments
 (0)