# Proposal: Platform-dependent conversions

**URL:** <https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032>\
**Category:** libs\
**Created:** [March 27, 2020, 2:37am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032 "2020-03-27T02:37:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![joshlf](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/joshlf/32/3815_2.png) [@joshlf](https://internals.rust-lang.org/u/joshlf)\
**Post date:** [March 27, 2020, 2:37am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/1 "2020-03-27T02:37:04Z")

</div>

In writing platform-dependent code, I often find myself wanting infallible conversions such as `u32 -> usize` (infallible on 32-bit and 64-bit platforms). `From` and `Into` impls on the primitive types are only provided for conversions which are infallible on _all_ platforms. How would folks feel about adding platform-dependent conversion traits that are the analogues of the `From` and `Into` traits, but implemented differently depending on the target platform?

Today, doing platform-dependent conversions like `u32 -> usize` usually entails a cast that just _happens_ to be lossless (e.g., `some_u32_value as usize`), possibly combined with a comment explaining why it happens to be lossless. With these traits, we could have the much more robust `usize::from(some_u32_value)` and all of the attendant goodness that type safety brings.

---

<div class="post-metadata">

**Author:** ![Tom-Phinney](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tom-phinney/32/3299_2.png) [@Tom-Phinney](https://internals.rust-lang.org/u/Tom-Phinney)\
**Post date:** [March 27, 2020, 2:41am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/2 "2020-03-27T02:41:37Z")

</div>

How are you going to gate this so that the same code, ported to a platform where `usize` is `u24`, generates compile-time errors? It seems to me that platform-dependent code fractures the Rust ecosystem, so that code which works on some platforms misbehaves on other platforms. Of course you can already use assembly, which usually is architecture-dependent and often platform-dependent.

---

<div class="post-metadata">

**Author:** ![joshlf](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/joshlf/32/3815_2.png) [@joshlf](https://internals.rust-lang.org/u/joshlf)\
**Post date:** [March 27, 2020, 2:48am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/3 "2020-03-27T02:48:50Z")

</div>

> [@Tom-Phinney](#):
>
> How are you going to gate this so that the same code, ported to a platform where `usize` is `u24` , generates compile-time errors? It seems to me that platform-dependent code fractures the Rust ecosystem, so that code which works on some platforms misbehaves on other platforms. Of course you can already use assembly, which usually is architecture-dependent and often platform-dependent.

The idea would be something like:

```rust
// name to be bikeshedded
trait From<T> {
    fn from(t: T) -> Self;
}

#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
impl From<u32> for usize { ... }

// ...and so on for other types

```

User code would fail to build on platforms without these impls just as code which relies on the platform-specific parts of `std` such as `std::os::unix` does today if built on the wrong platform.

As for the portability concern, there will always exist some code which is explicitly designed to not be portable - sometimes entire crates, and sometimes just individual modules or functions within a larger, platform-agnostic crate - and it would be good if that code were more type safe.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [March 27, 2020, 2:56am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/4 "2020-03-27T02:56:28Z")

</div>

If you use `std::sys::unix`, it's explicit that you're doing something target specific.

If you have a function that takes `Into<usize>` and you give it a `u64` computed elsewhere, you might not even realize that you just wrote code that only works on 64-bit targets.

---

<div class="post-metadata">

**Author:** ![joshlf](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/joshlf/32/3815_2.png) [@joshlf](https://internals.rust-lang.org/u/joshlf)\
**Post date:** [March 27, 2020, 2:59am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/5 "2020-03-27T02:59:22Z")

</div>

> [@cuviper](#):
>
> If you have a function that takes `Into<usize>` and you give it a `u64` computed elsewhere, you might not even realize that you just wrote code that only works on 64-bit targets.

In case it wasn't clear, my proposal is to introduce _new_ traits, not re-use the existing ones. Maybe names like `PlatformFrom` or something would be better in order to be explicit?

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [March 27, 2020, 3:20am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/6 "2020-03-27T03:20:06Z")

</div>

Ah, you said _analogues_ of the `From` and `Into` traits, I missed that. I do think they should be named distinctly, since the current traits are even in the prelude.

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [March 27, 2020, 3:29am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/7 "2020-03-27T03:29:53Z")

</div>

For some relevant prior discussions, see [Numeric .into() should not require everyone to support 16-bit and 128-bit usize](https://internals.rust-lang.org/t/numeric-into-should-not-require-everyone-to-support-16-bit-and-128-bit-usize/3609).

Tangentially related, there have also been discussions around allowing some traits that operate on `usize` (like `Index`) to take other integer types, which would reduce the need for conversions.

---

<div class="post-metadata">

**Author:** ![joshlf](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/joshlf/32/3815_2.png) [@joshlf](https://internals.rust-lang.org/u/joshlf)\
**Post date:** [March 27, 2020, 4:55am UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/8 "2020-03-27T04:55:00Z")

</div>

Thanks for the feedback, folks! I've posted a [pre-RFC](https://internals.rust-lang.org/t/pre-rfc-platformfrom-and-platforminto/12033).

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 27, 2020, 2:28pm UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/9 "2020-03-27T14:28:29Z")

</div>

I'm definitely annoyed every time I write my multi-megabyte-large executables that process gigabytes of data in RAM, but have to do unchecked silently-truncating `as` casts, because Rust wants my code to compile without warnings on 16-bit platforms.

I thought fixes for `usize` were blocked on portability lints:

> <https://github.com/rust-lang/rfcs/blob/master/text/1868-portability-lint.md>

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [June 25, 2020, 2:28pm UTC](https://internals.rust-lang.org/t/proposal-platform-dependent-conversions/12032/10 "2020-06-25T14:28:34Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
