alloc_traits/
local.rs

1use core::fmt;
2use core::marker::PhantomData;
3use core::ptr::NonNull;
4
5use crate::NonZeroLayout;
6use crate::util::defaults;
7
8/// A marker struct denoting a lifetime that is not simply coercible to another.
9#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
10pub struct AllocTime<'lt> {
11    marker: PhantomData<&'lt fn(&'lt ())>,
12}
13
14/// A marker struct denoting a lifetime that is not simply coercible to another.
15#[deprecated = "Use the new name 'AllocTime' instead"]
16pub type Invariant<'lt> = AllocTime<'lt>;
17
18/// An allocation valid for a particular lifetime.
19///
20/// It is advisable to try and deallocate it before the end of the lifetime instead of leaking the
21/// allocation.
22#[derive(Clone, Copy, Debug, PartialEq)]
23pub struct Allocation<'alloc> {
24    /// A pointer to the allocated and potentially uninitialized bytes.
25    pub ptr: NonNull<u8>,
26    /// The allocated layout.
27    pub layout: NonZeroLayout,
28    /// The lifetime of the allocation.
29    pub lifetime: AllocTime<'alloc>,
30}
31
32/// An allocator providing memory regions valid for a particular lifetime.
33///
34/// It is useful to compare this trait to `std::alloc::GlobalAlloc`. Similar to the trait it is
35/// required that the implementors adhere to the contract of the methods.
36pub unsafe trait LocalAlloc<'alloc> {
37    /// Allocate one block of memory.
38    ///
39    /// The callee guarantees that a successful return contains a pointer that is valid for **at
40    /// least** the layout requested by the caller.
41    fn alloc(&'alloc self, layout: NonZeroLayout) -> Option<Allocation<'alloc>>;
42
43    /// Deallocate a block previously allocated.
44    /// # Safety
45    /// The caller must ensure that:
46    /// * `alloc` has been previously returned from a call to `alloc`.
47    /// * There are no more pointer to the allocation.
48    unsafe fn dealloc(&'alloc self, alloc: Allocation<'alloc>);
49
50    /// Allocate a block of memory initialized with zeros.
51    ///
52    /// The callee guarantees that a successful return contains a pointer that is valid for **at
53    /// least** the layout requested by the caller and the contiguous region of bytes, starting at
54    /// the pointer and with the size of the returned layout, is initialized and zeroed.
55    fn alloc_zeroed(&'alloc self, layout: NonZeroLayout)
56        -> Option<Allocation<'alloc>> 
57    {
58        defaults::local::alloc_zeroed(self, layout)
59    }
60
61    /// Change the layout of a block previously allocated.
62    ///
63    /// The callee guarantees that a successful return contains a pointer that is valid for **at
64    /// least** the layout requested by the caller and the contiguous region of bytes, starting at
65    /// the pointer and with the size of the returned layout, is initialized with the prefix of the
66    /// previous allocation that is still valid.
67    ///
68    /// Note that it is *NOT* safe to elide the methods call for changing the alignment of the
69    /// layout to a less strict one, or to an incidentally fulfilled stricter version. The
70    /// allocator might make use of the alignment during deallocation.
71    unsafe fn realloc(&'alloc self, alloc: Allocation<'alloc>, layout: NonZeroLayout)
72        -> Option<Allocation<'alloc>>
73    {
74        defaults::local::realloc(self, alloc, layout)
75    }
76}
77
78impl fmt::Debug for AllocTime<'_> {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        f.pad("AllocTime")
81    }
82}