@@ -54,7 +54,9 @@ impl AllocInit {
5454 #[ inline]
5555 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
5656 pub unsafe fn init ( self , memory : MemoryBlock ) {
57- self . init_offset ( memory, 0 )
57+ // SAFETY: the safety contract for `init_offset` must be
58+ // upheld by the caller.
59+ unsafe { self . init_offset ( memory, 0 ) }
5860 }
5961
6062 /// Initialize the memory block like specified by `init` at the specified `offset`.
@@ -78,7 +80,10 @@ impl AllocInit {
7880 match self {
7981 AllocInit :: Uninitialized => ( ) ,
8082 AllocInit :: Zeroed => {
81- memory. ptr . as_ptr ( ) . add ( offset) . write_bytes ( 0 , memory. size - offset)
83+ // SAFETY: the caller must guarantee that `offset` is smaller than or equal to `memory.size`,
84+ // so the memory from `memory.ptr + offset` of length `memory.size - offset`
85+ // is guaranteed to be contaned in `memory` and thus valid for writes.
86+ unsafe { memory. ptr . as_ptr ( ) . add ( offset) . write_bytes ( 0 , memory. size - offset) }
8287 }
8388 }
8489 }
@@ -281,11 +286,23 @@ pub unsafe trait AllocRef {
281286 return Ok ( MemoryBlock { ptr, size } ) ;
282287 }
283288
284- let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
289+ let new_layout =
290+ // SAFETY: the caller must ensure that the `new_size` does not overflow.
291+ // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
292+ // The caller must ensure that `new_size` is greater than zero.
293+ unsafe { Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) } ;
285294 let new_memory = self . alloc ( new_layout, init) ?;
286- ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_memory. ptr . as_ptr ( ) , size) ;
287- self . dealloc ( ptr, layout) ;
288- Ok ( new_memory)
295+
296+ // SAFETY: because `new_size` must be greater than or equal to `size`, both the old and new
297+ // memory allocation are valid for reads and writes for `size` bytes. Also, because the old
298+ // allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to
299+ // `copy_nonoverlapping` is safe.
300+ // The safety contract for `dealloc` must be upheld by the caller.
301+ unsafe {
302+ ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_memory. ptr . as_ptr ( ) , size) ;
303+ self . dealloc ( ptr, layout) ;
304+ Ok ( new_memory)
305+ }
289306 }
290307 }
291308 }
@@ -356,11 +373,23 @@ pub unsafe trait AllocRef {
356373 return Ok ( MemoryBlock { ptr, size } ) ;
357374 }
358375
359- let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
376+ let new_layout =
377+ // SAFETY: the caller must ensure that the `new_size` does not overflow.
378+ // `layout.align()` comes from a `Layout` and is thus guaranteed to be valid for a Layout.
379+ // The caller must ensure that `new_size` is greater than zero.
380+ unsafe { Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) } ;
360381 let new_memory = self . alloc ( new_layout, AllocInit :: Uninitialized ) ?;
361- ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_memory. ptr . as_ptr ( ) , new_size) ;
362- self . dealloc ( ptr, layout) ;
363- Ok ( new_memory)
382+
383+ // SAFETY: because `new_size` must be lower than or equal to `size`, both the old and new
384+ // memory allocation are valid for reads and writes for `new_size` bytes. Also, because the
385+ // old allocation wasn't yet deallocated, it cannot overlap `new_memory`. Thus, the call to
386+ // `copy_nonoverlapping` is safe.
387+ // The safety contract for `dealloc` must be upheld by the caller.
388+ unsafe {
389+ ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_memory. ptr . as_ptr ( ) , new_size) ;
390+ self . dealloc ( ptr, layout) ;
391+ Ok ( new_memory)
392+ }
364393 }
365394 }
366395 }
@@ -386,7 +415,8 @@ where
386415
387416 #[ inline]
388417 unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : Layout ) {
389- ( * * self ) . dealloc ( ptr, layout)
418+ // SAFETY: the safety contract must be upheld by the caller
419+ unsafe { ( * * self ) . dealloc ( ptr, layout) }
390420 }
391421
392422 #[ inline]
@@ -398,7 +428,8 @@ where
398428 placement : ReallocPlacement ,
399429 init : AllocInit ,
400430 ) -> Result < MemoryBlock , AllocErr > {
401- ( * * self ) . grow ( ptr, layout, new_size, placement, init)
431+ // SAFETY: the safety contract must be upheld by the caller
432+ unsafe { ( * * self ) . grow ( ptr, layout, new_size, placement, init) }
402433 }
403434
404435 #[ inline]
@@ -409,6 +440,7 @@ where
409440 new_size : usize ,
410441 placement : ReallocPlacement ,
411442 ) -> Result < MemoryBlock , AllocErr > {
412- ( * * self ) . shrink ( ptr, layout, new_size, placement)
443+ // SAFETY: the safety contract must be upheld by the caller
444+ unsafe { ( * * self ) . shrink ( ptr, layout, new_size, placement) }
413445 }
414446}
0 commit comments