Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to constrain the lifetime when doing unsafe conversion

Tags:

rust

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.


1 Answers

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>() };
}


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!