What is the status on the panic-free subset of Rust idea?

Indexing syntax is unavoidably a problem, because container[index] syntax creates a place, not a value, and you can only have an Option<_> of a value. And indexing creating a place is a fundamental necessity for &v[i] and &mut v[i] to reference the item in the container.

Division, on the other hand, could theoretically be subset to panic-free already by only allowing integer division by NonZero instead of by primitive integers.

But also, just using methods isn't completely unreasonable. It won't look like particularly nice Rust code anymore, but that's unfortunately a known compromise required to get panic freedom. The entire reason panics exist is because some way to respond to "impossible" situations is necessary for ergonomics, and a panic is much nicer than just a raw abort crash. It's a standard error response hook for fatal errors.

It certainly would be nice if all code precisely tracked what conditions potentially cause panics, with similar precision to how conventional Rust tracks unsafety (potential UB), but it's just reality that bugs happen. Personally, I'd rather have code written that panics when some case thought to be entirely impossible happens, instead of getting UB. And in some cases, getting an erroneous None result when Some(_) is correct instead of a bug indicating panic is actually worse for overall resiliency, since None is an expected result for other cases.

The general "solution" for panic freedom is to return Result<T, AppError> everywhere. But the funny thing is, this is only really an improvement if that code path was already producing a Result. If it just returns T otherwise, sure side table unwinding isn't free, but it's still better than diluting icache with unused error resiliency code. (The optimization argument doesn't apply, since handling Result has the same barriers to optimization that unwinding does.) Even more so since parts of the

Unwinding is a general purpose solution which does consistently okay in roughly all cases. Propagation of Result::Err will be better in some cases and worse in others. Really, I think the "ideal" handling for panics in high-resiliency systems is to loop { thread::sleep() } in the panic handler/hook, and turn them into a leak of resources held by the thread. Rust programs' resource usage is good enough that this can still remain competitive.

2 Likes