@@ -606,20 +606,11 @@ pub unsafe trait GlobalAlloc {
606606/// method (`dealloc`) or by being passed to a reallocation method
607607/// (see above) that returns `Ok`.
608608///
609- /// A note regarding zero-sized types and zero-sized layouts: many
610- /// methods in the `AllocRef` trait state that allocation requests
611- /// must be non-zero size, or else undefined behavior can result.
612- ///
613- /// * If an `AllocRef` implementation chooses to return `Ok` in this
614- /// case (i.e., the pointer denotes a zero-sized inaccessible block)
615- /// then that returned pointer must be considered "currently
616- /// allocated". On such an allocator, *all* methods that take
617- /// currently-allocated pointers as inputs must accept these
618- /// zero-sized pointers, *without* causing undefined behavior.
619- ///
620- /// * In other words, if a zero-sized pointer can flow out of an
621- /// allocator, then that allocator must likewise accept that pointer
622- /// flowing back into its deallocation and reallocation methods.
609+ /// Unlike [`GlobalAlloc`], zero-sized allocations are allowed in
610+ /// `AllocRef`. If an underlying allocator does not support this (like
611+ /// jemalloc) or return a null pointer (such as `libc::malloc`), this case
612+ /// must be caught. In this case [`Layout::dangling()`] can be used to
613+ /// create a dangling, but aligned `NonNull<u8>`.
623614///
624615/// Some of the methods require that a layout *fit* a memory block.
625616/// What it means for a layout to "fit" a memory block means (or
@@ -649,6 +640,9 @@ pub unsafe trait GlobalAlloc {
649640/// * if an allocator does not support overallocating, it is fine to
650641/// simply return `layout.size()` as the allocated size.
651642///
643+ /// [`GlobalAlloc`]: self::GlobalAlloc
644+ /// [`Layout::dangling()`]: self::Layout::dangling
645+ ///
652646/// # Safety
653647///
654648/// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and
@@ -669,14 +663,6 @@ pub unsafe trait GlobalAlloc {
669663/// the future.
670664#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
671665pub unsafe trait AllocRef {
672- // (Note: some existing allocators have unspecified but well-defined
673- // behavior in response to a zero size allocation request ;
674- // e.g., in C, `malloc` of 0 will either return a null pointer or a
675- // unique pointer, but will not have arbitrary undefined
676- // behavior.
677- // However in jemalloc for example,
678- // `mallocx(0)` is documented as undefined behavior.)
679-
680666 /// On success, returns a pointer meeting the size and alignment
681667 /// guarantees of `layout` and the actual size of the allocated block,
682668 /// which must be greater than or equal to `layout.size()`.
@@ -690,15 +676,6 @@ pub unsafe trait AllocRef {
690676 /// behavior, e.g., to ensure initialization to particular sets of
691677 /// bit patterns.)
692678 ///
693- /// # Safety
694- ///
695- /// This function is unsafe because undefined behavior can result
696- /// if the caller does not ensure that `layout` has non-zero size.
697- ///
698- /// (Extension subtraits might provide more specific bounds on
699- /// behavior, e.g., guarantee a sentinel address or a null pointer
700- /// in response to a zero-size allocation request.)
701- ///
702679 /// # Errors
703680 ///
704681 /// Returning `Err` indicates that either memory is exhausted or
@@ -716,7 +693,7 @@ pub unsafe trait AllocRef {
716693 /// rather than directly invoking `panic!` or similar.
717694 ///
718695 /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
719- unsafe fn alloc ( & mut self , layout : Layout ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > ;
696+ fn alloc ( & mut self , layout : Layout ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > ;
720697
721698 /// Deallocate the memory referenced by `ptr`.
722699 ///
@@ -738,10 +715,6 @@ pub unsafe trait AllocRef {
738715 /// Behaves like `alloc`, but also ensures that the contents
739716 /// are set to zero before being returned.
740717 ///
741- /// # Safety
742- ///
743- /// This function is unsafe for the same reasons that `alloc` is.
744- ///
745718 /// # Errors
746719 ///
747720 /// Returning `Err` indicates that either memory is exhausted or
@@ -753,17 +726,17 @@ pub unsafe trait AllocRef {
753726 /// rather than directly invoking `panic!` or similar.
754727 ///
755728 /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
756- unsafe fn alloc_zeroed ( & mut self , layout : Layout ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
729+ fn alloc_zeroed ( & mut self , layout : Layout ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
757730 let size = layout. size ( ) ;
758731 let result = self . alloc ( layout) ;
759732 if let Ok ( ( p, _) ) = result {
760- ptr:: write_bytes ( p. as_ptr ( ) , 0 , size) ;
733+ unsafe { ptr:: write_bytes ( p. as_ptr ( ) , 0 , size) }
761734 }
762735 result
763736 }
764737
765738 // == METHODS FOR MEMORY REUSE ==
766- // realloc. alloc_excess, realloc_excess
739+ // realloc, realloc_zeroed, grow_in_place, grow_in_place_zeroed, shrink_in_place
767740
768741 /// Returns a pointer suitable for holding data described by
769742 /// a new layout with `layout`’s alignment and a size given
@@ -793,8 +766,6 @@ pub unsafe trait AllocRef {
793766 /// * `layout` must *fit* the `ptr` (see above). (The `new_size`
794767 /// argument need not fit it.)
795768 ///
796- /// * `new_size` must be greater than zero.
797- ///
798769 /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
799770 /// must not overflow (i.e., the rounded value must be less than `usize::MAX`).
800771 ///
@@ -1009,8 +980,7 @@ pub unsafe trait AllocRef {
1009980 /// * `layout` must *fit* the `ptr` (see above); note the
1010981 /// `new_size` argument need not fit it,
1011982 ///
1012- /// * `new_size` must not be greater than `layout.size()`
1013- /// (and must be greater than zero),
983+ /// * `new_size` must not be greater than `layout.size()`,
1014984 ///
1015985 /// # Errors
1016986 ///
0 commit comments