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?
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
Either way, I'll make the change!
Sven van Caem said:
Yes, that's the one!
We may need to update llvm before you can switch that, but I don't recall fully
I know that llvm initially got the alignment of u128 wrong, but a fix eventually landed
I'm not sure which roc matches currently
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.
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
where left is the value roc returned, and right is the value that was expected
i128 seems to be slightly different each time, but u128 seems to be the same garbage each time
It's not a thorough test, but I'll change RustGlue back to emitting u128 instead of roc_std::U128 for now
I think this can be fixed the next time we update llvm
Though we may also need to update our u128 alignment in general in the compiler
Last updated: Jul 06 2025 at 12:14 UTC