Since discussion has slowed somewhat (thanks for all the feedback!), here’s my current thinking based on comments so far.
Interaction with type inferencing
First off, there have been a lot of concerns about type inference being affected. In my mind, coercion by necessity is decided after inferencing: since coercion needs to generate run-time code, it needs to have clear inputs on the source type and the destination type for a particular operation. Someone please tell me if this understanding doesn’t mesh with the way it’s implemented in rustc. As such, in my mind the proposed number type coercions by definition do not change the behavior of the type inferencer.
Allow-by-default lint
Second, I think it makes sense to have an allow-by-default lint that disables or warns about coercions in a particular crate, module or function. This could help with the case of hot loops or for those people who insist on Rust being a super-explicit language.
Scenarios
There seem to be three different pain points that could be improved. These might have different kinds of implementation methods – more trait implementations vs inserting widening conversions – but I think it still makes sense to discuss them in one RFC to make sure this is a coherent proposal.
Store
Store a value of some integer type into a slot (like a struct field, a local variable with a defined type, a return value or a formal function parameter). In this case I think it would make sense to apply coercion.
Comparison
When numbers of different types are compared, coerce the smaller type to the larger to enable the comparison.
Indexing
Allow indexing with different unsigned number types. The trick here is to make sure we don’t unduly affect portability, since the “native” index usize
type could be any of u16
, u32
or u64
in practice. The question is how much that matters since the collection length is the more important constraint here, and will often be more limiting than the platform’s size type length.
Coercions
As for the allowed coercions, I’m now thinking of the following:
- Signed fixed length integers to larger signed fixed length integers
- Unsigned fixed length integers to larger unsigned fixed length integers
- Unsigned fixed length integers to large enough signed fixed length integers
- Fixed length floating point types to larger floating point types
Conclusions
We could tweak the proposal along the scenarios axis and along the coercions axis, of course. Personally I’m least sure about the indexing part.
What do people think about this refined version?