As the title says.
pub unsafe trait Allocator {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>;
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
}
The two required methods on an Allocator both take different pointer types, this seems weird to me. Why has that choice been made?
Furthermore, why are u8 and [u8] chosen at all? Why not just have NonNull<()> or NonNull<[()]> for both methods?
My understanding is that choosing [u8] or u8 is a fine idea because it has the least-strict layout requirements that can actually be allocated (since Layout requires align to be non-zero). But, I think requiring a cast every time could be a better design choice.
The allocator might over-allocate, and
NonNull<[u8]>is a fat pointer including length information.Why
u8rather than()? Not sure, but it probably reflects the idea that all memory is a bunch of bytes in the end. Also the fact that pointers to ZSTs are allowed to dangle might have something to do with it.