Restrict lifetime for reference converted from pointer

Acording to nomicon after pointer to reference
conversation reference get special lifetime almost or more then static.
Is any way how make hint to compiler, that lifetime of slice is restricted to visibility of data and n,
so them become not valid after exit from function?

extern "C" fn f1(data: *const u8, n: usize) {
    let slice: &[u8] = unsafe { std::slice::from_raw_parts(data, n) };
    std::thread::spawn(move || {
        println!("slice {:?}", slice);
    });
}

As you can see in this example compiler allow to move slice to thread, because of it thinks
that slice has static lifetime, but this is not true, slice is valid untill end of function.
Is any way to specificy it without introducing new function?

extern "C" fn f1(data: *const u8, n: usize) {
    let slice: &[u8] = unsafe { std::slice::from_raw_parts(data, n) };
    do_f1(slice);
}

fn do_f1(slice: &[u8]) {
    std::thread::spawn(move || {
        println!("slice {:?}", slice);
    });
}

This code doesn't compile, exactlly like I want, but it is to boring to introduce bunch of small functions,
is any specifial syntax to mention lifetime of function's body?

fn slice_that_lives_as_long_as_the_pointer<'a>(data: &'a *const u8, n: usize) -> &'a [u8] {
    unsafe { std::slice::from_raw_parts(*data, n) }
}

extern "C" fn f1(data: *const u8, n: usize) {
    let slice = slice_that_lives_as_long_as_the_pointer(&data, n);
    // do_f1(slice);
}

fn do_f1(slice: &'static [u8]) {
    std::thread::spawn(move || {
        println!("slice {:?}", slice);
    });
}

Note that the lifetime of the slice is still not accurate, as it's tied to the lifetime of the pointer, not the lifetime of the pointee, but this type of thing tends to catch the most egregious errors.

Be aware that this isn't true in all contexts. You could make the lifetime shorter and in the process invalidate the pointer (e.g. by calling free on it). The lifetime might also actually be valid longer than the function call, but it's hard to tell when dealing with C code.

1 Like