Skip to content

if/while Some(n) = &mut foo sugar will leak a temporary mutable borrow to current scope in particular situation #62013

@CGQAQ

Description

@CGQAQ

Same Code in the Playground

pub struct Demo {
    foo: Option<Box<Demo>>,
}

// Compiles
pub fn foo1(mut a: &mut Demo) {
    if let Some(ref mut b) = a.foo {
        a = b;
    }
    a.foo = None;
}

// Does not compile
pub fn foo2(mut a: &mut Demo) {
    if let Some(b) = &mut a.foo {
        a = b;
    }
    a.foo = None;
}

// Same Error with foo2
pub fn foo3(mut a: &mut Demo) {
    if let Some(ref mut b) = &mut a.foo {
        a = b;
    }
    a.foo = None;
}

What is exactly difference between foo1 and foo2

ADD: I think foo1 will desuger something like this:

pub fn foo1_desugered(mut a: &mut Demo) {
    match a.foo {
        Some(ref mut _1) => a = _1 ,
        None => ()
    }
    a.foo = None;
}

and foo2 will be like:

pub fn foo2_desugered(mut a: &mut Demo) {
    let mut _t1 = &mut a.foo;
    match _t1 {
        Some(_1) => a = _1 ,
        None => ()
    }
    a.foo = None;
}

ADD#2 And if I explicit add a scope:

// Does not compile
pub fn foo2(mut a: &mut Demo) {
    {
        if let Some(b) = &mut a.foo {
            a = b;
        }
    }
    a.foo = None;
}

pub fn foo2_desugered(mut a: &mut Demo) {
    {
        let mut _t1 = &mut a.foo;
        match _t1 {
            Some(_1) => a = _1 ,
            None => ()
        }
    }
    a.foo = None;
}

same error :(

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.T-compilerRelevant to the compiler 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