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?
Allowing the availability of
unsafe to be tied to
features or other attributes
This allows for users to:
- only allow the usage of
unsafewhen a specific feature is enabled (e.g. which adds the usage of some ffi crate)
- make it explicit that
unsafeis 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.
Making a language feature less accessible
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.
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.