Skip to content

Uninhabited types have strange borrow-checking behavior, even behind references #146590

@theemathas

Description

@theemathas

I'm not sure if this is a bug or not.

enum Never {}

fn works(x: &mut Result<Never, String>) {
    match x {
        &mut Ok(ref mut y) => match x {
            &mut Err(ref mut z) => {
                let _y = y;
                let _z = z;
            }
            _ => {}
        },
        _ => {}
    };
}

fn fails(x: &mut Result<String, String>) {
    match x {
        &mut Ok(ref mut y) => match x {
            &mut Err(ref mut z) => {
                let _y = y;
                let _z = z;
            }
            _ => {}
        },
        _ => {}
    };
}

I expected either both functions to compile or both functions to fail to compile. Instead, only the fails function gives the following error:

error[E0503]: cannot use `*x` because it was mutably borrowed
  --> src/lib.rs:18:37
   |
18 |         &mut Ok(ref mut y) => match x {
   |                 ---------           ^ use of borrowed `x.0`
   |                 |
   |                 `x.0` is borrowed here
19 |             &mut Err(ref mut z) => {
20 |                 let _y = y;
   |                          - borrow later used here

For more information about this error, try `rustc --explain E0503`.

In my understanding, whether &mut Never is uninhabited is undecided. Therefore, since I'm only creating references to Never (as opposed to actually creating Never values) I would think that I wouldn't get any special casing for uninhabited types. Thus, the current behavior seems wrong to me.

Meta

Reproducible on the playground with version 1.92.0-nightly (2025-09-14 52618eb338609df44978)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-exhaustiveness-checkingRelating to exhaustiveness / usefulness checking of patternsA-patternsRelating to patterns and pattern matchingC-bugCategory: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions