Description
When building a project with serde
dependency for i686-unknown-linux-gnu
target, the following error message appear:
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> /home/xxxxx/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mbedtls-0.12.5/src/cipher/raw/serde.rs:356:5 | 356 | ::core::mem::transmute(ctx) | ^^^^^^^^^^^^^^^^^^^^^^ | = note: source type: mbedtls_sys::gcm_context (3136 bits) = note: target type: [u8; 400] (3200 bits)
How to reproduce
-
Create a new project with only the following dependencies in
Cargo.toml
:
mbedtls = "0.13.2" serde = "1.0.219"
-
Then simply compile with
cargo build --target i686-unknown-linux-gnu
Troubleshoot
This seems to be an alignment error occurring for 32bits architecture.
I pinpointed it to the definition of _SIZE_OF_GCM_CONTEXT
:
const _SIZE_OF_GCM_CONTEXT: usize = (_SIZE_OF_CIPHER_CONTEXT + 7) / 8 * 8 + 8 * 16 + 8 * 16 + 8 + 8 + 16 + 16 + 16 + 8; // first summand: cipher_context 8-byte aligned
IMO, there are 2 errors in it:
- As the comment suggests,
_SIZE_OF_CIPHER_CONTEXT
is 8 byte aligned. To be ported to 32 bits architecture, it should be aligned onsize_of::<usize>()
. - The very last operand (8) is the size of
::types::raw_types::c_int
, which should also besize_of::<usize>()
.
Therefore, we have the following expression:
const _SIZE_OF_GCM_CONTEXT: usize = (_SIZE_OF_CIPHER_CONTEXT + size_of::<usize>() - 1) / size_of::<usize>() * size_of::<usize>() + 8 * 16 + 8 * 16 + 8 + 8 + 16 + 16 + 16 + size_of::<usize>();
I tested it on default target (64bits) and i686-unknown-linux-gnu
, and it worked great.