]> git.lizzy.rs Git - rust.git/blob - src/libcore/alloc.rs
Rollup merge of #69817 - thekuom:test/borrow-checking-pattern-features, r=Centril
[rust.git] / src / libcore / alloc.rs
1 //! Memory allocation APIs
2
3 // ignore-tidy-undocumented-unsafe
4
5 #![stable(feature = "alloc_module", since = "1.28.0")]
6
7 use crate::cmp;
8 use crate::fmt;
9 use crate::mem;
10 use crate::num::NonZeroUsize;
11 use crate::ptr::{self, NonNull};
12 use crate::usize;
13
14 const fn size_align<T>() -> (usize, usize) {
15     (mem::size_of::<T>(), mem::align_of::<T>())
16 }
17
18 /// Layout of a block of memory.
19 ///
20 /// An instance of `Layout` describes a particular layout of memory.
21 /// You build a `Layout` up as an input to give to an allocator.
22 ///
23 /// All layouts have an associated non-negative size and a
24 /// power-of-two alignment.
25 ///
26 /// (Note however that layouts are *not* required to have positive
27 /// size, even though many allocators require that all memory
28 /// requests have positive size. A caller to the `AllocRef::alloc`
29 /// method must either ensure that conditions like this are met, or
30 /// use specific allocators with looser requirements.)
31 #[stable(feature = "alloc_layout", since = "1.28.0")]
32 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
33 #[lang = "alloc_layout"]
34 pub struct Layout {
35     // size of the requested block of memory, measured in bytes.
36     size_: usize,
37
38     // alignment of the requested block of memory, measured in bytes.
39     // we ensure that this is always a power-of-two, because API's
40     // like `posix_memalign` require it and it is a reasonable
41     // constraint to impose on Layout constructors.
42     //
43     // (However, we do not analogously require `align >= sizeof(void*)`,
44     //  even though that is *also* a requirement of `posix_memalign`.)
45     align_: NonZeroUsize,
46 }
47
48 impl Layout {
49     /// Constructs a `Layout` from a given `size` and `align`,
50     /// or returns `LayoutErr` if any of the following conditions
51     /// are not met:
52     ///
53     /// * `align` must not be zero,
54     ///
55     /// * `align` must be a power of two,
56     ///
57     /// * `size`, when rounded up to the nearest multiple of `align`,
58     ///    must not overflow (i.e., the rounded value must be less than
59     ///    `usize::MAX`).
60     #[stable(feature = "alloc_layout", since = "1.28.0")]
61     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
62     #[inline]
63     pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
64         if !align.is_power_of_two() {
65             return Err(LayoutErr { private: () });
66         }
67
68         // (power-of-two implies align != 0.)
69
70         // Rounded up size is:
71         //   size_rounded_up = (size + align - 1) & !(align - 1);
72         //
73         // We know from above that align != 0. If adding (align - 1)
74         // does not overflow, then rounding up will be fine.
75         //
76         // Conversely, &-masking with !(align - 1) will subtract off
77         // only low-order-bits. Thus if overflow occurs with the sum,
78         // the &-mask cannot subtract enough to undo that overflow.
79         //
80         // Above implies that checking for summation overflow is both
81         // necessary and sufficient.
82         if size > usize::MAX - (align - 1) {
83             return Err(LayoutErr { private: () });
84         }
85
86         unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
87     }
88
89     /// Creates a layout, bypassing all checks.
90     ///
91     /// # Safety
92     ///
93     /// This function is unsafe as it does not verify the preconditions from
94     /// [`Layout::from_size_align`](#method.from_size_align).
95     #[stable(feature = "alloc_layout", since = "1.28.0")]
96     #[rustc_const_stable(feature = "alloc_layout", since = "1.28.0")]
97     #[inline]
98     pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
99         Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
100     }
101
102     /// The minimum size in bytes for a memory block of this layout.
103     #[stable(feature = "alloc_layout", since = "1.28.0")]
104     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
105     #[inline]
106     pub const fn size(&self) -> usize {
107         self.size_
108     }
109
110     /// The minimum byte alignment for a memory block of this layout.
111     #[stable(feature = "alloc_layout", since = "1.28.0")]
112     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
113     #[inline]
114     pub const fn align(&self) -> usize {
115         self.align_.get()
116     }
117
118     /// Constructs a `Layout` suitable for holding a value of type `T`.
119     #[stable(feature = "alloc_layout", since = "1.28.0")]
120     #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]
121     #[inline]
122     pub const fn new<T>() -> Self {
123         let (size, align) = size_align::<T>();
124         // Note that the align is guaranteed by rustc to be a power of two and
125         // the size+align combo is guaranteed to fit in our address space. As a
126         // result use the unchecked constructor here to avoid inserting code
127         // that panics if it isn't optimized well enough.
128         unsafe { Layout::from_size_align_unchecked(size, align) }
129     }
130
131     /// Produces layout describing a record that could be used to
132     /// allocate backing structure for `T` (which could be a trait
133     /// or other unsized type like a slice).
134     #[stable(feature = "alloc_layout", since = "1.28.0")]
135     #[inline]
136     pub fn for_value<T: ?Sized>(t: &T) -> Self {
137         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
138         // See rationale in `new` for why this is using an unsafe variant below
139         debug_assert!(Layout::from_size_align(size, align).is_ok());
140         unsafe { Layout::from_size_align_unchecked(size, align) }
141     }
142
143     /// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
144     ///
145     /// Note that the pointer value may potentially represent a valid pointer,
146     /// which means this must not be used as a "not yet initialized"
147     /// sentinel value. Types that lazily allocate must track initialization by
148     /// some other means.
149     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
150     pub const fn dangling(&self) -> NonNull<u8> {
151         // align is non-zero and a power of two
152         unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
153     }
154
155     /// Creates a layout describing the record that can hold a value
156     /// of the same layout as `self`, but that also is aligned to
157     /// alignment `align` (measured in bytes).
158     ///
159     /// If `self` already meets the prescribed alignment, then returns
160     /// `self`.
161     ///
162     /// Note that this method does not add any padding to the overall
163     /// size, regardless of whether the returned layout has a different
164     /// alignment. In other words, if `K` has size 16, `K.align_to(32)`
165     /// will *still* have size 16.
166     ///
167     /// Returns an error if the combination of `self.size()` and the given
168     /// `align` violates the conditions listed in
169     /// [`Layout::from_size_align`](#method.from_size_align).
170     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
171     #[inline]
172     pub fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
173         Layout::from_size_align(self.size(), cmp::max(self.align(), align))
174     }
175
176     /// Returns the amount of padding we must insert after `self`
177     /// to ensure that the following address will satisfy `align`
178     /// (measured in bytes).
179     ///
180     /// e.g., if `self.size()` is 9, then `self.padding_needed_for(4)`
181     /// returns 3, because that is the minimum number of bytes of
182     /// padding required to get a 4-aligned address (assuming that the
183     /// corresponding memory block starts at a 4-aligned address).
184     ///
185     /// The return value of this function has no meaning if `align` is
186     /// not a power-of-two.
187     ///
188     /// Note that the utility of the returned value requires `align`
189     /// to be less than or equal to the alignment of the starting
190     /// address for the whole allocated block of memory. One way to
191     /// satisfy this constraint is to ensure `align <= self.align()`.
192     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
193     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
194     #[inline]
195     pub const fn padding_needed_for(&self, align: usize) -> usize {
196         let len = self.size();
197
198         // Rounded up value is:
199         //   len_rounded_up = (len + align - 1) & !(align - 1);
200         // and then we return the padding difference: `len_rounded_up - len`.
201         //
202         // We use modular arithmetic throughout:
203         //
204         // 1. align is guaranteed to be > 0, so align - 1 is always
205         //    valid.
206         //
207         // 2. `len + align - 1` can overflow by at most `align - 1`,
208         //    so the &-mask with `!(align - 1)` will ensure that in the
209         //    case of overflow, `len_rounded_up` will itself be 0.
210         //    Thus the returned padding, when added to `len`, yields 0,
211         //    which trivially satisfies the alignment `align`.
212         //
213         // (Of course, attempts to allocate blocks of memory whose
214         // size and padding overflow in the above manner should cause
215         // the allocator to yield an error anyway.)
216
217         let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
218         len_rounded_up.wrapping_sub(len)
219     }
220
221     /// Creates a layout by rounding the size of this layout up to a multiple
222     /// of the layout's alignment.
223     ///
224     /// This is equivalent to adding the result of `padding_needed_for`
225     /// to the layout's current size.
226     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
227     #[inline]
228     pub fn pad_to_align(&self) -> Layout {
229         let pad = self.padding_needed_for(self.align());
230         // This cannot overflow. Quoting from the invariant of Layout:
231         // > `size`, when rounded up to the nearest multiple of `align`,
232         // > must not overflow (i.e., the rounded value must be less than
233         // > `usize::MAX`)
234         let new_size = self.size() + pad;
235
236         Layout::from_size_align(new_size, self.align()).unwrap()
237     }
238
239     /// Creates a layout describing the record for `n` instances of
240     /// `self`, with a suitable amount of padding between each to
241     /// ensure that each instance is given its requested size and
242     /// alignment. On success, returns `(k, offs)` where `k` is the
243     /// layout of the array and `offs` is the distance between the start
244     /// of each element in the array.
245     ///
246     /// On arithmetic overflow, returns `LayoutErr`.
247     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
248     #[inline]
249     pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
250         // This cannot overflow. Quoting from the invariant of Layout:
251         // > `size`, when rounded up to the nearest multiple of `align`,
252         // > must not overflow (i.e., the rounded value must be less than
253         // > `usize::MAX`)
254         let padded_size = self.size() + self.padding_needed_for(self.align());
255         let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
256
257         unsafe {
258             // self.align is already known to be valid and alloc_size has been
259             // padded already.
260             Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
261         }
262     }
263
264     /// Creates a layout describing the record for `self` followed by
265     /// `next`, including any necessary padding to ensure that `next`
266     /// will be properly aligned. Note that the resulting layout will
267     /// satisfy the alignment properties of both `self` and `next`.
268     ///
269     /// The resulting layout will be the same as that of a C struct containing
270     /// two fields with the layouts of `self` and `next`, in that order.
271     ///
272     /// Returns `Some((k, offset))`, where `k` is layout of the concatenated
273     /// record and `offset` is the relative location, in bytes, of the
274     /// start of the `next` embedded within the concatenated record
275     /// (assuming that the record itself starts at offset 0).
276     ///
277     /// On arithmetic overflow, returns `LayoutErr`.
278     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
279     #[inline]
280     pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
281         let new_align = cmp::max(self.align(), next.align());
282         let pad = self.padding_needed_for(next.align());
283
284         let offset = self.size().checked_add(pad).ok_or(LayoutErr { private: () })?;
285         let new_size = offset.checked_add(next.size()).ok_or(LayoutErr { private: () })?;
286
287         let layout = Layout::from_size_align(new_size, new_align)?;
288         Ok((layout, offset))
289     }
290
291     /// Creates a layout describing the record for `n` instances of
292     /// `self`, with no padding between each instance.
293     ///
294     /// Note that, unlike `repeat`, `repeat_packed` does not guarantee
295     /// that the repeated instances of `self` will be properly
296     /// aligned, even if a given instance of `self` is properly
297     /// aligned. In other words, if the layout returned by
298     /// `repeat_packed` is used to allocate an array, it is not
299     /// guaranteed that all elements in the array will be properly
300     /// aligned.
301     ///
302     /// On arithmetic overflow, returns `LayoutErr`.
303     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
304     #[inline]
305     pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
306         let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
307         Layout::from_size_align(size, self.align())
308     }
309
310     /// Creates a layout describing the record for `self` followed by
311     /// `next` with no additional padding between the two. Since no
312     /// padding is inserted, the alignment of `next` is irrelevant,
313     /// and is not incorporated *at all* into the resulting layout.
314     ///
315     /// On arithmetic overflow, returns `LayoutErr`.
316     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
317     #[inline]
318     pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
319         let new_size = self.size().checked_add(next.size()).ok_or(LayoutErr { private: () })?;
320         Layout::from_size_align(new_size, self.align())
321     }
322
323     /// Creates a layout describing the record for a `[T; n]`.
324     ///
325     /// On arithmetic overflow, returns `LayoutErr`.
326     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
327     #[inline]
328     pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
329         Layout::new::<T>().repeat(n).map(|(k, offs)| {
330             debug_assert!(offs == mem::size_of::<T>());
331             k
332         })
333     }
334 }
335
336 /// The parameters given to `Layout::from_size_align`
337 /// or some other `Layout` constructor
338 /// do not satisfy its documented constraints.
339 #[stable(feature = "alloc_layout", since = "1.28.0")]
340 #[derive(Clone, PartialEq, Eq, Debug)]
341 pub struct LayoutErr {
342     private: (),
343 }
344
345 // (we need this for downstream impl of trait Error)
346 #[stable(feature = "alloc_layout", since = "1.28.0")]
347 impl fmt::Display for LayoutErr {
348     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349         f.write_str("invalid parameters to Layout::from_size_align")
350     }
351 }
352
353 /// The `AllocErr` error indicates an allocation failure
354 /// that may be due to resource exhaustion or to
355 /// something wrong when combining the given input arguments with this
356 /// allocator.
357 #[unstable(feature = "allocator_api", issue = "32838")]
358 #[derive(Clone, PartialEq, Eq, Debug)]
359 pub struct AllocErr;
360
361 // (we need this for downstream impl of trait Error)
362 #[unstable(feature = "allocator_api", issue = "32838")]
363 impl fmt::Display for AllocErr {
364     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
365         f.write_str("memory allocation failed")
366     }
367 }
368
369 /// The `CannotReallocInPlace` error is used when [`grow_in_place`] or
370 /// [`shrink_in_place`] were unable to reuse the given memory block for
371 /// a requested layout.
372 ///
373 /// [`grow_in_place`]: ./trait.AllocRef.html#method.grow_in_place
374 /// [`shrink_in_place`]: ./trait.AllocRef.html#method.shrink_in_place
375 #[unstable(feature = "allocator_api", issue = "32838")]
376 #[derive(Clone, PartialEq, Eq, Debug)]
377 pub struct CannotReallocInPlace;
378
379 #[unstable(feature = "allocator_api", issue = "32838")]
380 impl CannotReallocInPlace {
381     pub fn description(&self) -> &str {
382         "cannot reallocate allocator's memory in place"
383     }
384 }
385
386 // (we need this for downstream impl of trait Error)
387 #[unstable(feature = "allocator_api", issue = "32838")]
388 impl fmt::Display for CannotReallocInPlace {
389     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
390         write!(f, "{}", self.description())
391     }
392 }
393
394 /// A memory allocator that can be registered as the standard library’s default
395 /// through the `#[global_allocator]` attribute.
396 ///
397 /// Some of the methods require that a memory block be *currently
398 /// allocated* via an allocator. This means that:
399 ///
400 /// * the starting address for that memory block was previously
401 ///   returned by a previous call to an allocation method
402 ///   such as `alloc`, and
403 ///
404 /// * the memory block has not been subsequently deallocated, where
405 ///   blocks are deallocated either by being passed to a deallocation
406 ///   method such as `dealloc` or by being
407 ///   passed to a reallocation method that returns a non-null pointer.
408 ///
409 ///
410 /// # Example
411 ///
412 /// ```no_run
413 /// use std::alloc::{GlobalAlloc, Layout, alloc};
414 /// use std::ptr::null_mut;
415 ///
416 /// struct MyAllocator;
417 ///
418 /// unsafe impl GlobalAlloc for MyAllocator {
419 ///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
420 ///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
421 /// }
422 ///
423 /// #[global_allocator]
424 /// static A: MyAllocator = MyAllocator;
425 ///
426 /// fn main() {
427 ///     unsafe {
428 ///         assert!(alloc(Layout::new::<u32>()).is_null())
429 ///     }
430 /// }
431 /// ```
432 ///
433 /// # Safety
434 ///
435 /// The `GlobalAlloc` trait is an `unsafe` trait for a number of reasons, and
436 /// implementors must ensure that they adhere to these contracts:
437 ///
438 /// * It's undefined behavior if global allocators unwind. This restriction may
439 ///   be lifted in the future, but currently a panic from any of these
440 ///   functions may lead to memory unsafety.
441 ///
442 /// * `Layout` queries and calculations in general must be correct. Callers of
443 ///   this trait are allowed to rely on the contracts defined on each method,
444 ///   and implementors must ensure such contracts remain true.
445 #[stable(feature = "global_alloc", since = "1.28.0")]
446 pub unsafe trait GlobalAlloc {
447     /// Allocate memory as described by the given `layout`.
448     ///
449     /// Returns a pointer to newly-allocated memory,
450     /// or null to indicate allocation failure.
451     ///
452     /// # Safety
453     ///
454     /// This function is unsafe because undefined behavior can result
455     /// if the caller does not ensure that `layout` has non-zero size.
456     ///
457     /// (Extension subtraits might provide more specific bounds on
458     /// behavior, e.g., guarantee a sentinel address or a null pointer
459     /// in response to a zero-size allocation request.)
460     ///
461     /// The allocated block of memory may or may not be initialized.
462     ///
463     /// # Errors
464     ///
465     /// Returning a null pointer indicates that either memory is exhausted
466     /// or `layout` does not meet this allocator's size or alignment constraints.
467     ///
468     /// Implementations are encouraged to return null on memory
469     /// exhaustion rather than aborting, but this is not
470     /// a strict requirement. (Specifically: it is *legal* to
471     /// implement this trait atop an underlying native allocation
472     /// library that aborts on memory exhaustion.)
473     ///
474     /// Clients wishing to abort computation in response to an
475     /// allocation error are encouraged to call the [`handle_alloc_error`] function,
476     /// rather than directly invoking `panic!` or similar.
477     ///
478     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
479     #[stable(feature = "global_alloc", since = "1.28.0")]
480     unsafe fn alloc(&self, layout: Layout) -> *mut u8;
481
482     /// Deallocate the block of memory at the given `ptr` pointer with the given `layout`.
483     ///
484     /// # Safety
485     ///
486     /// This function is unsafe because undefined behavior can result
487     /// if the caller does not ensure all of the following:
488     ///
489     /// * `ptr` must denote a block of memory currently allocated via
490     ///   this allocator,
491     ///
492     /// * `layout` must be the same layout that was used
493     ///   to allocate that block of memory,
494     #[stable(feature = "global_alloc", since = "1.28.0")]
495     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
496
497     /// Behaves like `alloc`, but also ensures that the contents
498     /// are set to zero before being returned.
499     ///
500     /// # Safety
501     ///
502     /// This function is unsafe for the same reasons that `alloc` is.
503     /// However the allocated block of memory is guaranteed to be initialized.
504     ///
505     /// # Errors
506     ///
507     /// Returning a null pointer indicates that either memory is exhausted
508     /// or `layout` does not meet allocator's size or alignment constraints,
509     /// just as in `alloc`.
510     ///
511     /// Clients wishing to abort computation in response to an
512     /// allocation error are encouraged to call the [`handle_alloc_error`] function,
513     /// rather than directly invoking `panic!` or similar.
514     ///
515     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
516     #[stable(feature = "global_alloc", since = "1.28.0")]
517     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
518         let size = layout.size();
519         let ptr = self.alloc(layout);
520         if !ptr.is_null() {
521             ptr::write_bytes(ptr, 0, size);
522         }
523         ptr
524     }
525
526     /// Shrink or grow a block of memory to the given `new_size`.
527     /// The block is described by the given `ptr` pointer and `layout`.
528     ///
529     /// If this returns a non-null pointer, then ownership of the memory block
530     /// referenced by `ptr` has been transferred to this allocator.
531     /// The memory may or may not have been deallocated,
532     /// and should be considered unusable (unless of course it was
533     /// transferred back to the caller again via the return value of
534     /// this method). The new memory block is allocated with `layout`, but
535     /// with the `size` updated to `new_size`.
536     ///
537     /// If this method returns null, then ownership of the memory
538     /// block has not been transferred to this allocator, and the
539     /// contents of the memory block are unaltered.
540     ///
541     /// # Safety
542     ///
543     /// This function is unsafe because undefined behavior can result
544     /// if the caller does not ensure all of the following:
545     ///
546     /// * `ptr` must be currently allocated via this allocator,
547     ///
548     /// * `layout` must be the same layout that was used
549     ///   to allocate that block of memory,
550     ///
551     /// * `new_size` must be greater than zero.
552     ///
553     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
554     ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
555     ///
556     /// (Extension subtraits might provide more specific bounds on
557     /// behavior, e.g., guarantee a sentinel address or a null pointer
558     /// in response to a zero-size allocation request.)
559     ///
560     /// # Errors
561     ///
562     /// Returns null if the new layout does not meet the size
563     /// and alignment constraints of the allocator, or if reallocation
564     /// otherwise fails.
565     ///
566     /// Implementations are encouraged to return null on memory
567     /// exhaustion rather than panicking or aborting, but this is not
568     /// a strict requirement. (Specifically: it is *legal* to
569     /// implement this trait atop an underlying native allocation
570     /// library that aborts on memory exhaustion.)
571     ///
572     /// Clients wishing to abort computation in response to a
573     /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
574     /// rather than directly invoking `panic!` or similar.
575     ///
576     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
577     #[stable(feature = "global_alloc", since = "1.28.0")]
578     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
579         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
580         let new_ptr = self.alloc(new_layout);
581         if !new_ptr.is_null() {
582             ptr::copy_nonoverlapping(ptr, new_ptr, cmp::min(layout.size(), new_size));
583             self.dealloc(ptr, layout);
584         }
585         new_ptr
586     }
587 }
588
589 /// An implementation of `AllocRef` can allocate, reallocate, and
590 /// deallocate arbitrary blocks of data described via `Layout`.
591 ///
592 /// `AllocRef` is designed to be implemented on ZSTs, references, or
593 /// smart pointers because having an allocator like `MyAlloc([u8; N])`
594 /// cannot be moved, without updating the pointers to the allocated
595 /// memory.
596 ///
597 /// Some of the methods require that a memory block be *currently
598 /// allocated* via an allocator. This means that:
599 ///
600 /// * the starting address for that memory block was previously
601 ///   returned by a previous call to an allocation method (`alloc`,
602 ///   `alloc_zeroed`) or reallocation method (`realloc`), and
603 ///
604 /// * the memory block has not been subsequently deallocated, where
605 ///   blocks are deallocated either by being passed to a deallocation
606 ///   method (`dealloc`) or by being passed to a reallocation method
607 ///  (see above) that returns `Ok`.
608 ///
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>`.
614 ///
615 /// Some of the methods require that a layout *fit* a memory block.
616 /// What it means for a layout to "fit" a memory block means (or
617 /// equivalently, for a memory block to "fit" a layout) is that the
618 /// following two conditions must hold:
619 ///
620 /// 1. The block's starting address must be aligned to `layout.align()`.
621 ///
622 /// 2. The block's size must fall in the range `[use_min, use_max]`, where:
623 ///
624 ///    * `use_min` is `layout.size()`, and
625 ///
626 ///    * `use_max` is the capacity that was returned.
627 ///
628 /// Note that:
629 ///
630 ///  * the size of the layout most recently used to allocate the block
631 ///    is guaranteed to be in the range `[use_min, use_max]`, and
632 ///
633 ///  * a lower-bound on `use_max` can be safely approximated by a call to
634 ///    `usable_size`.
635 ///
636 ///  * if a layout `k` fits a memory block (denoted by `ptr`)
637 ///    currently allocated via an allocator `a`, then it is legal to
638 ///    use that layout to deallocate it, i.e., `a.dealloc(ptr, k);`.
639 ///
640 ///  * if an allocator does not support overallocating, it is fine to
641 ///    simply return `layout.size()` as the allocated size.
642 ///
643 /// [`GlobalAlloc`]: self::GlobalAlloc
644 /// [`Layout::dangling()`]: self::Layout::dangling
645 ///
646 /// # Safety
647 ///
648 /// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and
649 /// implementors must ensure that they adhere to these contracts:
650 ///
651 /// * Pointers returned from allocation functions must point to valid memory and
652 ///   retain their validity until at least one instance of `AllocRef` is dropped
653 ///   itself.
654 ///
655 /// * Cloning or moving the allocator must not invalidate pointers returned
656 ///   from this allocator. Cloning must return a reference to the same allocator.
657 ///
658 /// * `Layout` queries and calculations in general must be correct. Callers of
659 ///   this trait are allowed to rely on the contracts defined on each method,
660 ///   and implementors must ensure such contracts remain true.
661 ///
662 /// Note that this list may get tweaked over time as clarifications are made in
663 /// the future.
664 #[unstable(feature = "allocator_api", issue = "32838")]
665 pub unsafe trait AllocRef {
666     /// On success, returns a pointer meeting the size and alignment
667     /// guarantees of `layout` and the actual size of the allocated block,
668     /// which must be greater than or equal to `layout.size()`.
669     ///
670     /// If this method returns an `Ok(addr)`, then the `addr` returned
671     /// will be non-null address pointing to a block of storage
672     /// suitable for holding an instance of `layout`.
673     ///
674     /// The returned block of storage may or may not have its contents
675     /// initialized. (Extension subtraits might restrict this
676     /// behavior, e.g., to ensure initialization to particular sets of
677     /// bit patterns.)
678     ///
679     /// # Errors
680     ///
681     /// Returning `Err` indicates that either memory is exhausted or
682     /// `layout` does not meet allocator's size or alignment
683     /// constraints.
684     ///
685     /// Implementations are encouraged to return `Err` on memory
686     /// exhaustion rather than panicking or aborting, but this is not
687     /// a strict requirement. (Specifically: it is *legal* to
688     /// implement this trait atop an underlying native allocation
689     /// library that aborts on memory exhaustion.)
690     ///
691     /// Clients wishing to abort computation in response to an
692     /// allocation error are encouraged to call the [`handle_alloc_error`] function,
693     /// rather than directly invoking `panic!` or similar.
694     ///
695     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
696     fn alloc(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr>;
697
698     /// Deallocate the memory referenced by `ptr`.
699     ///
700     /// # Safety
701     ///
702     /// This function is unsafe because undefined behavior can result
703     /// if the caller does not ensure all of the following:
704     ///
705     /// * `ptr` must denote a block of memory currently allocated via
706     ///   this allocator,
707     ///
708     /// * `layout` must *fit* that block of memory,
709     ///
710     /// * In addition to fitting the block of memory `layout`, the
711     ///   alignment of the `layout` must match the alignment used
712     ///   to allocate that block of memory.
713     unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
714
715     /// Behaves like `alloc`, but also ensures that the contents
716     /// are set to zero before being returned.
717     ///
718     /// # Errors
719     ///
720     /// Returning `Err` indicates that either memory is exhausted or
721     /// `layout` does not meet allocator's size or alignment
722     /// constraints, just as in `alloc`.
723     ///
724     /// Clients wishing to abort computation in response to an
725     /// allocation error are encouraged to call the [`handle_alloc_error`] function,
726     /// rather than directly invoking `panic!` or similar.
727     ///
728     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
729     fn alloc_zeroed(&mut self, layout: Layout) -> Result<(NonNull<u8>, usize), AllocErr> {
730         let size = layout.size();
731         let result = self.alloc(layout);
732         if let Ok((p, _)) = result {
733             unsafe { ptr::write_bytes(p.as_ptr(), 0, size) }
734         }
735         result
736     }
737
738     // == METHODS FOR MEMORY REUSE ==
739     // realloc, realloc_zeroed, grow_in_place, grow_in_place_zeroed, shrink_in_place
740
741     /// Returns a pointer suitable for holding data described by
742     /// a new layout with `layout`’s alignment and a size given
743     /// by `new_size` and the actual size of the allocated block.
744     /// The latter is greater than or equal to `layout.size()`.
745     /// To accomplish this, the allocator may extend or shrink
746     /// the allocation referenced by `ptr` to fit the new layout.
747     ///
748     /// If this returns `Ok`, then ownership of the memory block
749     /// referenced by `ptr` has been transferred to this
750     /// allocator. The memory may or may not have been freed, and
751     /// should be considered unusable (unless of course it was
752     /// transferred back to the caller again via the return value of
753     /// this method).
754     ///
755     /// If this method returns `Err`, then ownership of the memory
756     /// block has not been transferred to this allocator, and the
757     /// contents of the memory block are unaltered.
758     ///
759     /// # Safety
760     ///
761     /// This function is unsafe because undefined behavior can result
762     /// if the caller does not ensure all of the following:
763     ///
764     /// * `ptr` must be currently allocated via this allocator,
765     ///
766     /// * `layout` must *fit* the `ptr` (see above). (The `new_size`
767     ///   argument need not fit it.)
768     ///
769     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
770     ///   must not overflow (i.e., the rounded value must be less than `usize::MAX`).
771     ///
772     /// (Extension subtraits might provide more specific bounds on
773     /// behavior, e.g., guarantee a sentinel address or a null pointer
774     /// in response to a zero-size allocation request.)
775     ///
776     /// # Errors
777     ///
778     /// Returns `Err` only if the new layout
779     /// does not meet the allocator's size
780     /// and alignment constraints of the allocator, or if reallocation
781     /// otherwise fails.
782     ///
783     /// Implementations are encouraged to return `Err` on memory
784     /// exhaustion rather than panicking or aborting, but this is not
785     /// a strict requirement. (Specifically: it is *legal* to
786     /// implement this trait atop an underlying native allocation
787     /// library that aborts on memory exhaustion.)
788     ///
789     /// Clients wishing to abort computation in response to a
790     /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
791     /// rather than directly invoking `panic!` or similar.
792     ///
793     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
794     unsafe fn realloc(
795         &mut self,
796         ptr: NonNull<u8>,
797         layout: Layout,
798         new_size: usize,
799     ) -> Result<(NonNull<u8>, usize), AllocErr> {
800         let old_size = layout.size();
801
802         if new_size > old_size {
803             if let Ok(size) = self.grow_in_place(ptr, layout, new_size) {
804                 return Ok((ptr, size));
805             }
806         } else if new_size < old_size {
807             if let Ok(size) = self.shrink_in_place(ptr, layout, new_size) {
808                 return Ok((ptr, size));
809             }
810         } else {
811             return Ok((ptr, new_size));
812         }
813
814         // otherwise, fall back on alloc + copy + dealloc.
815         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
816         let result = self.alloc(new_layout);
817         if let Ok((new_ptr, _)) = result {
818             ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size));
819             self.dealloc(ptr, layout);
820         }
821         result
822     }
823
824     /// Behaves like `realloc`, but also ensures that the new contents
825     /// are set to zero before being returned.
826     ///
827     /// # Safety
828     ///
829     /// This function is unsafe for the same reasons that `realloc` is.
830     ///
831     /// # Errors
832     ///
833     /// Returns `Err` only if the new layout
834     /// does not meet the allocator's size
835     /// and alignment constraints of the allocator, or if reallocation
836     /// otherwise fails.
837     ///
838     /// Implementations are encouraged to return `Err` on memory
839     /// exhaustion rather than panicking or aborting, but this is not
840     /// a strict requirement. (Specifically: it is *legal* to
841     /// implement this trait atop an underlying native allocation
842     /// library that aborts on memory exhaustion.)
843     ///
844     /// Clients wishing to abort computation in response to a
845     /// reallocation error are encouraged to call the [`handle_alloc_error`] function,
846     /// rather than directly invoking `panic!` or similar.
847     ///
848     /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
849     unsafe fn realloc_zeroed(
850         &mut self,
851         ptr: NonNull<u8>,
852         layout: Layout,
853         new_size: usize,
854     ) -> Result<(NonNull<u8>, usize), AllocErr> {
855         let old_size = layout.size();
856
857         if new_size > old_size {
858             if let Ok(size) = self.grow_in_place_zeroed(ptr, layout, new_size) {
859                 return Ok((ptr, size));
860             }
861         } else if new_size < old_size {
862             if let Ok(size) = self.shrink_in_place(ptr, layout, new_size) {
863                 return Ok((ptr, size));
864             }
865         } else {
866             return Ok((ptr, new_size));
867         }
868
869         // otherwise, fall back on alloc + copy + dealloc.
870         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
871         let result = self.alloc_zeroed(new_layout);
872         if let Ok((new_ptr, _)) = result {
873             ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size));
874             self.dealloc(ptr, layout);
875         }
876         result
877     }
878
879     /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
880     ///
881     /// If this returns `Ok`, then the allocator has asserted that the
882     /// memory block referenced by `ptr` now fits `new_size`, and thus can
883     /// be used to carry data of a layout of that size and same alignment as
884     /// `layout`. The returned value is the new size of the allocated block.
885     /// (The allocator is allowed to expend effort to accomplish this, such
886     /// as extending the memory block to include successor blocks, or virtual
887     /// memory tricks.)
888     ///
889     /// Regardless of what this method returns, ownership of the
890     /// memory block referenced by `ptr` has not been transferred, and
891     /// the contents of the memory block are unaltered.
892     ///
893     /// # Safety
894     ///
895     /// This function is unsafe because undefined behavior can result
896     /// if the caller does not ensure all of the following:
897     ///
898     /// * `ptr` must be currently allocated via this allocator,
899     ///
900     /// * `layout` must *fit* the `ptr` (see above); note the
901     ///   `new_size` argument need not fit it,
902     ///
903     /// * `new_size` must not be less than `layout.size()`,
904     ///
905     /// # Errors
906     ///
907     /// Returns `Err(CannotReallocInPlace)` when the allocator is
908     /// unable to assert that the memory block referenced by `ptr`
909     /// could fit `layout`.
910     ///
911     /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
912     /// function; clients are expected either to be able to recover from
913     /// `grow_in_place` failures without aborting, or to fall back on
914     /// another reallocation method before resorting to an abort.
915     #[inline]
916     unsafe fn grow_in_place(
917         &mut self,
918         ptr: NonNull<u8>,
919         layout: Layout,
920         new_size: usize,
921     ) -> Result<usize, CannotReallocInPlace> {
922         let _ = ptr;
923         let _ = layout;
924         let _ = new_size;
925         Err(CannotReallocInPlace)
926     }
927
928     /// Behaves like `grow_in_place`, but also ensures that the new
929     /// contents are set to zero before being returned.
930     ///
931     /// # Safety
932     ///
933     /// This function is unsafe for the same reasons that `grow_in_place` is.
934     ///
935     /// # Errors
936     ///
937     /// Returns `Err(CannotReallocInPlace)` when the allocator is
938     /// unable to assert that the memory block referenced by `ptr`
939     /// could fit `layout`.
940     ///
941     /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
942     /// function; clients are expected either to be able to recover from
943     /// `grow_in_place` failures without aborting, or to fall back on
944     /// another reallocation method before resorting to an abort.
945     unsafe fn grow_in_place_zeroed(
946         &mut self,
947         ptr: NonNull<u8>,
948         layout: Layout,
949         new_size: usize,
950     ) -> Result<usize, CannotReallocInPlace> {
951         let size = self.grow_in_place(ptr, layout, new_size)?;
952         ptr.as_ptr().add(layout.size()).write_bytes(0, new_size - layout.size());
953         Ok(size)
954     }
955
956     /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
957     ///
958     /// If this returns `Ok`, then the allocator has asserted that the
959     /// memory block referenced by `ptr` now fits `new_size`, and
960     /// thus can only be used to carry data of that smaller
961     /// layout. The returned value is the new size the allocated block.
962     /// (The allocator is allowed to take advantage of this,
963     /// carving off portions of the block for reuse elsewhere.) The
964     /// truncated contents of the block within the smaller layout are
965     /// unaltered, and ownership of block has not been transferred.
966     ///
967     /// If this returns `Err`, then the memory block is considered to
968     /// still represent the original (larger) `layout`. None of the
969     /// block has been carved off for reuse elsewhere, ownership of
970     /// the memory block has not been transferred, and the contents of
971     /// the memory block are unaltered.
972     ///
973     /// # Safety
974     ///
975     /// This function is unsafe because undefined behavior can result
976     /// if the caller does not ensure all of the following:
977     ///
978     /// * `ptr` must be currently allocated via this allocator,
979     ///
980     /// * `layout` must *fit* the `ptr` (see above); note the
981     ///   `new_size` argument need not fit it,
982     ///
983     /// * `new_size` must not be greater than `layout.size()`,
984     ///
985     /// # Errors
986     ///
987     /// Returns `Err(CannotReallocInPlace)` when the allocator is
988     /// unable to assert that the memory block referenced by `ptr`
989     /// could fit `layout`.
990     ///
991     /// Note that one cannot pass `CannotReallocInPlace` to the `handle_alloc_error`
992     /// function; clients are expected either to be able to recover from
993     /// `shrink_in_place` failures without aborting, or to fall back
994     /// on another reallocation method before resorting to an abort.
995     #[inline]
996     unsafe fn shrink_in_place(
997         &mut self,
998         ptr: NonNull<u8>,
999         layout: Layout,
1000         new_size: usize,
1001     ) -> Result<usize, CannotReallocInPlace> {
1002         let _ = ptr;
1003         let _ = layout;
1004         let _ = new_size;
1005         Err(CannotReallocInPlace)
1006     }
1007 }