Skip to content

No way to get mutable reference to Vec member without expressing uniqueness over the full VecΒ #134507

Open
@orlp

Description

I've ran into the following standard library defect. There appears to be no possible sound way to go from a Vec<T> to a &mut T without expressing uniqueness over the full Vec. Vec::as_mut_ptr does not suffice because it takes a &mut self which expresses unique access over the full vec. A function which goes from *mut Vec<T> -> *mut T is necessary, but missing. The same is true for *mut [T] -> *mut T.


Consider the following example, where I have a v: Vec<Vec<u32>> where m.len() == n and m[i].len() == t for all i. I have t threads and I now want to process this array mutably in parallel, transposed. For example suppose I want to do the following in-place cumulative sum:

(0..t).into_par_iter().map(|thread_idx| {
    let mut cumsum = 0;
    for i in 0..n {
        // This obviously doesn't work, but you can't write this soundly with pointers either.
        let x: &mut u32 = &mut v[i][thread_idx];
        cumsum += *x;
        *x = cumsum;
    }
})

As far as I can tell, there is no way to write this soundly without introducing (potentially significant) overhead at all. The only way to write this soundly is to first create a temporary array of pointers and to modify the inner loop to use those pointers:

let ptrs: Vec<*mut u32> = v.iter_mut().map(|vi| vi.as_mut_ptr()).collect();
    // ...
        let x: &mut u32 = unsafe { &mut *ptrs[i].add(thread_idx) };
}

I really think the standard library should offer some kind of way to write this loop soundly without the unnecessary overhead of creating a pointer array. The simplest solution I think is to add functions which go from *mut Vec<T> -> *mut T and *mut [T] -> *mut T without creating an intermediate unique reference to the entire Vec or slice.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-collectionsArea: `std::collection`C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.needs-acpThis change is blocked on the author creating an ACP.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions