@@ -853,6 +853,59 @@ pub unsafe trait AllocRef {
853853 result
854854 }
855855
856+ /// Behaves like `realloc`, but also ensures that the new contents
857+ /// are set to zero before being returned.
858+ ///
859+ /// # Safety
860+ ///
861+ /// This function is unsafe for the same reasons that `realloc` is.
862+ ///
863+ /// # Errors
864+ ///
865+ /// Returns `Err` only if the new layout
866+ /// does not meet the allocator's size
867+ /// and alignment constraints of the allocator, or if reallocation
868+ /// otherwise fails.
869+ ///
870+ /// Implementations are encouraged to return `Err` on memory
871+ /// exhaustion rather than panicking or aborting, but this is not
872+ /// a strict requirement. (Specifically: it is *legal* to
873+ /// implement this trait atop an underlying native allocation
874+ /// library that aborts on memory exhaustion.)
875+ ///
876+ /// Clients wishing to abort computation in response to a
877+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
878+ /// rather than directly invoking `panic!` or similar.
879+ ///
880+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
881+ unsafe fn realloc_zeroed (
882+ & mut self ,
883+ ptr : NonNull < u8 > ,
884+ layout : Layout ,
885+ new_size : usize ,
886+ ) -> Result < NonNull < u8 > , AllocErr > {
887+ let old_size = layout. size ( ) ;
888+
889+ if new_size >= old_size {
890+ if let Ok ( ( ) ) = self . grow_in_place_zeroed ( ptr, layout, new_size) {
891+ return Ok ( ptr) ;
892+ }
893+ } else if new_size < old_size {
894+ if let Ok ( ( ) ) = self . shrink_in_place ( ptr, layout, new_size) {
895+ return Ok ( ptr) ;
896+ }
897+ }
898+
899+ // otherwise, fall back on alloc + copy + dealloc.
900+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
901+ let result = self . alloc_zeroed ( new_layout) ;
902+ if let Ok ( new_ptr) = result {
903+ ptr:: copy_nonoverlapping ( ptr. as_ptr ( ) , new_ptr. as_ptr ( ) , cmp:: min ( old_size, new_size) ) ;
904+ self . dealloc ( ptr, layout) ;
905+ }
906+ result
907+ }
908+
856909 /// Behaves like `alloc`, but also ensures that the contents
857910 /// are set to zero before being returned.
858911 ///
@@ -904,6 +957,31 @@ pub unsafe trait AllocRef {
904957 self . alloc ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
905958 }
906959
960+ /// Behaves like `alloc`, but also returns the whole size of
961+ /// the returned block. For some `layout` inputs, like arrays, this
962+ /// may include extra storage usable for additional data.
963+ /// Also it ensures that the contents are set to zero before being returned.
964+ ///
965+ /// # Safety
966+ ///
967+ /// This function is unsafe for the same reasons that `alloc` is.
968+ ///
969+ /// # Errors
970+ ///
971+ /// Returning `Err` indicates that either memory is exhausted or
972+ /// `layout` does not meet allocator's size or alignment
973+ /// constraints, just as in `alloc`.
974+ ///
975+ /// Clients wishing to abort computation in response to an
976+ /// allocation error are encouraged to call the [`handle_alloc_error`] function,
977+ /// rather than directly invoking `panic!` or similar.
978+ ///
979+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
980+ unsafe fn alloc_excess_zeroed ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
981+ let usable_size = self . usable_size ( & layout) ;
982+ self . alloc_zeroed ( layout) . map ( |p| Excess ( p, usable_size. 1 ) )
983+ }
984+
907985 /// Behaves like `realloc`, but also returns the whole size of
908986 /// the returned block. For some `layout` inputs, like arrays, this
909987 /// may include extra storage usable for additional data.
@@ -934,6 +1012,37 @@ pub unsafe trait AllocRef {
9341012 self . realloc ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
9351013 }
9361014
1015+ /// Behaves like `realloc`, but also returns the whole size of
1016+ /// the returned block. For some `layout` inputs, like arrays, this
1017+ /// may include extra storage usable for additional data.
1018+ /// Also it ensures that the contents are set to zero before being returned.
1019+ ///
1020+ /// # Safety
1021+ ///
1022+ /// This function is unsafe for the same reasons that `realloc` is.
1023+ ///
1024+ /// # Errors
1025+ ///
1026+ /// Returning `Err` indicates that either memory is exhausted or
1027+ /// `layout` does not meet allocator's size or alignment
1028+ /// constraints, just as in `realloc`.
1029+ ///
1030+ /// Clients wishing to abort computation in response to a
1031+ /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
1032+ /// rather than directly invoking `panic!` or similar.
1033+ ///
1034+ /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
1035+ unsafe fn realloc_excess_zeroed (
1036+ & mut self ,
1037+ ptr : NonNull < u8 > ,
1038+ layout : Layout ,
1039+ new_size : usize ,
1040+ ) -> Result < Excess , AllocErr > {
1041+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
1042+ let usable_size = self . usable_size ( & new_layout) ;
1043+ self . realloc_zeroed ( ptr, layout, new_size) . map ( |p| Excess ( p, usable_size. 1 ) )
1044+ }
1045+
9371046 /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
9381047 ///
9391048 /// If this returns `Ok`, then the allocator has asserted that the
@@ -983,6 +1092,34 @@ pub unsafe trait AllocRef {
9831092 if new_size <= u { Ok ( ( ) ) } else { Err ( CannotReallocInPlace ) }
9841093 }
9851094
1095+ /// Behaves like `grow_in_place`, but also ensures that the new
1096+ /// contents are set to zero before being returned.
1097+ ///
1098+ /// # Safety
1099+ ///
1100+ /// This function is unsafe for the same reasons that `grow_in_place` is.
1101+ ///
1102+ /// # Errors
1103+ ///
1104+ /// Returns `Err(CannotReallocInPlace)` when the allocator is
1105+ /// unable to assert that the memory block referenced by `ptr`
1106+ /// could fit `layout`.
1107+ ///
1108+ /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
1109+ /// function; clients are expected either to be able to recover from
1110+ /// `grow_in_place` failures without aborting, or to fall back on
1111+ /// another reallocation method before resorting to an abort.
1112+ unsafe fn grow_in_place_zeroed (
1113+ & mut self ,
1114+ ptr : NonNull < u8 > ,
1115+ layout : Layout ,
1116+ new_size : usize ,
1117+ ) -> Result < ( ) , CannotReallocInPlace > {
1118+ self . grow_in_place ( ptr, layout, new_size) ?;
1119+ ptr. as_ptr ( ) . add ( layout. size ( ) ) . write_bytes ( 0 , new_size - layout. size ( ) ) ;
1120+ Ok ( ( ) )
1121+ }
1122+
9861123 /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
9871124 ///
9881125 /// If this returns `Ok`, then the allocator has asserted that the
0 commit comments