@@ -606,20 +606,11 @@ pub unsafe trait GlobalAlloc {
606
606
/// method (`dealloc`) or by being passed to a reallocation method
607
607
/// (see above) that returns `Ok`.
608
608
///
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>`.
623
614
///
624
615
/// Some of the methods require that a layout *fit* a memory block.
625
616
/// What it means for a layout to "fit" a memory block means (or
@@ -649,6 +640,9 @@ pub unsafe trait GlobalAlloc {
649
640
/// * if an allocator does not support overallocating, it is fine to
650
641
/// simply return `layout.size()` as the allocated size.
651
642
///
643
+ /// [`GlobalAlloc`]: self::GlobalAlloc
644
+ /// [`Layout::dangling()`]: self::Layout::dangling
645
+ ///
652
646
/// # Safety
653
647
///
654
648
/// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and
@@ -669,14 +663,6 @@ pub unsafe trait GlobalAlloc {
669
663
/// the future.
670
664
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
671
665
pub 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
-
680
666
/// On success, returns a pointer meeting the size and alignment
681
667
/// guarantees of `layout` and the actual size of the allocated block,
682
668
/// which must be greater than or equal to `layout.size()`.
@@ -690,15 +676,6 @@ pub unsafe trait AllocRef {
690
676
/// behavior, e.g., to ensure initialization to particular sets of
691
677
/// bit patterns.)
692
678
///
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
- ///
702
679
/// # Errors
703
680
///
704
681
/// Returning `Err` indicates that either memory is exhausted or
@@ -716,7 +693,7 @@ pub unsafe trait AllocRef {
716
693
/// rather than directly invoking `panic!` or similar.
717
694
///
718
695
/// [`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 > ;
720
697
721
698
/// Deallocate the memory referenced by `ptr`.
722
699
///
@@ -738,10 +715,6 @@ pub unsafe trait AllocRef {
738
715
/// Behaves like `alloc`, but also ensures that the contents
739
716
/// are set to zero before being returned.
740
717
///
741
- /// # Safety
742
- ///
743
- /// This function is unsafe for the same reasons that `alloc` is.
744
- ///
745
718
/// # Errors
746
719
///
747
720
/// Returning `Err` indicates that either memory is exhausted or
@@ -753,17 +726,17 @@ pub unsafe trait AllocRef {
753
726
/// rather than directly invoking `panic!` or similar.
754
727
///
755
728
/// [`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 > {
757
730
let size = layout. size ( ) ;
758
731
let result = self . alloc ( layout) ;
759
732
if let Ok ( ( p, _) ) = result {
760
- ptr:: write_bytes ( p. as_ptr ( ) , 0 , size) ;
733
+ unsafe { ptr:: write_bytes ( p. as_ptr ( ) , 0 , size) }
761
734
}
762
735
result
763
736
}
764
737
765
738
// == METHODS FOR MEMORY REUSE ==
766
- // realloc. alloc_excess, realloc_excess
739
+ // realloc, realloc_zeroed, grow_in_place, grow_in_place_zeroed, shrink_in_place
767
740
768
741
/// Returns a pointer suitable for holding data described by
769
742
/// a new layout with `layout`’s alignment and a size given
@@ -793,8 +766,6 @@ pub unsafe trait AllocRef {
793
766
/// * `layout` must *fit* the `ptr` (see above). (The `new_size`
794
767
/// argument need not fit it.)
795
768
///
796
- /// * `new_size` must be greater than zero.
797
- ///
798
769
/// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
799
770
/// must not overflow (i.e., the rounded value must be less than `usize::MAX`).
800
771
///
@@ -1009,8 +980,7 @@ pub unsafe trait AllocRef {
1009
980
/// * `layout` must *fit* the `ptr` (see above); note the
1010
981
/// `new_size` argument need not fit it,
1011
982
///
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()`,
1014
984
///
1015
985
/// # Errors
1016
986
///
0 commit comments