I am wondering if it is possible for the footprint of a &Cell<T> to grow such that it encompasses other simultaneously live Cells.
For example, let's say you have two shared references to Cells, one is of type &Cell<[i32]> and the other is of type &Cell<[i32; N]>. Let's also assume that both Cells point into the same original allocation, but the second cell points to the last N bytes and the length of the first slice is the <size of the original allocation> - N.
Would it be sound to modify the length of the slice pointed to by the first cell so that it encompasses the target of the second Cell?
I guess I have the same question generally of any instance of &UnsafeCell<T>.
This is not yet decided in rust. It is called "subobject provenance" as the provenance of the reference could only allow access to a part of the whole object.
It is also not special for UnsafeCells. I don't think they behave different from any other object in Rust.
I'm aware that you can create overlapping Cells, but what I'm wondering is if you can take two references to Cells which don't initially overlap and do something that causes them to overlap.
Would you happen to have an example? I'm struggling to come up with a way to change a Cell<[i32]> (from non-overlapping to overlapping), rather than creating a new (overlapping) Cell<[i32]>.
In my understanding, from my experience, and in general, once you've narrowed a reference's provenance to a certain span of bytes, it's no longer valid to derive a pointer to the original allocation from that reference. I ran into this when implementing my own allocation API. If you want to grow the original reference back to the full size, you'll need to keep around a pointer or reference with the original provenance.
Ah, but you can grow the reference to the full size if you have a pointer with the full provenance around? Do you happen to have a link to a place in your allocation API where this happens?
Yes, if you take a look at core::ptr::with_provenance. Edit: I hallucinated that. It's actually ptr.with_addr. However, if you have the original pointer around, you should be able to just use that pointer directly, no?
If you have a pointer with the full provenance around you are creating a new reference from that pointer, you are not "growing" the existing reference that had a smaller provenance