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.)
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 fn
s 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 fn
s.)