Borrowing closure problem in Rust 1.5 (works in 1.4)


#1

Hi,

Apologies for asking you to look into a quite complex problem, but I’m not sure whether it’s me or Rust that’s at fault here, or how to make a minimal example.

I spent some days writing a server module for my dbus bindings a while ago, and went to great extent to make it possible to make the callbacks from dbus transform into calling closures that borrow their environment. And it works…in 1.4. Then I upgraded my compiler, and now I get lifetime errors.

The easiest way to test it is to clone dbus-rs and run “cargo test”. The test failing is called prop_lifetime_simple and it fails with count does not live long enough, which does not make sense to me. (There is another more complex test case too, that also fails, for the same reason.)

Again, with 1.4 it works just fine. @bluss suggested it might have to do something with variance or Arc having a soundness bug fixed, but I don’t know what to do about it or how to fix it (if possible) so that borrowing closures work as expected again. Or if it’s a Rust compiler bug.

Thanks in advance.


#2

Haven’t looked at this too closely, but in that test, don’t you want to be moving ownership of count into that closure? Shouldn’t you write ....on_set(move |_,_,_| { ... }) instead?


#3

But I want borrowing closures to work too, not only moving closures, and the count variable is declared in a way that it should live longer than the closure, so I think it should work as written, too?


#4

What I understood was that Arc<T> gained the internal marker PhantomData<T>. The variance changes shouldn’t matter actually, but the marker also indicates for dropck that the Arc<T> represents (shared) ownership of a T value. So indeed dropck rules now apply where they previously did not.

relnotes explanation is “Correct a bug in Rc/Arc that caused dropck to be unaware
that they could drop their content. Soundness fix”


#5

Right, but the question still remains how this causes compilation to fail, because the way the test is written, surely count should outlive everything declared afterwards, which includes the closure and everything connected to it?