Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Cargo needs to grow a label for crates that provably do not panic. (Neverminding allocations and things outside our control flow.)

I want to ban crates that panic from my dependency chain.

The language could really use an extra set of static guarantees around this. I would opt in.



> I want to ban crates that panic from my dependency chain.

Which means banning anything that allocates memory and thousands of stdlib functions/methods.


See the immediately preceding sentence.

I'm fine with allocation failures. I don't want stupid unwrap()s, improper slice access, or other stupid and totally preventable behavior.

There are things inside the engineer's control. I want that to not panic.


Your pair of posts is very interesting to me. Can you share with me: What is your programming environment such that you are "fine with allocation failures"? I'm not doubting you, but for me, if I am doing systems programming with C or C++, my program is doomed if a malloc fails! When I saw your post, I immediately thought: Am I doing it wrong? If I get a NULL back from malloc(), I just terminate with an error message.


Not GP but I read "I'm fine with allocation failures" as "I'm OK with my program terminating if it can't allocate (but not for other errors)".


I mean, yeah, if I am using a library, as an user of this library, I would like to be able to handle the error myself. Having the library decide to panic, for example, is the opposite of it.


If I can't allocate memory, I'm typically okay with the program terminating.

I don't want dependencies deciding to unwrap() or expect() some bullshit and that causing my entire program to crash because I didn't anticipate or handle the panic.

Code should be written, to the largest extent possible, to mitigate errors using Result<>. This is just laziness.

I want checks in the language to safeguard against lazy Rust developers. I don't want their code in my dependency tree, and I want static guarantees against this.

edit: I just searched unwrap() usage on Github, and I'm now kind of worried/angry:

https://github.com/search?q=unwrap%28%29+language%3ARust&typ...

A lot of this is just pure laziness.


Not to mention overcommit has become standard behavior on many systems, so you wouldn't even get a NULL unless you really tried.


I think I'd prefer a compile-time guarantee.

Something that allows me to tag annotate a function (or my whole crate) as "no panic", and get a compile error if the function or anything it calls has a reachable panic.

This will allow it to work with many unmodified crates, as long as constant propagation can prove that any panics are unreachable. This approach will also allow crates to provide panicking and non panicking versions of their API (which many already do).


Yes, I want that. I also want to be able to (1) statically apply a badge on every crate that makes and meets these guarantees (including transitively with that crate's own dependencies) so I can search crates.io for stronger guarantees and (2) annotate my Cargo.toml to not import crates that violate this, so time isn't wasted compiling - we know it'll fail in advance.

On the subject of this, I want more ability to filter out crates in our Cargo.toml. Such as a max dependency depth. Or a frozen set of dependencies that is guaranteed not to change so audits are easier. (Obviously we could vendor the code in and be in charge of our own destiny, but this feels like something we can let crate authors police.)


I think the most common solution at the moment is dtolnay's no_panic [0]. That has a bunch of caveats, though, and the ergonomics leave something to be desired, so a first-party solution would probably be preferable.

[0]: https://github.com/dtolnay/no-panic


This sounds a little bit like Safe Haskell, which never really took off.


I would be fine just getting rid of unwrap(), expect(), etc. That's still a net win.

Look at how many lazy cases of this there are in Rust code [1].

Some of these are no doubt tested (albeit impossible to statically guarantee), but a lot of it looks like sloppiness or not leaning on the language's strong error handling features.

It's disappointing to see. We've had so much of this creep into the language that eventually it caused a major stop-the-world outage. This is unlikely to be the last time we see it.

[1] https://github.com/search?q=unwrap%28%29+language%3ARust&typ...


I don't write Rust so I don't really know, but from someone else's description here it sounds similar to `fromJust` in Haskell which is a common newbie footgun. I think you're right that this is a case of not using the language properly, though I know I was seduced into the idea that Haskell is safe by default when I was first learning, which isn't quite true — the safety features are opt-in.

A language DX feature I quite like is when dangerous things are labelled as such. IIRC, some examples of this are `accursedUnutterablePerformIO` in Haskell, and `DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_CREATE_ROOT_CONTAINERS` in React.js.


I would be in favor of renaming unwrap() and its family to `unwrap_do_not_use_or_you_will_break_the_internet()`

I still think we should remove them outright or make production code fail to compile without a flag allowing them. And we also need tools to start cleaning up our dependency tree of this mess.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: