This discussion on reddit got me thinking got me thinking about making the usage of unsafe
more restricted.
I think a reasonable case can be made for switching from “always allow unsafe unless #![forbid(unsafe_code)]
is specified” to "always deny unsafe unless #![allow(unsafe_code)]
is specified.
Would it make sense to write an RFC for this?
Pro
Allowing the availability of unsafe
to be tied to features
or other attributes
This allows for users to:
- only allow the usage of
unsafe
when a specific feature is enabled (e.g. which adds the usage of some ffi crate) - make it explicit that
unsafe
is only needed on specific platforms (e.g. because the code uses FromRawFd on that platform) - add an “unsafe_optimizations” feature
Code can then add conditional opt-ins like:
#![cfg_attr(feature = "unsafe_optimizations", allow(unsafe_code))]
I’ts theoretically possible to opt-out under all other combinations, but that would be a lot more difficult to keep track of or to verify.
Higher bar of entry
In the spirit of “make easy things easy and hard thing possible”, we probably don’t want to make something that is hard (to reason about) easy as long as it’s possible. Forcing developers to take a bit of a longer route to use something might make them think twice about doing it.
More informed decisions
Making unsafe less directly available also forces (new) users to do more research before being able to use it. We don’t want to force a quiz upon them before divulging the way to opt out of safety, but at least provide a bit more background about the possible pitfalls about opting out.
Con
Making a language feature less accessible
The whole unsafe
mechanism is one often touted as being one of the most significant language features Rust brings to the table.
On the other hand this change would only force users to add 1 line per source file where they want to use unsafe in, but they also get the option to better control the scope in which it is available.
Breaking change
Switching to by default disallow unsafe
would be a breaking change.
One option might be to add an extra option to Cargo.toml
with which the default can be changed that will default to the current behavior when not defined.
Another option would be to wait until the next edition of Rust and switch when crates opt-in to the new edition.