-
Notifications
You must be signed in to change notification settings - Fork 1.7k
RFC: Safe because I said so #1910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
It might make sense to experiment with something like this out of tree, comparable to the launch-code plugin |
| The new _The Rust Programming Language_ does not seem to mention unsafe code | ||
| at all. | ||
|
|
||
| I've not check _Rust by Example_ for unsafe examples, but where there are any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checked*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably remove any instances of "I".
|
|
||
| Add a `#[safe("Reason")]` to annotate why unsafe blocks are actually safe. | ||
| Also add a lint to the compiler to forbid unsafe blocks without a safe | ||
| annotation. Add a `#[warn(unexplained_unsafe)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you lost a
` lint.
|
Nice idea! It'll be used more if |
|
Please also with cryptographic signatures like launch-code. |
|
I'd only consider that acceptable if they were optional. Since I only use Rust for hobby projects, all I need is to have access to an |
|
Maybe not create new attributes at all, but just lint against an unsafe block that has no doc comment (stabilizing them on unsafe block expressions if needed)? |
|
"no doc comment" isn't enough because it could be silenced completely accidentally. (ie. By something which explains why I chose that algorithm, rather than why I think it's safe.) It'd have to be something that's clearly intentional, like |
|
@bjorn3 There is no need for special signature tooling here since you can verify signatures on all commits containing the word unsafe using |
|
Is there really a need for this? It's another annotation in the language and beginners will have to learn another thing (yes it is somehow obvious what As the rendered document states, this will lead to many placeholders. I don't think it will really prevent "unsafe unsafes". If a use of unsafe isn't valid in an obvious way, I'd go for the comment approach. For the |
|
This should probably apply to I feel like this would quickly result is some just-enough-to-pass-CR strings getting copy-pasted everywhere. Like Is the block itself the right scope for a justification? Something like "the first length elements are constructed, but space is allocated for the capacity ones" would probably be a justification for many things in different Also, if every block needs an attribute, that's implicit encouragement to merge unsafe blocks rather than keep them separate and localized. And the extra characters would make a targeted unsafe in a closure, for example, noisy enough that it'd look ugly, so it might just get widened. Would it be worth letting people say what they're justifying? Say It'd be nice to see some less-"silly" examples, since the current one is just Would this have actually solved the Overall, I think I'm 👎: This still depends on careful code review, and at that point it doesn't need to be an attribute. |
|
A lot of your arguments about how it could be circumvented by undisciplined coders could apply equally well to the The distinction being that At the very least, I'd argue that such a lint belongs in clippy alongside TL;DR: Not everything in Rust needs to be held up to the standard the borrow checker enforces on the code. Just because something requires a certain degree of cooperation from the developer doesn't disqualify it from being useful enough to include. P.S. I believe it was an instance of Andrew File System that I'm remembering being configured to allow creation but not deletion in a production setting. |
|
@rfcbot fcp postpone I am strongly in favor of giving more semantic content to our unsafe blocks. However, I'm not in favor of adding anything to the compiler right now to do that -- I'd rather we experiment out of tree. I am aware of at least one such experiment (launch-code, previously mentioned), and I know of a few people pursuing various verification techniques in academia as well. I have my own pet theories for what'd make a nice, simple tool. To throw into the mix, I think that we may want to expand our model of "unsafe blocks" and so forth as part of the unsafe code guidelines work -- so basically there are enough ingredients swirling around that I think it's too early to bless one approach as the winner. Therefore, I move to postpone this RFC. |
|
Team member @nikomatsakis has proposed to postpone this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
|
Postponing sounds prudent to me, though I do have one new ingredient to add to the general idea soup that might make an initial implementation palatable: Example (assuming the annotation is an attribute): #[lint_safe_because(
error(missing("natural-en-us")),
warn(missing("launch-code))"
)]
#[config_attr(nightly, lint_safe_because(error(invalid("launch-code"))))]
fn safe_fn() {
#[safe_because(
justification("natural-en-us",
"This block is safe because......"),
justification("natural-es-es",
"Esta bloque es segura porque"),
justification("audited-launch-code",
"⠐⡛⢾⣯⢓⢵⢖⡆⣈⠇⠸⣼⢁⢦⢰⢷⡫⢙⠻⠺⢗⢻⣷⠋⣸⡐⣂⡜⠇⡍⢁⢗⢜⠢⡢⣵⠩⠲⡈⢈⢂⡑⣷⣩⢲⢖⢃⡓⠄⣴⠩⡹⡸⠥⢱⢭⡼⠡⣻⡥⢜⢔⡌⠅"),
justification("proof-coq",
"<some coq source here.>")
)]
unsafe {
//...
}
}
#[safe_because(
justification("natural-en-us",
"This function is safe if callers can prove...."),
justification("natural-es-es",
"Esta función es segura si los usuarios pueden probar"),
justification("audited-launch-code",
"⠐⡛⢾⣯⢓⢵⢖⡆⣈⠇⠸⣼⢁⢦⢰⢷⡫⢙⠻⠺⢗⢻⣷⠋⣸⡐⣂⡜⠇⡍⢁⢗⢜⠢⡢⣵⠩⠲⡈⢈⢂⡑⣷⣩⢲⢖⢃⡓⠄⣴⠩⡹⡸⠥⢱⢭⡼⠡⣻⡥⢜⢔⡌⠅"),
justification("proof-coq",
"<some coq source here.>")
)]
unsafe fn unsafe_fn(i32:foo) {
//...
}Validators for justification types would be either external tools, lints (nightly/unstable only) or built into the compiler. Experimental validators could be used to experiment with and validate unsafe guidelines. As unsafe guidelines solidify and formal verification of rust code matures, further rfcs would propose stabilising individual validators. |
|
@jessstrap that can already be done with compiler plugins. |
|
@bjorn3 Yes, but compiler plugins are only on unstable. To clarify: I am proposing a stable |
|
@ssokolow I like There's definitely a place for more help writing and reviewing unsafe code. But I think it needs more than a single opaque string. Maybe, for example, an unsafe method could document its unchecked preconditions in such a way that exactly that set would need to be justified by the caller. Then when writing the code the compiler will prompt you about each thing you need to consider to call the unsafe, and in a bad copy-paste-edit would tell you that there's something extra. (Kinda like lints.) That's not unlike what the example justification in the RFC does--list the things that need to be considered and explain them--just in a way that the compiler can help. I agree that help doesn't need to be borrowck-level-perfect (though maybe with |
|
@scottmcm And that's a detail that varies from person to person.
|
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
1 similar comment
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
|
The final comment period is now complete. |
|
Closing as postponed, as originally proposed. |
Rendered