Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Last uses aren't moved into closures by default #1894

Closed
brson opened this issue Feb 23, 2012 · 3 comments
Closed

Last uses aren't moved into closures by default #1894

brson opened this issue Feb 23, 2012 · 3 comments

Comments

@brson
Copy link
Contributor

brson commented Feb 23, 2012

This fails:

fn main() {                                                                                                                                                    
    let x = ~1;                                                                                                                                                
    let x_in_parent = ptr::addr_of(*x) as uint;                                                                                                                
    let f = fn@() -> uint {                                                                                                                                    
        ptr::addr_of(*x) as uint                                                                                                                               
    };                                                                                                                                                         
    let x_in_child = f();                                                                                                                                      
    assert x_in_parent == x_in_child;                                                                                                                          
} 

Rewriting it with a capture clause works:

fn main() {                                                                                                                                                    
    let x = ~1;                                                                                                                                                
    let x_in_parent = ptr::addr_of(*x) as uint;                                                                                                                
    let f = fn@[move x]() -> uint {                                                                                                                                    
        ptr::addr_of(*x) as uint                                                                                                                               
    };                                                                                                                                                         
    let x_in_child = f();                                                                                                                                      
    assert x_in_parent == x_in_child;                                                                                                                          
}      

This is a bit surprising and makes spawn not do the expected thing when written with the convenient block closure syntax. For this reason core::task uses fn~ closures with explicit capture clauses.

@nikomatsakis
Copy link
Contributor

It occurs to me that the last use analysis might be doing the right thing (I don't know), but the trans code certainly is not. Right now, trans::closure decides whether to copy or move based purely on the capture clause. It shouldn't be a big deal to modify it to consult the last use table, but I'm not sure where to look (e.g., would the last use of the variable be the fn expr itself in this case?)

@nikomatsakis
Copy link
Contributor

@marijnh, you'd know best (see previous comment)

@marijnh
Copy link
Contributor

marijnh commented Feb 24, 2012

I initially punted on this because the act of closing over a variable doesn't have a node id associated with it the way regular mentions of a variable have. I agree it should be implemented. Assigning to myself.

marijnh added a commit that referenced this issue Mar 1, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants