Hacker News new | past | comments | ask | show | jobs | submit login

At least sources of panic! are easily greppable. Cutting corners on error handling is usually pretty obvious





I don't think grepping for panics is practical, unless you are trying to depend on exclusively no-panic libraries.

Even if you are no_std, core has tons of APIs like unwrap(), index slicing, etc. that can panic if you violate the preconditions. It's not practical to grep for all of them.


There is panic-analyzer [1] that searches for code that needlessly panics. You can also use the no-panic macro [2] to turn possible panics in a specific function (including main) into a compile error

1: https://crates.io/crates/panic-analyzer

2: https://crates.io/crates/no-panic


Panic-analyzer looks like it is based on heuristics, searching for known-panicing APIs. I tried it on a workspace that uses io::stdout() and it did not flag this as potentially panicing.

No-panic looks nifty: it appears to be reliable, which is great. I wish there was an easy way to automatically apply this annotation to every single function in a given file or crate.


I think the article is wrong in that std::io::stdout would be panicking, or that "the panic is reachable somehow". It's just the optimizer doesn't see it doesn't panic.

https://doc.rust-lang.org/beta/src/std/io/stdio.rs.html#674-...

The implementation calls indeed a panicking API, OnceLock::get_or_init:

https://doc.rust-lang.org/beta/std/sync/struct.OnceLock.html...

But it only panicks if it is being used in a wrong way, which it isn't. The usage is contained within the implementation of std::io::stdout, so it's an implementation detail.

It's a shame that there are no better ways to eliminate panics in case they are impossible to trigger. The article shows some tricks, but I think the language is missing still some expressability around this, and the stdlib should also thrive harder to actually get rid of hard-to-optimize links to panic runtime in case of APIs that don't actually panic.


If the only problem was OnceLock, the simplest solution would be to replace it with a const initializer.

The main reason getting panic-free stdout is hard, is that the STDOUT initializers both call allocating constructors, and LineWriter doesn't have non-allocating constructors.

Solving this elegantly seems hard.


Thanks for the clarification on OnceLock::get_or_init. It's interesting to know that this is dynamically unreachable, but in a way that the compiler could not statically prove.

I 100% agree with your last paragraph. I would love if the language and stdlib made it easier to make panic-free binaries.


There are panics that aren't greppable that way. For instance `some_array[past_bounds]` causes a panic.

It is interesting to consider how `panic!` serves as some documentation of explicitly giving up. Easy to see in a pull request. And having the string packed alongside it is nice.

Still miffed, but we'll get there.


I mean... rust modules aren't typically in your CWD, no? they're not in some node_modules that you can grep, but in a cargo folder with /all of the libraries you ever used/, not just the ones you have for this one project.

Putting them all in the project root takes just a single `cargo vendor` command.

But I would assume that for mozilla their entire CSS subsystem is pulled in as a git (hg?) submodule or something anyways.


not sure how the CSS subsystem is included (I remember it is shared with Servo?), but in general all of the Rust dependencies in mozilla-central is vendored, so nothing is in your ~/.cargo directory.

For what it's worth, eg vscode can jump to definition even when your code is in a different crate that's not in your repository.

If you run cargo vendor, they end up in a neat directory.



Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: