diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 0785942d13a3..24ade7300c33 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -140,25 +140,19 @@ impl TypedArena { /// Allocates an object in the `TypedArena`, returning a reference to it. #[inline] pub fn alloc(&self, object: T) -> &mut T { + assert!(size_of::() != 0); + if self.ptr == self.end { self.grow(1) } unsafe { - if size_of::() == 0 { - self.ptr.set(self.ptr.get().wrapping_byte_add(1)); - let ptr = ptr::NonNull::::dangling().as_ptr(); - // Don't drop the object. This `write` is equivalent to `forget`. - ptr::write(ptr, object); - &mut *ptr - } else { - let ptr = self.ptr.get(); - // Advance the pointer. - self.ptr.set(self.ptr.get().add(1)); - // Write into uninitialized memory. - ptr::write(ptr, object); - &mut *ptr - } + let ptr = self.ptr.get(); + // Advance the pointer. + self.ptr.set(self.ptr.get().add(1)); + // Write into uninitialized memory. + ptr::write(ptr, object); + &mut *ptr } } @@ -302,16 +296,10 @@ fn clear_last_chunk(&self, last_chunk: &mut ArenaChunk) { let end = self.ptr.get().addr(); // We then calculate the number of elements to be dropped in the last chunk, // which is the filled area's length. - let diff = if size_of::() == 0 { - // `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get - // the number of zero-sized values in the last and only chunk, just out of caution. - // Recall that `end` was incremented for each allocated value. - end - start - } else { - // FIXME: this should *likely* use `offset_from`, but more - // investigation is needed (including running tests in miri). - (end - start) / size_of::() - }; + assert_ne!(size_of::(), 0); + // FIXME: this should *likely* use `offset_from`, but more + // investigation is needed (including running tests in miri). + let diff = (end - start) / size_of::(); // Pass that to the `destroy` method. unsafe { last_chunk.destroy(diff); diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs index eb9406d691b1..751ddd80408a 100644 --- a/compiler/rustc_arena/src/tests.rs +++ b/compiler/rustc_arena/src/tests.rs @@ -22,7 +22,6 @@ fn clear(&mut self) { if let Some(last_chunk) = chunks_borrow.last_mut() { self.clear_last_chunk(last_chunk); let len = chunks_borrow.len(); - // If `T` is ZST, code below has no effect. for mut chunk in chunks_borrow.drain(..len - 1) { chunk.destroy(chunk.entries); } @@ -117,18 +116,6 @@ fn test_noncopy() { } } -#[test] -fn test_typed_arena_zero_sized() { - let arena = TypedArena::default(); - #[cfg(not(miri))] - const N: usize = 100000; - #[cfg(miri)] - const N: usize = 1000; - for _ in 0..N { - arena.alloc(()); - } -} - #[test] fn test_typed_arena_clear() { let mut arena = TypedArena::default(); @@ -207,7 +194,8 @@ fn test_typed_arena_drop_on_clear() { static DROP_COUNTER: Cell = Cell::new(0) } -struct SmallDroppable; +#[allow(unused)] +struct SmallDroppable(u8); impl Drop for SmallDroppable { fn drop(&mut self) { @@ -222,7 +210,7 @@ fn test_typed_arena_drop_small_count() { let arena: TypedArena = TypedArena::default(); for _ in 0..100 { // Allocate something with drop glue to make sure it doesn't leak. - arena.alloc(SmallDroppable); + arena.alloc(SmallDroppable(0)); } // dropping };