1313) ]
1414#![ feature( core_intrinsics) ]
1515#![ feature( dropck_eyepatch) ]
16- #![ feature( raw_vec_internals) ]
16+ #![ feature( new_uninit) ]
17+ #![ feature( maybe_uninit_slice) ]
1718#![ cfg_attr( test, feature( test) ) ]
1819#![ allow( deprecated) ]
1920
20- extern crate alloc;
21-
2221use rustc_data_structures:: cold_path;
2322use smallvec:: SmallVec ;
2423
@@ -27,12 +26,10 @@ use std::cell::{Cell, RefCell};
2726use std:: cmp;
2827use std:: intrinsics;
2928use std:: marker:: { PhantomData , Send } ;
30- use std:: mem;
29+ use std:: mem:: { self , MaybeUninit } ;
3130use std:: ptr;
3231use std:: slice;
3332
34- use alloc:: raw_vec:: RawVec ;
35-
3633/// An arena that can hold objects of only one type.
3734pub struct TypedArena < T > {
3835 /// A pointer to the next object to be allocated.
@@ -52,15 +49,15 @@ pub struct TypedArena<T> {
5249
5350struct TypedArenaChunk < T > {
5451 /// The raw storage for the arena chunk.
55- storage : RawVec < T > ,
52+ storage : Box < [ MaybeUninit < T > ] > ,
5653 /// The number of valid entries in the chunk.
5754 entries : usize ,
5855}
5956
6057impl < T > TypedArenaChunk < T > {
6158 #[ inline]
6259 unsafe fn new ( capacity : usize ) -> TypedArenaChunk < T > {
63- TypedArenaChunk { storage : RawVec :: with_capacity ( capacity) , entries : 0 }
60+ TypedArenaChunk { storage : Box :: new_uninit_slice ( capacity) , entries : 0 }
6461 }
6562
6663 /// Destroys this arena chunk.
@@ -69,30 +66,25 @@ impl<T> TypedArenaChunk<T> {
6966 // The branch on needs_drop() is an -O1 performance optimization.
7067 // Without the branch, dropping TypedArena<u8> takes linear time.
7168 if mem:: needs_drop :: < T > ( ) {
72- let mut start = self . start ( ) ;
73- // Destroy all allocated objects.
74- for _ in 0 ..len {
75- ptr:: drop_in_place ( start) ;
76- start = start. offset ( 1 ) ;
77- }
69+ ptr:: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( & mut self . storage [ ..len] ) ) ;
7870 }
7971 }
8072
8173 // Returns a pointer to the first allocated object.
8274 #[ inline]
83- fn start ( & self ) -> * mut T {
84- self . storage . ptr ( )
75+ fn start ( & mut self ) -> * mut T {
76+ MaybeUninit :: slice_as_mut_ptr ( & mut self . storage )
8577 }
8678
8779 // Returns a pointer to the end of the allocated space.
8880 #[ inline]
89- fn end ( & self ) -> * mut T {
81+ fn end ( & mut self ) -> * mut T {
9082 unsafe {
9183 if mem:: size_of :: < T > ( ) == 0 {
9284 // A pointer as large as possible for zero-sized elements.
9385 !0 as * mut T
9486 } else {
95- self . start ( ) . add ( self . storage . capacity ( ) )
87+ self . start ( ) . add ( self . storage . len ( ) )
9688 }
9789 }
9890 }
@@ -226,10 +218,10 @@ impl<T> TypedArena<T> {
226218 let used_bytes = self . ptr . get ( ) as usize - last_chunk. start ( ) as usize ;
227219 last_chunk. entries = used_bytes / mem:: size_of :: < T > ( ) ;
228220
229- // If the previous chunk's capacity is less than HUGE_PAGE
221+ // If the previous chunk's len is less than HUGE_PAGE
230222 // bytes, then this chunk will be least double the previous
231223 // chunk's size.
232- new_cap = last_chunk. storage . capacity ( ) ;
224+ new_cap = last_chunk. storage . len ( ) ;
233225 if new_cap < HUGE_PAGE / elem_size {
234226 new_cap = new_cap. checked_mul ( 2 ) . unwrap ( ) ;
235227 }
@@ -239,7 +231,7 @@ impl<T> TypedArena<T> {
239231 // Also ensure that this chunk can fit `additional`.
240232 new_cap = cmp:: max ( additional, new_cap) ;
241233
242- let chunk = TypedArenaChunk :: < T > :: new ( new_cap) ;
234+ let mut chunk = TypedArenaChunk :: < T > :: new ( new_cap) ;
243235 self . ptr . set ( chunk. start ( ) ) ;
244236 self . end . set ( chunk. end ( ) ) ;
245237 chunks. push ( chunk) ;
@@ -301,7 +293,7 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
301293 chunk. destroy ( chunk. entries ) ;
302294 }
303295 }
304- // RawVec handles deallocation of `last_chunk` and `self.chunks`.
296+ // Box handles deallocation of `last_chunk` and `self.chunks`.
305297 }
306298 }
307299}
@@ -344,10 +336,10 @@ impl DroplessArena {
344336 // There is no need to update `last_chunk.entries` because that
345337 // field isn't used by `DroplessArena`.
346338
347- // If the previous chunk's capacity is less than HUGE_PAGE
339+ // If the previous chunk's len is less than HUGE_PAGE
348340 // bytes, then this chunk will be least double the previous
349341 // chunk's size.
350- new_cap = last_chunk. storage . capacity ( ) ;
342+ new_cap = last_chunk. storage . len ( ) ;
351343 if new_cap < HUGE_PAGE {
352344 new_cap = new_cap. checked_mul ( 2 ) . unwrap ( ) ;
353345 }
@@ -357,7 +349,7 @@ impl DroplessArena {
357349 // Also ensure that this chunk can fit `additional`.
358350 new_cap = cmp:: max ( additional, new_cap) ;
359351
360- let chunk = TypedArenaChunk :: < u8 > :: new ( new_cap) ;
352+ let mut chunk = TypedArenaChunk :: < u8 > :: new ( new_cap) ;
361353 self . ptr . set ( chunk. start ( ) ) ;
362354 self . end . set ( chunk. end ( ) ) ;
363355 chunks. push ( chunk) ;
0 commit comments