Help with lifetime in rusty_v8

Hi, guys.
I have to convert a Buffer struct with ptr and len to v8::String. When I do it like the following, it's ok.

let p1 = v8::String::new_from_utf8(
    scope,
    p1.as_slice(),
    v8::NewStringType::Normal,
)
.unwrap();
let p2 = v8::Boolean::new(scope, p2 != 0);
let p3 = v8::String::new_from_utf8(
    scope,
    p3.as_slice(),
    v8::NewStringType::Normal,
)
.unwrap();

Then I tried to simplify the code like the following

let p1 = p1.to_string(scope);
let p2 = v8::Boolean::new(scope, p2 != 0);
let p3 = p3.to_string(scope);

Where to_string function is like this.

    pub fn to_string<'a, 'b>(self, scope: &'a mut HandleScope<'b>) -> Local<'a, v8::String>
    where
        'b: 'a,
    {
        let bytes = unsafe { std::slice::from_raw_parts(self.ptr, self.len as _) };
        let s = v8::String::new_from_utf8(scope, bytes, NewStringType::Normal).unwrap();
        self.dealloc();
        s
    }

Then the compiler complains about cannot borrow *scope as mutable more than once at a time. I don't understand why it does not complain the first time. Thanks.

Sorry. I think I solved the problem.

    pub fn to_string<'a, 'b>(self, scope: &'a mut HandleScope<'b>) -> Local<'b, v8::String>
    where
        'b: 'a,
    {
        let bytes = unsafe { std::slice::from_raw_parts(self.ptr, self.len as _) };
        let s = v8::String::new_from_utf8(scope, bytes, NewStringType::Normal).unwrap();
        self.dealloc();
        s
    }

The lifetime for Local should be 'b, not 'a.

You can elide the 'a parameter completely there, which reads a bit nicer to me, making the important lifetime stand out more.

2 Likes

Yes, you're right.