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}