Thank you for the Nomicon.
https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html reads " you can even toss #![forbid(unsafe_code)] into your code base to statically guarantee that you're only writing Safe". While that is technically correct, it may lead people to unintentionally introduce unsafe. Steps:
- "Let me check a such-and-such library"
- "Let me check a such-and-such 3rd party library." or
- "Let me review our such-and-such internal library.", or even
- "Let me check my own (private/internal) library that I wrote X years ago and mostly forgot about."
- "That library's
lib.rs has #![forbid(unsafe_code)]."
- "Great. So that library can't introduce any
unsafe to my library/crate." (This is the core of the mistake.)
- "Let me use that library's macro(s)." (Or, even worse: "Let me copy-and-paste that library's tutorial/doctest/unit test...".)
But, macros from such libraries can still generate unsafe code.
Of course, the consumer can have #![forbid(unsafe_code)] in her crate - but only if her crate doesn't use any unsafe on its own.
If the library uses macro_rules, any unsafe can be grepped for. If it's a procedural macro, unsafe could come from a concatenated (or otherwise generated) string, so not searchable. (Obviously, that would be either stupid or malicious, but malicious crates did exist.)
So, suggest a note like:
However, if you are using any macros, those may generate unsafe even if their library has #![forbid(unsafe_code)]. You can:
- check the macro implementation (but that won't cover future versions). Or,
- have
#![forbid(unsafe_code)] in your crate. Or,
- if your crate uses
unsafe (which is likely, since you are reading this):
- use such macro(s) in a playground library with
#![forbid(unsafe_code)], or
- move your code that uses such macro(s) in a separate module and have
#![forbid(unsafe_code)] in that module, or
- move your code that uses such macro(s) in a separate block and forbid
unsafe for that block #[forbid(unsafe_code)] {...}.
If this sounds acceptable, I'm open to providing a pull request.
Thank you for the Nomicon.
https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html reads " you can even toss
#![forbid(unsafe_code)]into your code base to statically guarantee that you're only writing Safe". While that is technically correct, it may lead people to unintentionally introduceunsafe. Steps:lib.rshas#![forbid(unsafe_code)]."unsafeto my library/crate." (This is the core of the mistake.)But, macros from such libraries can still generate
unsafecode.Of course, the consumer can have
#![forbid(unsafe_code)]in her crate - but only if her crate doesn't use anyunsafeon its own.If the library uses
macro_rules, anyunsafecan be grepped for. If it's a procedural macro,unsafecould come from a concatenated (or otherwise generated) string, so not searchable. (Obviously, that would be either stupid or malicious, but malicious crates did exist.)So, suggest a note like:
However, if you are using any macros, those may generate
unsafeeven if their library has#![forbid(unsafe_code)]. You can:#![forbid(unsafe_code)]in your crate. Or,unsafe(which is likely, since you are reading this):#![forbid(unsafe_code)], or#![forbid(unsafe_code)]in that module, orunsafefor that block#[forbid(unsafe_code)] {...}.If this sounds acceptable, I'm open to providing a pull request.