Skip to content

Uplifting captures to by-move is too conservative #30745

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
nagisa opened this issue Jan 6, 2016 · 3 comments
Closed

Uplifting captures to by-move is too conservative #30745

nagisa opened this issue Jan 6, 2016 · 3 comments
Labels
A-closures Area: Closures (`|…| { … }`)

Comments

@nagisa
Copy link
Member

nagisa commented Jan 6, 2016

In code like this there’s some algorithm in place which makes the capture of variable x by-value rather than the default by-ref:

fn main(){
    let x = Some(vec![0]);
    (||{ 
        drop(x); // takes `x` by-value, therefore closure captures `x` by-value as well.
    })()
}

However, x will not be captured by-value when the x is matched on in a moving manner:

fn main() {
    let x = Some(vec![0]);
    (|| {
        match x { // cannot move out of captured outer variable in an `Fn` closure [E0507]
            Some(x) => {}, // attempting to move value to here
            None => {}
        }
    })()
}

It would be nice if the algorithm handled more cases (including one presented here).

@huonw huonw added the A-closures Area: Closures (`|…| { … }`) label Jan 7, 2016
@solson
Copy link
Member

solson commented Jan 7, 2016

A similar test case without enums:

fn main(){
    let x = (vec![0],);
    (|| { 
        drop(x); // takes `x` by-value, therefore closure captures `x` by-value as well.
    })()
}
fn main(){
    let x = (vec![0],);
    (|| { 
        drop(x.0); // cannot move out of captured outer variable in an `Fn` closure [E0507]
    })()
}

Basically, as far as I can tell, the capture inference doesn't see drop(x.0) as a by-value use of x and so captures x by-ref. I think this is the same problem in @nagisa's examples, where matching x and extracting the contents in the Some case is also like accessing a subfield. (It's like (x as Some).0 in MIR-like syntax.)

@nagisa
Copy link
Member Author

nagisa commented Jan 29, 2016

cc #30046? Might be a duplicate.

@Mark-Simulacrum
Copy link
Member

Closing as duplicate of #30046.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-closures Area: Closures (`|…| { … }`)
Projects
None yet
Development

No branches or pull requests

4 participants