Hacker News new | ask | show | jobs
by dathinab 2171 days ago
1. Panicing is not in line with how `as` casts are supposed to act. (e.g. `u32value as u8` does not panic but just takes the "lower" one byte.)

2. This might (I haven't profiled it) introduce performance regressions in ways which should not happen.

3. Besides in some usages around `dyn` other usages of `as` get increasingly more alternatives. It's just a question of time until `as` (for int/float casts) is recommended to not be used at all, maybe even linted against.

4. Given precedence of many other programming languages people don't expect a "simple" float to int cast to be failable. (The new methods replacing `as` make the fallibility clear, as it's e.g. `u64::try_from(bigf64)`).

5. It's udef-ness is only detected/handled in llvm, _I don't know_ if llvm provides similar well integrated mechanisms for this as it does for integer overflows. If not that would be another problem.

2 comments

I came here with same question as davrosthedalek "Why doesn't it just panic?" and yours is an excellent and very convincing answer. Thanks for writing it up.
> Panicing is not in line with how `as` casts are supposed to act. (e.g. `u32value as u8` does not panic but just takes the "lower" one byte.)

So, instead of this being traditional UB, it was a combination of two separate issues:

- Rustc erroneously emitting code that exercised an LLVM UB case, and

- Imprecise Rust documentation around the exact behavior of float -> int ‘as’ casts

That phrasing seemingly implies that there was a generally-agreed intended behaviour for that case that was unfortunately neither documented nor actually exhibited. But that was not the case. The overflow behaviour of float-to-int casts was undefined, full stop. There was some consensus as to what such casts should not do, but no agreement on what the actual behaviour should be. Eventually, the discussion settled on defining casting overflow to saturate, and the implementation was altered to match.