1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Metadata traits common to all (de)allocators
use crate::*;
use crate*;
use Debug;
/// Allocator metadata (are ZSTs supported, max allocation size/alignment, error type, etc.)
/// Allocator supports zero-sized allocations. Implies Meta::ZST_SUPPORTED = true
/// Zero-sized allocations "should" always succeed.
///
/// ### Safety
/// Some code might rely on the presence of this trait to safely [`Result::unwrap_unchecked`] the result of:
/// * <code>[thin::Alloc::alloc_uninit]\(0\)</code>
/// * <code>[thin::Alloc::alloc_zeroed]\(0\)</code>
/// * <code>[thin::Realloc::realloc_uninit]\(ptr, 0\)</code>
/// * ~~<code>[thin::Realloc::realloc_zeroed]\(ptr, 0\)</code>~~ May fail anyways if <code>\![thin::Realloc::CAN_REALLOC_ZEROED]</code>
/// * <code>[fat::Alloc::alloc_uninit]\(layout\)</code> where `layout.size() == 0`
/// * <code>[fat::Alloc::alloc_zeroed]\(layout\)</code> where `layout.size() == 0`
/// * <code>[fat::Realloc::realloc_uninit]\(ptr, old_layout, new_layout\)</code> where `new_layout.size() == 0`
/// * <code>[fat::Realloc::realloc_zeroed]\(ptr, old_layout, new_layout\)</code> where `new_layout.size() == 0`
///
/// Note that these functions can still *panic* if:
/// * Passed bad pointers (e.g. to `Realloc::realloc_*`)
/// * Passed bad alignments (e.g. [`PanicOverAlign`](crate::allocator::adapt::PanicOverAlign))
/// * Interior heap corruption was detected
/// * ...
///
/// Although unless it's to report potential undefined behavior, this is at least discouraged.
pub unsafe
pub use ZstSupported as ZstInfalliableOrGlobalOomHandling;
pub use ZstInfalliable as ZstInfalliableOrGlobalOomHandling;
/// Independently constructed allocators are intercompatible.
///
/// Allocators constructed independently of each other (be that through [`Default`] or other means) will still be compatible with each other.
/// In other words, [`fat`] and [`thin`] traits can be used to allocate with one, reallocate with another, and free with a third.
/// While such [`Stateless`] allocators are typically ZSTs, they *don't* necessairly *have* to be - caching a reference or Arc or similar is allowed.
///
/// Implementing this trait also means that destroying `Self` can no longer invalidate existing allocations - they *must* remain alive until explicitly freed.
///
/// ### Safety
/// By implementing this trait for, say, `Malloc`, one would indicate that the following code is sound:
/// ```rust
/// use ialloc::allocator::c::Malloc;
/// use ialloc::thin::{Alloc, Free};
///
/// let alloc = Malloc::default().alloc_uninit(42).unwrap();
/// unsafe { Malloc::default().free(alloc) };
/// ```
/// Despite the fact that each call to `Malloc::default()` creates an entirely new independent instance of `Malloc`.
/// * [`fat`] traits should remain compatible with each other for different instaces of `Malloc`.
/// * [`thin`] traits should remain compatible with each other for different instaces of `Malloc`.
///
/// This is mainly used to gate the following functions, which are footguns in the presence of stateful allocators:
/// * [`boxed::ABox::from_raw`] (use [`boxed::ABox::from_raw_in`] instead)
/// * [`boxed::ABox::into_raw`] (use [`boxed::ABox::into_raw_with_allocator`] instead)
/// * [`vec::AVec::from_raw_parts`] (use [`vec::AVec::from_raw_parts_in`] instead)
/// * [`vec::AVec::into_raw_parts`] (use [`vec::AVec::into_raw_parts_with_allocator`] instead)
// FIXME: remove
pub unsafe