Description
(Opening a new issue to continue the discussion started in #60847.)
The core of the question is whether I can assume that x
and v
are disjoint (x
is not pointing into one of the v
's elements):
fn test(v: &mut Vec<u32>, x: &mut u32) {
// Can I assume here that x is not pointing to v?
}
I see at least two reasons why x
should not be allowed to alias an element of v
:
- It looks very counter-intuitive because it is typically illegal to have active mutable references to a structure and to its part.
- Taking into account how pervasive
Vec
is, this would likely kill most of the benefits for static analysis that Rust has against languages like C. The reason for this is that a sound tool (a static analyser or a verifier) would need to track whether any reference could potentially alias some element of a vector, which typically requires quantifiers. Unfortunately, using quantifiers typically leads to reasoning becoming undecidable. Not sure whether it is possible to somehow avoid the undecidability in this particular case, but scalability and performance will certainly be a huge problem.
At least one reason why aliasing should be allowed is given in the issue 60847. If I am not mistaken, that issue was motivated by this code in typed arena, which uses Vec
as a memory allocator. A variation of the code in the issue allows creating a reference that aliases the contents of the vector (playground):
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
v.pop();
let ptr = v.as_mut_ptr();
let ptr = unsafe { &mut *ptr };
test(&mut v, ptr);
println!("{:?}", v); // [8, 2, 3, 4, 7]
}
fn test(v: &mut Vec<u32>, x: &mut u32) {
assert!(v.len() < v.capacity());
v.push(7);
*x = 8;
}
My personal (highly biased) point of view is that it would be cleaner to separate the two use cases (vector as a collection of things and vector as a memory allocator) because it would allow the majority of Vec
users to not worry about potentially problematic aliasing. However, this would require having a new data structure that can be used as an allocator; maybe, RawVec
could be adopted for this?
If it is decided that the aliasing should not be allowed, then I have two additional questions:
- Does
Box
also give the same guarantee? - Is this non-aliasing property a property of
Vec
or a property of theUnique
pointer that is used insideVec
?