@@ -847,6 +847,59 @@ pub unsafe trait AllocRef {
847847 result
848848 }
849849
850+ /// Behaves like `realloc`, but also ensures that the new contents
851+ /// are set to zero before being returned.
852+ ///
853+ /// # Safety
854+ ///
855+ /// This function is unsafe for the same reasons that `realloc` is.
856+ ///
857+ /// # Errors
858+ ///
859+ /// Returns `Err` only if the new layout
860+ /// does not meet the allocator's size
861+ /// and alignment constraints of the allocator, or if reallocation
862+ /// otherwise fails.
863+ ///
864+ /// Implementations are encouraged to return `Err` on memory
865+ /// exhaustion rather than panicking or aborting, but this is not
866+ /// a strict requirement. (Specifically: it is *legal* to
867+ /// implement this trait atop an underlying native allocation
868+ /// library that aborts on memory exhaustion.)
869+ ///
870+ /// Clients wishing to abort computation in response to a
871+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
872+ /// rather than directly invoking `panic!` or similar.
873+ ///
874+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
875+ unsafe fn realloc_zeroed (
876+ & mut self ,
877+ ptr : NonNull < u8 > ,
878+ layout : Layout ,
879+ new_size : usize ,
880+ ) -> Result < NonNull < u8 > , AllocErr > {
881+ let old_size = layout. size ( ) ;
882+
883+ if new_size >= old_size {
884+ if let Ok ( ( ) ) = self . grow_in_place_zeroed ( ptr, layout, new_size) {
885+ return Ok ( ptr) ;
886+ }
887+ } else if new_size < old_size {
888+ if let Ok ( ( ) ) = self . shrink_in_place ( ptr, layout, new_size) {
889+ return Ok ( ptr) ;
890+ }
891+ }
892+
893+ // otherwise, fall back on alloc + copy + dealloc.
894+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
895+ let result = self . alloc_zeroed ( new_layout) ;
896+ if let Ok ( new_ptr) = result {
897+ ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_ptr. as_ptr ( ) , cmp:: min ( old_size, new_size) ) ;
898+ self . dealloc ( ptr, layout) ;
899+ }
900+ result
901+ }
902+
850903 /// Behaves like `alloc`, but also ensures that the contents
851904 /// are set to zero before being returned.
852905 ///
@@ -898,6 +951,31 @@ pub unsafe trait AllocRef {
898951 self . alloc ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
899952 }
900953
954+ /// Behaves like `alloc`, but also returns the whole size of
955+ /// the returned block. For some `layout` inputs, like arrays, this
956+ /// may include extra storage usable for additional data.
957+ /// Also it ensures that the contents are set to zero before being returned.
958+ ///
959+ /// # Safety
960+ ///
961+ /// This function is unsafe for the same reasons that `alloc` is.
962+ ///
963+ /// # Errors
964+ ///
965+ /// Returning `Err` indicates that either memory is exhausted or
966+ /// `layout` does not meet allocator's size or alignment
967+ /// constraints, just as in `alloc`.
968+ ///
969+ /// Clients wishing to abort computation in response to an
970+ /// allocation error are encouraged to call the [`handle_alloc_error`] function,
971+ /// rather than directly invoking `panic!` or similar.
972+ ///
973+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
974+ unsafe fn alloc_excess_zeroed ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
975+ let usable_size = self . usable_size ( & layout) ;
976+ self . alloc_zeroed ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
977+ }
978+
901979 /// Behaves like `realloc`, but also returns the whole size of
902980 /// the returned block. For some `layout` inputs, like arrays, this
903981 /// may include extra storage usable for additional data.
@@ -928,6 +1006,37 @@ pub unsafe trait AllocRef {
9281006 self . realloc ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
9291007 }
9301008
1009+ /// Behaves like `realloc`, but also returns the whole size of
1010+ /// the returned block. For some `layout` inputs, like arrays, this
1011+ /// may include extra storage usable for additional data.
1012+ /// Also it ensures that the contents are set to zero before being returned.
1013+ ///
1014+ /// # Safety
1015+ ///
1016+ /// This function is unsafe for the same reasons that `realloc` is.
1017+ ///
1018+ /// # Errors
1019+ ///
1020+ /// Returning `Err` indicates that either memory is exhausted or
1021+ /// `layout` does not meet allocator's size or alignment
1022+ /// constraints, just as in `realloc`.
1023+ ///
1024+ /// Clients wishing to abort computation in response to a
1025+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
1026+ /// rather than directly invoking `panic!` or similar.
1027+ ///
1028+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1029+ unsafe fn realloc_excess_zeroed (
1030+ & mut self ,
1031+ ptr : NonNull < u8 > ,
1032+ layout : Layout ,
1033+ new_size : usize ,
1034+ ) -> Result < Excess , AllocErr > {
1035+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
1036+ let usable_size = self . usable_size ( & new_layout) ;
1037+ self . realloc_zeroed ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
1038+ }
1039+
9311040 /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
9321041 ///
9331042 /// If this returns `Ok`, then the allocator has asserted that the
@@ -977,6 +1086,34 @@ pub unsafe trait AllocRef {
9771086 if new_size <= u { Ok ( ( ) ) } else { Err ( CannotReallocInPlace ) }
9781087 }
9791088
1089+ /// Behaves like `grow_in_place`, but also ensures that the new
1090+ /// contents are set to zero before being returned.
1091+ ///
1092+ /// # Safety
1093+ ///
1094+ /// This function is unsafe for the same reasons that `grow_in_place` is.
1095+ ///
1096+ /// # Errors
1097+ ///
1098+ /// Returns `Err(CannotReallocInPlace)` when the allocator is
1099+ /// unable to assert that the memory block referenced by `ptr`
1100+ /// could fit `layout`.
1101+ ///
1102+ /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
1103+ /// function; clients are expected either to be able to recover from
1104+ /// `grow_in_place` failures without aborting, or to fall back on
1105+ /// another reallocation method before resorting to an abort.
1106+ unsafe fn grow_in_place_zeroed (
1107+ & mut self ,
1108+ ptr : NonNull < u8 > ,
1109+ layout : Layout ,
1110+ new_size : usize ,
1111+ ) -> Result < ( ) , CannotReallocInPlace > {
1112+ self . grow_in_place ( ptr, layout, new_size) ?;
1113+ ptr. as_ptr ( ) . add ( layout. size ( ) ) . write_bytes ( 0 , new_size - layout. size ( ) ) ;
1114+ Ok ( ( ) )
1115+ }
1116+
9801117 /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
9811118 ///
9821119 /// If this returns `Ok`, then the allocator has asserted that the
0 commit comments