rune icon indicating copy to clipboard operation
rune copied to clipboard

Arena Bind and constrain lifetime

Open CeleritasCelery opened this issue 2 years ago • 0 comments

This is similar to #2. We have bind function for Arena.

https://github.com/CeleritasCelery/rune/blob/7136b74386a4586537ffa59c3be4849cb76354fe/src/arena/mod.rs#L346-L351

This relies on a safe trait ConstrainLifetime which let's us take object and "bind" it's lifetime to the Arena. We use this in case were an object may have root lifetime.

Why this is sound

It may seem odd that ConstrainLifetime is a safe trait, but you can't implement it in a way that would be unsound without unsafe code, so calling the trait is safe. All implementation would need to be unsafe, and by writing that unsafe code you have to uphold the invariant of ConstrainLifetime. This requires that the implementer is gc managed type.

impl<'old, 'new> ConstrainLifetime<'new, Object<'new>> for Object<'old> {
    fn constrain_lifetime<const C: bool>(self, _cx: &'new Block<C>) -> Object<'new> {
        // Lifetime is bound to borrow of Block, so it is safe to extend
        unsafe { transmute::<Object<'old>, Object<'new>>(self) }
    }
}

It is safe to call bind because so long as we are borrowing from Arena then garbage_collect can't be called, meaning the object cannot be freed even if the root it came from goes out of scope.

CeleritasCelery avatar Apr 11 '22 16:04 CeleritasCelery