Skip to content

Aliasing: Does Vec own its contents? #85697

Closed
@vakaras

Description

@vakaras

(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:

  1. It looks very counter-intuitive because it is typically illegal to have active mutable references to a structure and to its part.
  2. 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 the Unique pointer that is used inside Vec?

cc @RalfJung @matklad

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions