Mutable *slice like* parts

I have a handle from C and on this handle one can do some index operations [0...size]. Neither the handle nor the underlying C data structure is an array or contiguous. They are representations for some other contiguous memory but that memory cannot be de-referenced. So my input is something like this:

struct Heap
{
size: usize,
handle: *const void,
}

On the rust side I would like to have a slice like representation where I can mutably borrow into those index ranges. So i want to do some operation like heap[0..20] or heap.split_at(median) and as an output I'd like to have something like this:

struct HeapSlice
{
slice_start: usize,
slice_end: usize,
handle: *const void,
}

At all times I want the borrow-checker to validate that I give not away overlapping HeapSlice and HeapSlices should be slice-able themselves.

One solution would be to give out dummy memory of HeapSlices and [HeapSlice] over them. but I thought that there must be a better way without allocating dummy memory.

The compiler can't even guarantee this for normal arrays. It can't "see through" indexing or slicing, so when you index or slice something, it has to assume the result lets you access everything.

The best you can likely do is something like:

struct HeapSlice<'a> {
    heap: &'a Heap,
    start: usize,
    end: usize,
}

The lifetime ties each HeapSlice to the Heap it was derived from. If you want disjoint slices of the same Heap, you'll want to add a method like split_at_mut, which lets you take one slice and divide it in two.

Thank you very much!

You are referring to this behaviour, right: Splitting Borrows - The Rustonomicon
It is too bad that this does not work:

let a = &mut slice[2..4]
let b = &mut slice[0..1]

This would have been such elegant syntax. split_at_mut certainly works though.

Another Question: is there a way to remove the Heap structure and only have heap slice? I think it would be impossible to uniquely drop the c ptr when all splits go out of scope.

I don't think so. The Heap should own the resources, the HeapSlices should borrow from Heap. If you do that, you don't need to manage the slices going out of scope; the compiler will ensure a Heap outlives any slices derived from it.

1 Like