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

Missing drop in FnOnce adapter for closures #29946

Closed
eefriedman opened this issue Nov 20, 2015 · 12 comments
Closed

Missing drop in FnOnce adapter for closures #29946

eefriedman opened this issue Nov 20, 2015 · 12 comments
Assignees
Labels
A-destructors Area: Destructors (`Drop`, …) P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@eefriedman
Copy link
Contributor

struct Foo(i32);
impl Foo {
    pub fn dowork(&self) {
        println!("foo: doing work {}", self.0);
    }
}

impl Drop for Foo {
    fn drop(&mut self) {
        println!("foo: drop {}", self.0);
    }
}

fn f<T: FnOnce()>(t: T) {
    t()
}

fn main() {
    let x = Foo(1);
    let x = move || x.dowork();
    f(x);
}

playpen

Somehow, the Foo object leaks: my guess is that it has something to do with the way we generate code for the FnOnce() trait for closures which also implement Fn().

Originally reported at #28796 (comment) .

@Manishearth Manishearth added the A-destructors Area: Destructors (`Drop`, …) label Nov 22, 2015
@Manishearth
Copy link
Member

cc @pnkfelix

I think I've seen this before, happens with other traits as well.

@eddyb eddyb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 22, 2015
@pnkfelix pnkfelix self-assigned this Dec 3, 2015
@arielb1 arielb1 added the I-wrong label Dec 3, 2015
@nikomatsakis
Copy link
Contributor

triage: P-medium

1 similar comment
@nikomatsakis
Copy link
Contributor

triage: P-medium

@dotdash dotdash added the P-medium Medium priority label Dec 17, 2015
@rust-highfive rust-highfive added P-medium Medium priority and removed I-nominated P-medium Medium priority labels Dec 17, 2015
@thepowersgang
Copy link
Contributor

This appears to only happen if 1. the closure is called via a generic function, and 2. the captured variable is not explicitly moved into the closure body.

If "let a = x;" is used in place of calling a borrowing method, the destructor is called.

@thepowersgang
Copy link
Contributor

Preliminary investigation - The cause is from the closure not being treated as FnOnce when destructor calls are added to the "body" (in rustc_trans/trans/closure.rs load_closure_environment)

This is exposed when the closure is explicitly called as FnOnce (leading to ownership transfer into the closure, and hence no destructor being called).

Routes to fixing:

  1. Alter ClosureKind determining to take into account usage
  2. Insert a checked destructor invocation after calling a FnOnce closure (and let the drop flags prevent double-drop for working cases)
  3. (Unknown if possible) When a Fn/FnMut closure is called as a FnOnce, explicitly drop after calling (in the call_once "method").

@thepowersgang
Copy link
Contributor

::rustc_trans::trans::closure::trans_fn_once_adapter_shim exists, and is possibly the culprit.

@arielb1
Copy link
Contributor

arielb1 commented Feb 7, 2016

I don't think the shim is used here.

@thepowersgang
Copy link
Contributor

I'm reasonably sure it is. It is being run, and registers self to be dropped, but cleans up the scope without generating destructor calls

@thepowersgang
Copy link
Contributor

src/librustc_trans/trans/closure.rs#L424 appears to be the culprit, changing that line from

fcx.pop_custom_cleanup_scope(self_scope);

to

fcx.pop_and_trans_custom_cleanup_scope(bcx, self_scope);

Leads to my test case passing.

I'm running the full test suite now in preparation for a PR.

@arielb1
Copy link
Contributor

arielb1 commented Feb 7, 2016

trans::meth is such a hack

@thepowersgang
Copy link
Contributor

@arielb1

trans::meth is such a hack

What do you mean by that?

@thepowersgang
Copy link
Contributor

PR with fix filed #31462 - Running full local tests at the moment, stage1 passed

thepowersgang added a commit to thepowersgang/rust that referenced this issue Feb 7, 2016
bors added a commit that referenced this issue Feb 8, 2016
Generates drop calls at the end of the Fn/FnMut -> FnOnce closure shim

Fix #29946
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-destructors Area: Destructors (`Drop`, …) P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

10 participants