18
18
#![ feature( decl_macro) ]
19
19
#![ feature( rustc_attrs) ]
20
20
#![ cfg_attr( test, feature( test) ) ]
21
+ #![ feature( strict_provenance) ]
21
22
22
23
use smallvec:: SmallVec ;
23
24
@@ -87,7 +88,7 @@ impl<T> ArenaChunk<T> {
87
88
unsafe {
88
89
if mem:: size_of :: < T > ( ) == 0 {
89
90
// A pointer as large as possible for zero-sized elements.
90
- ! 0 as * mut T
91
+ ptr :: invalid_mut ( ! 0 )
91
92
} else {
92
93
self . start ( ) . add ( self . storage . len ( ) )
93
94
}
@@ -199,7 +200,7 @@ impl<T> TypedArena<T> {
199
200
unsafe {
200
201
if mem:: size_of :: < T > ( ) == 0 {
201
202
self . ptr . set ( ( self . ptr . get ( ) as * mut u8 ) . wrapping_offset ( 1 ) as * mut T ) ;
202
- let ptr = mem :: align_of :: < T > ( ) as * mut T ;
203
+ let ptr = ptr :: NonNull :: < T > :: dangling ( ) . as_ptr ( ) ;
203
204
// Don't drop the object. This `write` is equivalent to `forget`.
204
205
ptr:: write ( ptr, object) ;
205
206
& mut * ptr
@@ -216,7 +217,7 @@ impl<T> TypedArena<T> {
216
217
217
218
#[ inline]
218
219
fn can_allocate ( & self , additional : usize ) -> bool {
219
- let available_bytes = self . end . get ( ) as usize - self . ptr . get ( ) as usize ;
220
+ let available_bytes = self . end . get ( ) . addr ( ) - self . ptr . get ( ) . addr ( ) ;
220
221
let additional_bytes = additional. checked_mul ( mem:: size_of :: < T > ( ) ) . unwrap ( ) ;
221
222
available_bytes >= additional_bytes
222
223
}
@@ -262,7 +263,7 @@ impl<T> TypedArena<T> {
262
263
// If a type is `!needs_drop`, we don't need to keep track of how many elements
263
264
// the chunk stores - the field will be ignored anyway.
264
265
if mem:: needs_drop :: < T > ( ) {
265
- let used_bytes = self . ptr . get ( ) as usize - last_chunk. start ( ) as usize ;
266
+ let used_bytes = self . ptr . get ( ) . addr ( ) - last_chunk. start ( ) . addr ( ) ;
266
267
last_chunk. entries = used_bytes / mem:: size_of :: < T > ( ) ;
267
268
}
268
269
@@ -288,9 +289,9 @@ impl<T> TypedArena<T> {
288
289
// chunks.
289
290
fn clear_last_chunk ( & self , last_chunk : & mut ArenaChunk < T > ) {
290
291
// Determine how much was filled.
291
- let start = last_chunk. start ( ) as usize ;
292
+ let start = last_chunk. start ( ) . addr ( ) ;
292
293
// We obtain the value of the pointer to the first uninitialized element.
293
- let end = self . ptr . get ( ) as usize ;
294
+ let end = self . ptr . get ( ) . addr ( ) ;
294
295
// We then calculate the number of elements to be dropped in the last chunk,
295
296
// which is the filled area's length.
296
297
let diff = if mem:: size_of :: < T > ( ) == 0 {
@@ -395,15 +396,16 @@ impl DroplessArena {
395
396
/// request.
396
397
#[ inline]
397
398
fn alloc_raw_without_grow ( & self , layout : Layout ) -> Option < * mut u8 > {
398
- let start = self . start . get ( ) as usize ;
399
- let end = self . end . get ( ) as usize ;
399
+ let start = self . start . get ( ) . addr ( ) ;
400
+ let old_end = self . end . get ( ) ;
401
+ let end = old_end. addr ( ) ;
400
402
401
403
let align = layout. align ( ) ;
402
404
let bytes = layout. size ( ) ;
403
405
404
406
let new_end = end. checked_sub ( bytes) ? & !( align - 1 ) ;
405
407
if start <= new_end {
406
- let new_end = new_end as * mut u8 ;
408
+ let new_end = old_end . with_addr ( new_end) ;
407
409
self . end . set ( new_end) ;
408
410
Some ( new_end)
409
411
} else {
0 commit comments