Is it undefined behavior to create a mutable reference to an empty slice which lies within another slice with a live mutable reference?
Background: I'm writing an arena allocator for a specialized use case, and that allocator supports dynamically extending an allocation if that allocation is the last one in its memory chunk. This can lead to the following sequence of operations:
- alloc(8) which reserves 8 bytes starting at address, say, 0x1000, and returns a
&mut [u8]of length 8.
- alloc(0) which reserves 0 bytes and returns a
&mut [u8]of length 0.
- extend(0x1000, 4), which extends the allocation at 0x1000 by 4 bytes and returns a
&mut [u8]of length 12, still starting at address 0x1000 to avoid the memcpy.
Currently, the allocator uses
NonNull::dangling() for creating the zero-sized allocation in step 2, but I would like to remove that special case and just return a slice of length 0 starting at address 0x1008. That would mean that there are two live, mutables references to slices, one from 0x1000 to 0x100c, the other from 0x1008 to 0x1008. Would that be undefined behavior? I don't think so, because there is no memory that is accessible from different mutable references, but I'm not sure what the exact requirements are.