Matches on &mut[] move the .. match & don't consider disjointness · Issue #8636 · rust-lang/rust (original) (raw)

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