Non copyable values captured by fn~ closures can be copied #2828

Closed
msullivan opened this Issue Jul 7, 2012 · 4 comments

Comments

Projects
None yet
3 participants
Contributor

msullivan commented Jul 7, 2012

The following program compiles and runs and will run the destructor twice:

class non_copyable {
    let n: int;
    new() { self.n = 0; }
    drop { log(error, "running destructor"); }
}

fn main() {
    let x = non_copyable();

    let f = fn~() { assert x.n == 0; };
    let g = copy f;

    f(); g();
}
Contributor

nikomatsakis commented Jul 7, 2012

The problem is that send used to be a subset of copy. This was changed but it sounds like fn~ was changed inconsistently. If we moved over to the fn types with explicit bounds (fn:send vs fn:send copy) this would be solved.

@ghost ghost assigned catamorphism Nov 24, 2012

catamorphism added a commit that referenced this issue Dec 8, 2012

Contributor

catamorphism commented Dec 8, 2012

This appears to have fixed itself, hallelujah! In 8255aa1 I checked in the test case.

Contributor

nikomatsakis commented Dec 8, 2012

I don't think it's really fixed. If you modify the test case to include a "move" capture clause, it still reproduces:

struct NoCopy {
    n: int
}
fn NoCopy() -> NoCopy {
    NoCopy { n: 0 }
}

impl NoCopy: Drop {
    fn finalize(&self) {
        log(error, "running destructor");
    }
}

fn main() {
    let x = NoCopy();

    let f = fn~(move x) { assert x.n == 0; }; 
    let g = copy f; // <-- Error expected here

    f(); g();
}

The proper fix is the work on closure bounds I did not get to for 0.5!

@nikomatsakis nikomatsakis reopened this Dec 8, 2012

Contributor

catamorphism commented Dec 8, 2012

Oops! Bumping to 0.6, then.

bors added a commit that referenced this issue Feb 7, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment