I'm currently looking into doing more stuff with arrays, but I think the performance of those operations could be even better if we were allowed to somehow transmute into a Leaked<T>
the array up front, only to un-leak it when the function ends. This would let us use leak amplification without a) introducing unsafety and b) setting up a catch_panic(_)
. Is this somehow possible in Rust?
For example, creating a generic array from an iterator (this obviously does not work):
#[inline]
fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
unsafe {
// pre-leak the whole array, it's uninitialized anyway
let mut res : GenericArray<Leaked<T>, N> = std::mem::uninitialized();
let i = list.into_iter();
for r in res.iter_mut() {
// this could panic anytime
std::ptr::write(r, Leaked::new(f(i.next().unwrap())))
}
// transmuting un-leaks the array
std::mem::transmute::<GenericArray<Leaked<T>, N>,
GenericArray<T, N>>(res)
}
}
I should note that if we either had compile-time access to the size of T
or a type that can hide its innards from borrowck (like Leaked<T>
in the example), this is perfectly feasible.
It is possible using nodrop, but it could leak.
fn map_inner<I, S, F, T, N>(list: I, f: F) -> GenericArray<T, N>
where I: IntoIterator<Item=S>, F: Fn(&S) -> T, N: ArrayLength<T> {
unsafe {
// pre-leak the whole array, it's uninitialized anyway
let mut res : NoDrop<GenericArray<T, N>> = NoDrop::new(std::mem::uninitialized());
let i = list.into_iter();
for r in res.iter_mut() {
// this could panic anytime
std::ptr::write(r, f(i.next().unwrap()))
}
res.into_inner()
}
}
Let's suppose that after the first item (a
) is consumed from i
and written to r
, a panic happens. The remaining items from i
would be drop, but the item a
would not. Although leaking memory is not considered unsafe, it is not desirable.
I think that the approach described in the question link is the way to go. It is similar to the Vec and ArrayVec implementations. I'm using a similar approach in array library that I'm writing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With