AttachGuardHolder has a lifetime parameter that is specified by the caller and which indicates that AttachGuardHolder has a reference to something borrowed from outside (with 'a).

foo() is specified to borrow self for that same lifetime. This essentially borrows AttachGuardHolder for its entire lifetime, which is going to be shorter than 'a.

To complicate matters, it’s borrowing self mutably - this means the lifetime of AttachGuardHolder has to be exactly the same as 'a because mutable lifetimes become invariant. Since AttachGuardHolder is dropped before jvm_holder, the compiler complains.

If you remove the mutable borrow, lifetimes are allowed to be variant. As such, you can borrow self for a longer lifetime (there’s no harm since it’s immutable).

The fix here is to change &'a mut self to &mut self in foo(). This will use a shorter borrow lifetime, just for that call to foo.

Thank you, it’s very useful! I didn’t know that &'a mut T is invariant over T.
Now that I learned how to name this thing (lifetime invariance), I found a long explanation of it in the documentation of lifetime subtyping. I put the link in case someone else has my same problem.

I’m still thinking about this… I’m trying to remove the dependency on jni by writing my own structs. From my understanding the following code should trigger the same compile-time error. However, it compiles fine. So it means that I still miss something

The AttachGuard from the JNI crate you’re using has a Drop impl, and that’s what makes the code barf there as well. In fact, now that I think about it, there may not be a variance/invariance issue here at all and it boils down to the drop check.

You can read more about drop check here, it’s closely related to borrow checking.

Also, somewhat tangentially, even if your code in main() compiled, there’s a second issue there - you wouldn’t be able to call any more methods on attach_guard_holder after the line that calls foo(). This is because &'a mut self causes the value to be borrowed mutably for essentially its entire lifetime, and no more borrows of any kind would be permitted.