Skip to content

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

Open
@orlp

Description

@orlp

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-collectionsArea: `std::collections`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