-
Notifications
You must be signed in to change notification settings - Fork 17
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
Should arg
and build_with
be unsafe?
#6
Comments
Unsafe means "can cause memory safery issues". This is not likely to be the case here. There are a lot of similar cases in the stdlib where doing things incorrectly might break invariants (like implementing the Hash trait or PartialEq trait wrong in a hashmap) and yet those aren't unsafe. The docs should make sure to mention that though. |
My understanding is you use unsafe to mark that this API entry point can break invariants, possibly as a "I know the input code paths, give me better performance" Example: https://doc.rust-lang.org/std/intrinsics/fn.unchecked_div.html From TRPL
https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html |
Alright, I'm back on a computer. So first, I'll take back what I said. Unsafe really means "may use features that can cause undefined behavior". I can't find where this is written clearly, but for instance, from the nomicon (https://doc.rust-lang.org/nomicon/what-unsafe-does.html):
And from the page you linked: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html
In safe rust, you cannot run into undefined behavior. In unsafe rust, you have to be very careful about not breaking the invariants, otherwise you may cause undefined behavior. Now, what is undefined behavior? That's a hard question to answer, as rust does not yet properly identify what is defined and undefined (the Rust Unsafe Guidelines working group are working on it). There is an effort at defining them here: https://doc.rust-lang.org/reference/behavior-considered-undefined.html. Now, what about unchecked_div ? Unchecked_div is actually an llvm intrinsic. If you misuse it, you will misguide the compiler into undefined behavior, potentially doing anything. What about your arg function here? Here's the thing: misusing arg cannot cause undefined behavior. If you call arg at the wrong moment, what may happen is that cargo will error out with a help message, and as a result the message iterator will panic. That's it. No UB was invoked. In general, unless you have a very good reason, I don't think marking functions as unsafe without actually using unsafe capabilities in it isn't a good idea. Here's an example of a way to break invariants of an API that doesn't result in UB, and as such is explicitly not marked as unsafe: https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html
This is a very old post about what is unsafe, but I think it's relevant: http://huonw.github.io/blog/2014/07/what-does-rusts-unsafe-mean/. |
While I understand the concern that an API "requiring" too many unsafe blocks helps nullify the value of unsafe (at least that is what I read out of some of your comments) I disagree about unsafe being restricted only to compiler Undefined Behavior but also applies to API invariants. I think I'l open an issue on this in the API guidelines. And just to have all the references in one place:
|
I've tried to capture this in an unbiased way at rust-lang/api-guidelines#179 |
As a separate discussion point: Could something be done to avoid the invariant entirely? Maybe having |
Always a good idea to find ways to make an API less error prone. For trying to detect it, my main concern is not hampering the user from legit use cases. I'm not familiar enough with the different ways parameters could be constructed where this could be an issue. It does help that the problem space is narrowed down to where it might be valid to pass a string to cargo with a Also I've not investigated and documented this but I suspect there are other uses of
I've broken this out into #14 |
…holder README.md 'Crates Status' icon link
arg
andbuild_with
have the ability to break the invariants of the API and should probably be marked asunsafe
.While at it, it should probably be renamed to
arg_unchecked
, opening us up to aarg
that is checked.The text was updated successfully, but these errors were encountered: