5

Take a look:

use std::convert::{From, TryFrom};

fn main() {
  let size: usize = 42;
  let good: u128  = u128::try_from(size).unwrap(); // works fine
  let bad:  u128  = u128::from(size);              // doesn't compile!
}

As far as I know, usize is an integral type and those are never larger than 128 bits. Therefore, I see no way the usize -> u128 conversion can fail. So, why doesn't u128 implement From<usize>?

Update: Rust's documentation says:

From T for U implies Into U for T

Though usize -> u128 seems fine, u128 -> usize doesn't. OK, but why isn't Into<u128> implemented for usize instead?

passing_through
  • 1,778
  • 12
  • 24
  • 3
    [`usize`](https://doc.rust-lang.org/std/primitive.usize.html) is the size of a pointer. *In theory* you could have a system with an address space that required more than 128 bits for addressing...someday. Future proofing? ;-) – T.J. Crowder Jul 10 '20 at 10:39
  • “From T for U implies Into U for T” in this case, it would mean that both `usize -> u128` and `u128 <- usize` are fine. It says nothing about `u128 -> usize`. – mcarton Jul 10 '20 at 11:21

2 Answers2

5

Though usize -> u128 seems fine, u128 -> usize doesn't. OK, but why isn't Into implemented for usize instead?

Because while usize is guaranteed to always ever be at least 16 bits as far as Rust is concerned, it's not guaranteed to always ever be at most 64 bits.

It seems unlikely to ever be useful but technically nothing precludes 256 bits pointers, and since usize is guaranteed to be pointer-sized it would make the usize -> u128 conversion failible.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • 1
    Wouldn't the normal thing be to make it conditionally defined if the target platform usize is <= 128bits only. So it always is there and compiles, but if you ever target the crazy hypothetical platform with 256bit pointers, it won't be defined and your program won't compile. – Eloff Jul 20 '21 at 17:37
  • No, making core stdlib trait "conditionally defined" is not a normal thing, at least for the standard library. The normal thing for the standard library is to define platform-specific extension traits, which is not relevant here. – Masklinn Jul 20 '21 at 19:36
  • my approach seems much better than there being no trait defined at all for all platforms, when in fact it could currently be defined on all supported platforms. Whether there's precedent for that or not, isn't really important. – Eloff Jul 21 '21 at 21:27
  • "More convenient" does not mean "better". And precedent is in fact important, core traits disappearing is a significant policy change, not an innocuous difference of opinion. See also: #37423, #70460 – Masklinn Jul 22 '21 at 06:13
0

The document of From trait says

Note: This trait must not fail. If the conversion can fail, use TryFrom.

Since you will not know whether usize can hold a u16/u32/u64/u128 value(depending on your compile target), all of these primitive types implement TryFrom instead of From.

In Rust document, implies means when you have a type implements From, the compiler will give you an Into for free(note that the opposite is not true). The same idea applies to TryFrom and TryInto.So the following code will work as expected.

use std::convert::{TryFrom,TryInto};

fn main() {
  let size: usize = 42;
  let good: u128  = u128::try_from(size).unwrap();
  let doublegood:usize = good.try_into().unwrap();
}
whilrun
  • 1,701
  • 11
  • 21
  • You're right but please check the updated post: why doesn't `usize` implement `Into`? I believe it doesn't imply `From` (which would be unsafe) or anything else. – passing_through Jul 10 '20 at 11:07
  • 1
    @passing_through believe it is designed to be consistent since the conversion from usize to u32,u16, and u8 is not guaranteed in today's hardware. Rust is facing the future and we may see that one day 128 bit or 256 bit CPU will be installed on PCs. If that day really came, convertion from usize to u128 will not be safe neither. Thus if rust implemented an `Into` today, it must be changed to `TryInto` and any programs rely on this functionality will risk panic or not working completely. Furthermore, we already have a neat `as` in rust to do the unsafe convertions. – whilrun Jul 10 '20 at 11:14