lotsoftools

Understanding Rust Error E0713

Introduction

Rust Error E0713 occurs when attempting to borrow state past the end of the lifetime of a type that implements the Drop trait. This article will provide an understanding of the error, explain the erroneous code example, suggest a possible fix, and demonstrate how to prevent this error from reoccurring.

Erroneous code example

#![allow(unused)]
fn main() {
pub struct S<'a> { data: &'a mut String }

impl<'a> Drop for S<'a> {
    fn drop(&mut self) { self.data.push_str("being dropped"); }
}

fn demo<'a>(s: S<'a>) -> &'a mut String { let p = &mut *s.data; p }
}

In the problematic code example above, the function demo tries to borrow the string data held within its argument s and return that borrow. However, S is declared as implementing Drop.

Understanding the error

Structs implementing the Drop trait have an implicit destructor that gets called when they go out of scope. This destructor has exclusive access to the fields of the struct when it runs. When s reaches the end of demo, its destructor gets exclusive access to its &mut-borrowed string data. Allowing another borrow of that string data (p) to exist across the drop of s would violate the principle that &mut-borrows have exclusive, unaliased access to their referenced data.

Fixing the error

Changing the demo function so that the destructor does not run while the string data is borrowed can fix this error. One approach is to take S by reference:

#![allow(unused)]
fn main() {
pub struct S<'a> { data: &'a mut String }

impl<'a> Drop for S<'a> {
    fn drop(&mut self) { self.data.push_str("being dropped"); }
}

fn demo<'a>(s: &'a mut S<'a>) -> &'a mut String { let p = &mut *(*s).data; p }
}

To avoid violating the &mut-borrow's exclusive access, this approach requires a reference to S with lifetime 'a. A shorter lifetime would imply that after demo finishes executing, something else (such as the destructor) could access s.data after the end of that shorter lifetime.

Conclusion

Rust Error E0713 is the result of attempting to borrow state past the end of the lifetime of a type that implements the Drop trait. By understanding the error and applying the suggested fix, you can ensure that your code adheres to the safety guarantees that Rust provides.