Can I create an "unsafe close"?
I have a code that looks like this when simplified:
fn foo() -> Vec<u8> {
unsafe {
unsafe_iterator().map(|n| wrap_element(n)).collect()
}
}
The iterator returns items that would be invalid if the underlying data changed. Unfortunately, I cannot rely on the normal Rust engine mut
here (I am doing some ... strange things).
To fix the insecurity, I move the iterator at once and make copies of each item (through wrap_element
) and then throw the whole thing into Vec
. This works because nothing else has the ability to go in and change the underlying data.
The code works as-now, but since I use this idiom several times, I wanted a little DRY in my code:
fn zap<F>(f: F) -> Vec<u8>
where F: FnOnce() -> UnsafeIter
{
f().map(|n| wrap_element(n)).collect()
}
fn foo() -> Vec<u8> {
zap(|| unsafe { unsafe_iterator() }) // Unsafe block
}
My problem with this solution is that the call unsafe_iterator
is unsafe and it wrap_element
/ collect
again makes it safe. The way the code is structured doesn't convey this at all.
I would like to somehow mark my closure as unsafe
and then zap
to make it safe again.
source to share
It is not possible to create a closure unsafe
in the same vein as and unsafe fn
since closures are just anonymous types with trait family implementations Fn
, FnMut
and / or FnOnce
Since these traits have no methods unsafe
, it is not possible to create a closure that unsafe
invokes.
You can create a second set of closure traits with methods unsafe
and then write implementations for them, but you will lose most of the sugar closure.
source to share