Skip to content

Returning the result of reborrowing in pattern matching causes compilation error #92038

@WaffleLapkin

Description

@WaffleLapkin

This fails to compile on latest stable (and nightly) (playground):

fn f(a: &mut [u8]) -> &mut [u8] {
    match a {
        [b @ ..] if false => b,
        aa => aa,
    }
}
error[E0505]: cannot move out of `a` because it is borrowed
 --> src/main.rs:6:9
  |
3 |   fn f(a: &mut [u8]) -> &mut [u8] {
  |           - let's call the lifetime of this reference `'1`
4 | /     match a {
5 | |         [b @ ..] if false => b,
  | |          ------ borrow of `a[..]` occurs here
6 | |         aa => aa,
  | |         ^^ move out of `a` occurs here
7 | |     }
  | |_____- returning this value requires that `a[..]` is borrowed for `'1`

This seems like a bug in rustc, especially considering that any of the following are compiling just fine (playground):

fn f1(a: &mut [u8]) -> &mut [u8] {
    match a {
        b if false => b,
        aa => aa,
    }
}

fn f2(a: &mut [u8]) -> &mut [u8] {
    match a {
        b if false => b,
        [aa @ ..] => aa,
    }
}

fn f3(a: &mut [u8]) -> &mut [u8] {
    match a {
        [..] if false => a,
        [aa @ ..] => aa,
    }
}

Originally I've found this bug with code like this (playground):

fn original(a: &mut [u8]) -> &mut [u8] {
    match a {
        [.., b] if false => core::slice::from_mut(b),
        [aa @ ..] => aa,
        //^ cannot borrow `a[..]` as mutable more than once at a time
    }
}

Meta

rustc

  • stable: 1.57.0
  • nightly: 1.59.0-nightly (2021-12-13 8f117a77d0880ed59afc)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.D-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamfixed-by-poloniusCompiling with `-Zpolonius` fixes this issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions