Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting array of mutable pointers to mutable references with const generics

Suppose that I guarantee (through unspecified means) that I have an array of type [*mut T; N] containing N valid and disjoint mutable pointers, all with lifetime 'a. How can I convert this to an array of mutable references [&'a mut T; N]?

In other words, how can I implement this function?

unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
    // What goes here?
}

I'm not particularly looking for an implementation that uses an allocation step (e.g. using Vec).


Because min_const_generics is set to stabilize in Rust 1.51, this question is targetting a hypothetical stable Rust that also has min_const_generics. I am looking for answers compatible with these requirements, using no other unstable features.

E.g. with the feature array_map one can simply

unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
   arr.map(|ptr| unsafe { &mut *ptr })
}

but since that is not set to stabilize by 1.51 (as far as I know) I do not wish to use it.

like image 455
orlp Avatar asked May 06 '26 12:05

orlp


1 Answers

Ideally, you would just use std::mem::transmute here, as references and pointers have the same memory layout. Unfortunately, std::mem::transmute doesn't work on generic arrays, even when the two types have the same layout. However, you can use union to work around this, as using a #[repr(C)] union is analogous to transmute:

#[repr(C)]
union Transmute<'a, T, const N: usize> {
    ptr_arr: ManuallyDrop<[*mut T; N]>,
    ref_arr: ManuallyDrop<[&'a mut T; N]>,
}

unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
    let u = Transmute::<'a, T, N> { ptr_arr: ManuallyDrop::new(ptrs) };
    ManuallyDrop::into_inner(u.ref_arr)
}

You can also use std::mem::transmute_copy, which effectively does the same here:

unsafe fn ptrs_to_refs<'a, T, const N: usize>(ptrs: [*mut T; N]) -> [&'a mut T; N] {
    std::mem::transmute_copy(&ptrs)
}
like image 152
Frxstrem Avatar answered May 09 '26 03:05

Frxstrem



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!