user17836287
user17836287

Reputation:

how to constrain the lifetime when doing unsafe conversion

I want to create a Test ref from the array ref with the same size and keep the lifetime checking.
I can do this by using a function and I know the function can deduce the lifetime. The code below is intentionally designed to fail when compiling because of use after move. It works.

struct Test {
    a: i32,
}

/// 'a can be removed for simplification
fn create_test<'a>(ptr: &'a mut [u8]) -> &'a mut Test {
    assert_eq!(ptr.len(), size_of::<Test>());
    unsafe { &mut *(ptr as *mut [u8] as *mut Test) }
}

fn main() {
    let mut space = Box::new([0 as u8; 100]);
    let (s1, _s2) = space.split_at_mut(size_of::<Test>());

    let test = create_test(s1);
    drop(space);

    test.a += 1;
}

My question is how can I do this without declaring an extra function to constrain the lifetime.

fn main() {
    let mut space = Box::new([0 as u8; 100]);
    let (s1, _s2): (&'a mut [u8], _) = space.split_at_mut(size_of::<Test>());
    let test: &'a mut Test = unsafe { &mut *(s1 as *mut [u8] as *mut Test) };
    drop(space);
}

such `a is not allowed.

Upvotes: 4

Views: 271

Answers (2)

user17836287
user17836287

Reputation:

The following code works. And it holds the borrowing check.

fn main() {
    let mut space = Box::new([0 as u8; 100]);
    let layout = Layout::new::<Test>();
    println!("{}", layout.align());
    let (_prefix, tests, _suffix) = unsafe { space.align_to_mut::<Test>() };
    assert!(tests.len() > 0);
    let test = &mut tests[0];
    let (_, suffix, _) = unsafe { tests[1..].align_to_mut::<u8>() };
}

Upvotes: 3

Chayim Friedman
Chayim Friedman

Reputation: 71400

You cannot do that, but this is not needed either. Lifetimes are used to ensure safety across function boundaries. In the same function you can just ensure safety manually.

Theoretically, we would not need a borrow checker if the compiler could just inspect the called functions and follow the execution path to deterime whether we invoke Undefined Behavior. Practically, this can't be done because of problems like the Halting Problem and performance.

Upvotes: 1

Related Questions