Search code examples
rustunsafe

What are best practices for `unsafe` functions in which only a small part of the code is actually doing `unsafe` things?


In the crate I'm developing I have several unsafe functions, which are marked as such because of reasons explained in this answer. In unsafe functions, I can perform unsafe operations as if the full function body was wrapped in an unsafe { } block.

The problem is that, in bigger functions, only a small part of the function body is actually performing unsafe operations, while the rest is doing perfectly safe stuff. Often, this safe stuff is even pretty independent of the unsafe code. In these larger functions, I would like to narrow the scope of unsafe operations. The reason should be fairly understandable: I also don't wrap my complete codebase in an unsafe { } block just because I can.

Unfortunately, there isn't a safe { } block to "invert" the behavior of unsafe functions. If there were I would use it like that:

unsafe fn my_function() {
    safe {
        // ... doing safe stuff ...

        unsafe {
            // ... doing `unsafe` stuff ...
        }

        // ... doing safe stuff ...
    }
}

But as this is not possible: what are best practices in these situations to narrow the scope of unsafe operations? Are there established tricks to deal with this?

Just to be clear: this question is not about discussing whether or not narrowing the unsafe scope is good or bad. I stated that I want to do it: this question is about how to do it and what solutions (if any) are most commonly used in practice. (And if you don't understand why I would like to do it, this RFC is very related.)


Solution

  • For future folks reading this question, nowadays we have a lint for this (you can see by following the RFC link in the OP to this issue). If you add a #![deny(unsafe_op_in_unsafe_fn)] somewhere like the top of your crate's main rs file, you will get errors for using unsafe operations in unsafe fns unless you add unsafe blocks around them. (i.e. in the language of the OP, there is effectively a safe block wrapping the body of all unsafe fns.)