Skip to content

Too conservative lifetime check in match arm with if condition. #137878

Open
@sswybd

Description

@sswybd
#![allow(unused)]

enum Enum {
    A,
}

fn main() {
    let mut a = Some(Enum::A);
    match &mut a {
        _ if foo(&a) => (),
        _ => (),
    }  // example1: worked
    match &mut a {
        Some(_) if foo(&a) => (),
        _ => (),
    }  // example2: not worked
}
fn foo<T>(a: &T) -> bool {
    true
}

The above two examples are similar, but compilation can succeed only for the first, while the second one has the following error:

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:14:24
   |
13 |     match &mut a {
   |           ------ mutable borrow occurs here
14 |         Some(_) if foo(&a) => (),
   |                        ^^- mutable borrow later used here
   |                        |
   |                        immutable borrow occurs here

But the exclusive reference in Some(_) is indeed never used and this specific case at least should be acceptable. I think this is something related to non-lexical lifetime, yet it's a quite simple case to implement or correct in the lifetime checker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsA-patternsRelating to patterns and pattern matchingC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions