Vec { unsafe { unsafe_iterator().map(|n| ...">

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.

+3


source to share


1 answer


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.

+2


source







All Articles