This `fail!` is mildly unfortunate, because it ends up inside a loop, and unwinding makes it hard for LLVM to optimise.

Would it be possible to measure changing this to just returning `0`. (And the `cast(x).unwrap()` in `digit` to `cast(x).unwrap_or(0)`, just in case.)