Closed Manishearth closed 9 years ago
This doesn't seem to track the blocks, but come to think of it do we really need to? Tracking blocks lets us know when something is implicitly dropped, but checking the emptiness of the map works too.
Also, I wonder how well it handles constructs like:
struct Composite {
x : Foo // protected
// ...
}
with partial moves and whatnot.
We could of course mandate that structs containing protected variables be themselves marked as protected, which makes life easier.
Overall, looks good! I may have another poke at this tomorrow to check how durable it is, but feel free to merge!
This doesn't seem to track the blocks, but come to think of it do we really need to? Tracking blocks lets us know when something is implicitly dropped, but checking the emptiness of the map works too.
That's what I figured. I don't think we need block ids at the moment.
One thing we don't handle is functions like this:
fn dropit<T>(x: T) { }
Since we just check all functions, but not instantiations of them, we can call dropit
on a drop protected var. Any suggestions?
We can check at the call site.
But check what? We don't annotate functions that can receive protected vars any more. We could check that a similar type is returned, but how do we know if it's the same var as before? Or that it hasn't been wrapped or unwrapped somehow?
But we do; we still have allow_drop
on the functions, right? If one of the arguments transitively resolves to a protected type (unless behind &
, we probably want a utility function for that), and the function isn't annotated with #[allow_drop(Foo)]
, then it's a case of a generic function being fed a protected type, and we can error.
We also need a better way to test all this... Something like rustc's compiletest would be perfect
But we do; we still have allow_drop on the functions, right? If one of the arguments transitively resolves to a protected type (unless behind &, we probably want a utility function for that), and the function isn't annotated with #[allow_drop(Foo)], then it's a case of a generic function being fed a protected type, and we can error.
Hmm, but then we'd have problems with vectors, right? Stuff like let mut v = Vec::new(); let c = Chan(); v.push(c);
should be allowed.
Hmm, but then we'd have problems with vectors, right? Stuff like
let mut v = Vec::new(); let c = Chan(); v.push(c);
should be allowed.
Oh, right, we removed the checks on ExprFnCall
and whatnot. We could add some sort of check that ensures that a protected type is never accepted by an unannotated generic, perhaps?
cc @Munksgaard