4 ms·
What I really, really need from Rust maintainers is a #[forbid(panic)] somewhen in the next releases.
by selfmodruntime 2y ago
What I really, really need from Rust maintainers is a #[forbid(panic)] somewhen in the next releases.
- duped 2y agoWhat do you need it for? That would forbid tons of code, like array indexing and unreachable!(). There's the UnwindSafe marker trait that isn't exactly the same thing but addresses the only real case I've seen for forbidding panics which is FFI.
- AlotOfReading 2y agoThere's plenty of situations where telling developers to go change their code so it doesn't panic might be an appropriate lint. Think safety critical rust for example.
- sshine 2y agoAdding to this argument: A lot of panics are placed instead of proper error handling as a cause of happy-path programming. (E.g. all cases of .unwrap()) Some panics are placed not knowing they’re panics. (E.g. indexing, calling a function that panics) Some panics are legitimately placed by people who want a program to panic at a given place; this may collide with the caller’s desire to use Result and error types. There are lots of situations where being notified about where the panics live can make your code more robust, because they do sneak in.
- SkiFire13 2y agoBut what about those panics for "I know this situation cannot possibly happen"?
- sshine 2y agoFor those you have `unreachable!()` (a hope rather than a certainty): https://doc.rust-lang.org/std/macro.unreachable.html https://doc.rust-lang.org/std/macro.unreachable.html In those cases you strike a deal with the devil. The type system won't help you. Maybe it's an acceptable tradeoff for readability and efficiency. Maybe you could have modelled the code so it wasn't necessary. I think you can divide the use of `unreachable!()` in two cases: 1) As a consequence of style (applying LEM to code) 2) As a consequence of low-level abstractions One can be avoided by remodelling. The other can be tucked away behind safe interfaces.
- steveklabnik 2y agoThe unreachable macro invokes a panic. It wouldn’t be allowed if panics were not allowed.
- Fulgen 2y agoAs the other commenter said, `unreachable!()` panics. You'd need https://doc.rust-lang.org/core/hint/fn.unreachable_unchecked.html https://doc.rust-lang.org/core/hint/fn.unreachable_unchecked...
- SkiFire13 2y agoWhich is arguably even worse, because now if it fails you don't even see it! You wanted to make the code more robust and ultimately made it less.
- sshine 2y agoYes, I'm not saying `unreachable!()` isn't a `panic!()`. And I am also not arguing for the use of `unreachable_unchecked!()`. I am only arguing that in all the other cases mentioned, you can simply avoid panics.
- SkiFire13 2y agoThe problem however is that a generic "panic" lint will trigger on these as well. Which will be pretty annoying. Combined with the fact that such a lint will have to see through functions in other crates (otherwise `unwrap` and indexing won't be linted) will make this pretty annoying. I hope maintainers won't be nagged to remove lecit panics like these just because the lint annoys some dependents...
- duped 2y agoMy claim is that's not actually very useful for ensuring the correctness of code, since Rust doesn't dependent typing.
- AlotOfReading 2y agoCorrectness of safety critical code (and others) is about more than just memory and logical safety. Imagine your brake control module is running rust and something unwinds. Now your time budget is being spent unwinding the stack and you're probably going to run into a watchdog halfway through, forcing a reboot and possibly escalating into a hard stop depending on the safety model. You can imagine similar issues with cryptography for example, or network stacks. I'm not saying that lint should be enabled by default. It's a highly specialized config, but it's an important protection when it's useful.
- selfmodruntime 2y agoFor embedded code that must never fail. I don’t want array indexing, I can just use „get“
- bestouff 2y agoI would allow array indexing if the compiler can prove the bounds have been properly checked before use.
- SkiFire13 2y agoThis is not that simple at all. For starters, what is a bound check? There's no such concept at the type level that the compiler can check. You'll need to add one such concept that propagates through functions, increasing the complexity of function signatures. And this still won't solve the problem of when you as a programmer know that something is definitely inbound but you can't express the proof in the language. Ultimately this means using `panic` (but you don't want to), dummy default values (but this is just `null` all over again!), adding dependent types (which AFAIK nobody has managed to do in a low level language, and even if it was possible it would add a lot of complexity) or just give up and accept your program cannot be accepted.
- duped 2y agoget() returns Option<T> which you need to match against, and if it's None then you may have no choice but to mark it unreachable!() which will panic in debug compiles. Or you can use get_unchecked which is unsafe and avoids the bounds check. If you pass the bounds check up higher then you have no risk of panic. My point is that forbidding code from panicking isn't that useful - you still need to audit the code to make sure it's correct.
- trealira 2y agoIf you want to prove that an array is never indexed out of bounds in some procedure for an embedded program, you can use Ada with SPARK or use Frama-C to prove it. As far as I know, Rust has no equivalent. Otherwise, like duped said, using get will return an Option<T>, and so you'd either have to use unreachable!() and panic anyway, or you'd have to propagate the error up the call stack and let it affect all the types of those functions (at which point, what is the caller supposed to do about it?).
- bryanlarsen 2y agoPut your code in a thread to turn panics into errors.
- afdbcreid 2y agoYou don't need threads for that, just std::panic::catch_unwind().
- Raicuparta 2y agocatch_unwind doesn't catch all panics. I imagine that running a thread would actually catch all panics, but I don't know enough about the subject to say that confidently. https://doc.rust-lang.org/std/panic/fn.catch_unwind.html#notes https://doc.rust-lang.org/std/panic/fn.catch_unwind.html#not...
- afdbcreid 2y agoAborting panics won't by caught by threads either. And they are common only in two scenarios: if you set panic="abort", or special UB checks that the standard library does. The former is just a simple configuration change, the latter is not really something you can handle in any way.