Skip to content

Replacing a parameter declared as mut a with let mut a = a; causes program to no longer compile #31723

Closed
@bstrie

Description

@bstrie

This may very well be a dupe of #31439, but it manifests somewhat differently and may shed light on the potential fix. Probably still worth having a test case for anyway.

Take this program, which compiles:

fn test_drain(mut a: Vec<u32>) -> Vec<u32> {
    a.drain(..).collect::<Vec<u32>>()
}

fn main() {}

Now, instead of declaring the parameter as mut a, declare it as immutable and rebind it as mutable in the body of the function, which is supposed to be semantically equivalent. This results in a compiler error:

fn test_drain(a: Vec<u32>) -> Vec<u32> {
    let mut a = a;
    a.drain(..).collect::<Vec<u32>>()
}

fn main() {}
<anon>:3:5: 3:6 error: `a` does not live long enough
<anon>:3     a.drain(..).collect::<Vec<u32>>()
             ^
<anon>:1:40: 4:2 note: reference must be valid for the destruction scope surrounding block at 1:39...
<anon>:1 fn test_drain(a: Vec<u32>) -> Vec<u32> {
<anon>:2     let mut a = a;
<anon>:3     a.drain(..).collect::<Vec<u32>>()
<anon>:4 }
<anon>:2:19: 4:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 2:18
<anon>:2     let mut a = a;
<anon>:3     a.drain(..).collect::<Vec<u32>>()
<anon>:4 }
error: aborting due to previous error
playpen: application terminated with error code 101

As in #31439, replacing the implicit return with an explicit return also allows the program to compile.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-destructorsArea: Destructors (`Drop`, …)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions