Manishearth / humpty_dumpty

Implicit Drop/move protection for Rust (linear types)
12 stars 1 forks source link

Handle closures #18

Open Munksgaard opened 9 years ago

Munksgaard commented 9 years ago

There are two issues here: linearity needs to be checked inside of closures, and we need to handle moved variables

Manishearth commented 9 years ago

I believe the ctxt has some data on closure capture clauses in a map.

Manishearth commented 9 years ago

http://doc.rust-lang.org/rustc/middle/ty/type.UpvarCaptureMap.html, I think?

Munksgaard commented 9 years ago

http://doc.rust-lang.org/rustc/middle/ty/fn.closure_upvars.html, maybe?

Manishearth commented 9 years ago

Oh, forgot that middle::ty has a helper funciton for everything you'll ever need ;)

Munksgaard commented 9 years ago

It occured to me that you could actually just check the def_map to see whether or not something is an upvar. The result is b1782ad. However, I realized that we actually have a bigger problem: we cannot guarantee that a closure will ever be run!

Consider the following code, which is basically just a stripped version of the test from b1782ad:

let x = Foo;
let cl = || {
    close(x);
};

cl is a closure that has captured x and will correctly close it, but only if it is actually run. I don't think we can actually tell whether or not that is the case.

Manishearth commented 9 years ago

There's also an upvar capture map somewhere in the tcx.

We should assume that closures that capture droppy things by move will be run once.

Munksgaard commented 9 years ago

I don't like that assumption, but I'm also not sure that there's actually anything else we can do.

Manishearth commented 9 years ago

I think it's reasonable.

Note that a closure capturing by move will be FnOnce unless it's capturing by move via move || (in which case it may or may not be. So those closures are run either zero times or once.

Since we don't know when it's going to happen, we assume that "once" is bad.

Alternatively we can track the closure dependency and when it gets run but that sounds complicated.

Munksgaard commented 9 years ago

What do you mean "once" is bad?

But yes, it would be very nasty to track the closure.

Manishearth commented 9 years ago

@Munksgaard I mean that we disallow closures of this form.

Instantiating a closure that takes an upvar by-move is a move. This is similar to let x = foo(chan) in an abstract sense.