Skip to content

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

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

Activity

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

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