Hacker News new | ask | show | jobs
by dschatz 4039 days ago
Just to add to this point, the difference is that Rust can only guarantee this for the standard library. I can similarly write a library with safe interfaces that can be (ab)used to cause UB and there's little that the Rust team can do. This is different from other "safe" languages.

This is why it's so important to establish what the responsibility and expectation is of library developers to uphold the safety guarantees that everyone else relies on. It only takes one bad library to destroy the safety guarantees everyone who is transitively using that library relies on.

2 comments

This is not all that different from Java (or Python, etc.), where it is quite easy to hide a call to a native function behind a seemingly-safe interface. The real difference is that native methods in Java must be written in a different language (C), while Rust supports both modes in the same language. (Edit: Or, if you prefer, two different but very closely related languages.)

I would argue, at any rate, that this sort of safe/unsafe boundary is still useful for the purpose of auditing code. Conceptually, memory bugs are interactions between two points in the program: e.g. one location deallocates a pointer, then another tries to dereference it. With Rust's implementation of unsafe, you are guaranteed that any bad interactions must have at least one endpoint in an unsafe block. You still can't completely ignore the safe code, because unsafe code can reach arbitrarily far out of its box (so to speak), but in general this constraint does help significantly in limiting the amount of code that needs to be audited.

Agreed. We had a segfault in Servo due to upgrading the compiler (and some internal representations changing). I wasn't able to track it myself (unfamiliarity with the code), but someone else was able to find its origin and fix it without much trouble because of `unsafe`. (That aside, we very rarely have segfaults in Servo, and Servo's huge)
Indeed. I have frequently segfaulted python by using certain modules (not even particularly obscure or low-quality ones either).
Right, but if you write a library using only Rust "safe" code, the guarantee is back on the Rust team.

To me, it would be better if libraries using unsafe code were marked.

Here's[0] an interesting idea for forcing crates using unsafe code to be handled specially, while allowing some "blessed" crates through without the special handling.

[0]: https://github.com/rust-lang/cargo/issues/934#issuecomment-6...

That seems like absolutely great idea. I want it already. I wonder why it wasn't processed further, while being 6 month old already.

It is different notion of "blessed" than the original proposal and, IMHO, a much better one. Steve's proposal is quite dubious, I guess. The problem is low standard for the word "blessed" here: in his proposal this badge has no technical meaning, but big social impact. Crate doesn't have to be superior in a technical sense to get this badge, it just has to be "famous", and stuff gets "famous" for various reasons. That's really bad and will get worse when Rust/Cargo will become more popular.

But that "safe/unsafe" isn't a matter of opinion anymore. If a library is known to be unsafe through the "safe" interface: it's a bug, and a crate shouldn't have this badge from a moment the bug has been discovered and until the bug is fixed again (or even longer, if there have been 5 such bugs over the last 2 weeks, even though now they seem to be fixed). It somewhat serves the original purpose (I assume), because it still means that a crate that isn't used heavily enough ("was downloaded N times over the last month") cannot be "blessed" — we don't have all necessary information to mark it as "blessed" yet, so it will help to set "junk crates" aside.

It's worth nothing if a library is made by Github, but is known to be buggy and to leak memory. But it is worth something if a "github API" crate made by John Doe is used by hundreds of people and didn't have a single memory leak for quite a while.

> Steve's proposal is quite dubious, I guess.

I pretty much opened this issue so we could talk about it, not because I think it's a good idea.

Oh, I didn't mean any offense. I'm just commenting on the idea: the original wording of the proposal seems dangerous, but both reem's and yazaddaruvala's ideas definitely have potential.

So you did a good job by starting that discussion. I hope it will have results.

It's all good, none taken! :)
I wonder if this shouldn't be on the "rust" side, rather than on the "crates.io"-side. Considering[1], I think I'd prefer either/or:

    extern unsafe crate phrases; // It's all UNSAFE!
Or: extern crate phrases; // It's mostly safe

    use unsafe phrases::english; // But not English
The idea being, that either phrases wouldn't be imported/give an error -- or everything in phrases except "english" would be imported -- and english would only be imported if qualified with "unsafe".

Either way... I can see this going the way of try/catch/throws in java -- where the usefulness diminishes as lazy programmers (we're all lazy) end up polluting everything with unsafe (just like "throws Exception e..").

[1] https://doc.rust-lang.org/book/crates-and-modules.html