I was thinking about this when Proposal: integer conversion methods came up and then this week I was watching @nikomatsakis’ PLISS talk (specifically, the part about explicit stuff potentially going implicit over time) and decided to put this into a pre-RFC. Happy to get feedback about what I might be missing here (since there didn’t seem to be any negative feedback when I mentioned it in the previous thread) and what else would need to be in an RFC for this.
- Feature Name: implicit-number-type-widening
- Start Date: 2019-06-19
Summary
In case where the coercion can be done losslessly and cheaply, convert between integer and floating point types without explicit syntax (like as
or .into()
or u64::from(v)
). This would include:
-
i8
->i32
(all signed integer types into larger signed integer types) -
u8
->u64
(all unsigned integer types into larger unsigned integer types) -
f32
->f64
(all floating point types into larger floating point types) -
u8
->i16
(all unsigned integer types to signed integer types that can fit all their values)
Motivation
Currently, all of these type conversions must appear explicitly in syntax. However, this feels overly cautious for conversions that can be done losslessly and cheaply. Moreover, allowing the lossless and cheap cases to be implicit would serve to better highlight the opposite cases (where there is a danger of data loss).
Guide-level explanation
In addition to the implicit coercions that we have today (like dereferencing or referencing), extend implicit conversions to allow these to happen.
@Tom-Phinney in the previous thread also specifically called out the pervasive use of usize
for indexing, so that it would be nice if smaller types could trivially be used as indexes.
This should be fully backwards compatible, in that it strictly extends the set of code the compiler would accept. We might add lints in clippy to nudge users toward implicit conversions.
The new behavior additionally seems more similar to C++ behavior, so it might lower the barrier to entry from that direction.
Reference-level explanation
Seems reasonably clear how this should work, but please tell me what I might be missing.
Drawbacks
Of course this makes things more implicit, and we’ve seen in the past that a part of the community really appreciates how many things in Rust take explicit syntax.
Rationale and alternatives
-
Do nothing: to some extent this is more like a paper cut than anything else.
-
Some more constrained set of coercions: maybe extending
i
toi
andu
tou
is less controversial than extendingu
toi
and/or extendingf32
tof64
.
Prior art
C++ has similar implicit type conversions; I found this article that explains it a bit. It looks like Java (and Kotlin) don’t have this.
I’d be happy to hear about what Haskell and OCaml do. My 10.000-foot view is that probably they’re not as concerned about having separate types for all the integer widths so this isn’t as relevant to those?
Dynamic languages obviously also do stuff like this, but I’m not sure it is as relevant; on the other hand, for the part of our community that comes from dynamic languages (which includes me, having done a lot of Python), having to explicitly write out lossless & cheap conversions is maybe more annoying.
Unresolved questions
Template
- What parts of the design do you expect to resolve through the RFC process before this gets merged?
- What parts of the design do you expect to resolve through the implementation of this feature before stabilization?
- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?
Future possibilities
Template
Think about what the natural extension and evolution of your proposal would be and how it would affect the language and project as a whole in a holistic way. Try to use this section as a tool to more fully consider all possible interactions with the project and language in your proposal. Also consider how the this all fits into the roadmap for the project and of the relevant sub-team.
This is also a good place to “dump ideas”, if they are out of scope for the RFC you are writing but otherwise related.
If you have tried and cannot think of any future possibilities, you may simply state that you cannot think of anything.
Note that having something written down in the future-possibilities section is not a reason to accept the current or a future RFC; such notes should be in the section on motivation or rationale in this or subsequent RFCs. The section merely provides additional information.