Skip to content

Matches on &mut[] move the .. match & don't consider disjointness #8636

Closed
@huonw

Description

@huonw

I believe the following should work, since head and tail are disjoint, and tail is just taking a slice into v (this would mean that v is inaccessible while the result of mut_head_tail is kept around):

fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> {
    match v {
        [ref mut head, .. tail] => {
            Some((head, tail))
        }
        [] => None
    }

    /* // this works currently:
    if v.is_empty() {
        None
    } else {
        let (low, hi) = v.mut_split(1);
        Some((&mut low[0], hi))
    }
    */
}

fn main() {
    let mut v = ~[1,2,3,4];

    match mut_head_tail(v) {
        None => {},
        Some((h,t)) => {
            *h = 1000;
            t.reverse();
        }
    }

    println!("{:?}", v);
}
mut-vec-match.rs:3:26: 3:30 error: cannot bind by-move and by-ref in the same pattern
mut-vec-match.rs:3         [ref mut head, .. tail] => {
                                             ^~~~
mut-vec-match.rs:3:9: 3:21 note: by-ref binding occurs here
mut-vec-match.rs:3         [ref mut head, .. tail] => {
                            ^~~~~~~~~~~~
error: aborting due to previous error

Changing it to (and removing the t.reverse()):

fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, ())> {
    match v {
        [ref mut head, .. ref mut _tail] => {
            Some((head, ()))
        }
        [] => None
    }
}
mut-vec-match.rs:21:9: 21:21 error: cannot borrow `(*v)[]` as mutable more than once at a time
mut-vec-match.rs:21         [ref mut head, .. ref mut _tail] => {
                             ^~~~~~~~~~~~
mut-vec-match.rs:21:8: 21:40 note: second borrow of `(*v)[]` as mutable occurs here
mut-vec-match.rs:21         [ref mut head, .. ref mut _tail] => {
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-enhancementCategory: An issue proposing an enhancement or a PR with one.fixed-by-NLLBugs fixed, but only when NLL is enabled.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions