Skip to content

drop-checking is more permissive when patterns have guards #142057

Open
@dianne

Description

@dianne

When pattern bindings are lowered to MIR, they're dropped in reverse-order of declaration (with some caveats when or-patterns are involved). However, by-ref bindings are created eagerly before anything else if guards are present, so that they can be used in guards (#49870). Because that affects the order in which drops are scheduled, this difference is observable through the drop check (playground link):

struct Struct<T>(T);
impl<T> Drop for Struct<T> {
    fn drop(&mut self) {}
}

fn main() {
    // This is an error: `short1` is dead before `long1` is dropped.
    match (Struct(&&0), 1) {
        (mut long1, ref short1) => long1.0 = &short1,
    }
    // This is OK: `short2`'s storage is live until after `long2`'s drop runs.
    match (Struct(&&0), 1) {
        (mut long2, ref short2) if true => long2.0 = &short2,
        _ => unreachable!(),
    }
}

Related: #142056

cc @rust-lang/lang since if this needs fixing it'll involve changing what programs are allowed. I imagine that needs a T-lang decision?

@rustbot label: +T-compiler +T-lang +A-MIR

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.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