Stream: compiler development

Topic: improper_ctypes warning on rust glue generated u128


view this post on Zulip Sven van Caem (Nov 05 2024 at 09:41):

Rust glue currently uses Rust's u128/i128 types to represent Roc's U128/I128 types. This causes rustc to raise a warning:

warning: `extern` block uses type `u128`, which is not FFI-safe
  --> src/x86_64.rs:27:50
   |
27 |         fn roc__mainForHost_1_exposed_generic(_: *mut u128);
   |                                                  ^^^^^^^^^ not FFI-safe
   |
   = note: 128-bit integers don't currently have a known stable ABI
   = note: `#[warn(improper_ctypes)]` on by default

I've noticed roc_std contains U128/I128 implementations with explicitly specified alignment. I suspect the proper fix here would be to make Rust glue use these types instead?

view this post on Zulip Anton (Nov 05 2024 at 09:54):

I think so, I've solved a difficult bug in the past where we assumed a Roc type (don't remember which one) had the same representation as a similar Rust type but this assumption was incorrect

view this post on Zulip Sven van Caem (Nov 05 2024 at 09:55):

This one?

view this post on Zulip Sven van Caem (Nov 05 2024 at 09:56):

Either way, I'll make the change!

view this post on Zulip Anton (Nov 05 2024 at 10:19):

Sven van Caem said:

This one?

Yes, that's the one!

view this post on Zulip Brendan Hansknecht (Nov 05 2024 at 16:55):

We may need to update llvm before you can switch that, but I don't recall fully

view this post on Zulip Brendan Hansknecht (Nov 05 2024 at 16:55):

I know that llvm initially got the alignment of u128 wrong, but a fix eventually landed

view this post on Zulip Brendan Hansknecht (Nov 05 2024 at 16:56):

I'm not sure which roc matches currently

view this post on Zulip Sven van Caem (Nov 07 2024 at 09:08):

I've just tested it with the following function:

Numbers : { u128 : U128, i128 : I128 }

main : Numbers -> Numbers
main = \{ u128, i128 } -> { u128: 2 * u128, i128: 2 * i128 }

it seems roc_std's U128/I128 give incorrect results and Rust's u128 and i128 work just fine. I suppose it wasn't an oversight after all? It does mean we're stuck with the improper_ctypes warning though unless we choose to suppress it.

view this post on Zulip Sven van Caem (Nov 07 2024 at 09:20):

Here's the values it fails with:

---- glue_cli_run::u128_i128 stdout ----
thread 'glue_cli_run::u128_i128' panicked at crates/glue/tests/test_glue_cli.rs:277:13:
`roc` command had unexpected stderr: 🔨 Rebuilding platform...
thread 'main' panicked at src/lib.rs:24:5:
assertion `left == right` failed
  left: Numbers { i128: 281446803774592, u128: 922337203685477580798 }
 right: Numbers { i128: 170141183460469231731687303715884105726, u128: 340282366920938463463374607431768211454 }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

view this post on Zulip Sven van Caem (Nov 07 2024 at 09:21):

where left is the value roc returned, and right is the value that was expected

view this post on Zulip Sven van Caem (Nov 07 2024 at 09:23):

i128 seems to be slightly different each time, but u128 seems to be the same garbage each time

view this post on Zulip Sven van Caem (Nov 07 2024 at 09:25):

It's not a thorough test, but I'll change RustGlue back to emitting u128 instead of roc_std::U128 for now

view this post on Zulip Brendan Hansknecht (Nov 09 2024 at 06:40):

I think this can be fixed the next time we update llvm

view this post on Zulip Brendan Hansknecht (Nov 09 2024 at 06:40):

Though we may also need to update our u128 alignment in general in the compiler


Last updated: Jul 06 2025 at 12:14 UTC