# Proposal: integer conversion methods

#21

It would be helpful to have a couple code samples with a lot of casts in them. It is really hard to judge the ergonomics of any of these options looking at only a single conversion…

#22

Here’s a simple example that shows the reduced readability (vs `as`):

``````use core::num::Wrapping;
impl crypto_support for u32 {
// Define arithmetic operator on u32s for 32b x 32b -> 32b pseudo-modulo
// multiply that approximates multiplication modulo G(x) ≈ x.pow(32) + 1
#[inline(always)]
fn mul_mod_gx(self, rhs: &Self) -> Self {
let t: u64 = self as u64 * rhs as u64;     // 32b x 32b -> 64b multiply
(t as u32).wrapping_sub((t >> 32) as u32)  // subtract MS half from LS half
}
``````

versus

``````    (t.to_wrapping_u32()).wrapping_sub((t >> 32).to_wrapping_u32())
``````

#23

That situation looks not like a cast problem to me, but instead like

where it would be (using my current favourite proposal)

``````let (low, high) = self.mul_with_carry(*rhs, 0);
low.wrapping_sub(high)
``````

And that snippit is a great example of why `as` scares me:

That’s casting `&_` to `u64`, which feels to me like it could be a ptr2int cast. I assume it’s not, and it’s doing what you wanted, but it’s really quite hard to be sure.

#24

This was offered only as an example. In actual use the inputs are wrapped `u32`s (`w32`s). I’m fully aware that Rust’s references and unsafe raw pointers are not simply integers (unlike in many other languages).

Some architectures implement 32b x 32b -> 64b multiply in one instruction, others implement it in two related instructions (one generating the low-order 32b and the other the high-order 32b of the 64b result), while still others can’t generate the high-order 32b in hardware at all. It’s low-level differences such as that which drive much crypto to be written in assembly.

Addendum: I should have pointed out that LLVM does not provide the needed n x n -> 2n multiply, even though most architectures support it.

#25

(I still think we should allow implicit widening, that is, coerce for example `u8` to `u16`.)

#26

… or anything not larger to `usize` for indexing.

#27

Am I off base in thinking all of these conversion functions can be accomplished with a single macro?