google/zerocopy

Build failure in v0.8.0-alpha.7 on Cortex M

dhardy opened this issue · 5 comments

$ cargo build --target=thumbv6m-none-eabi --no-default-features
   Compiling zerocopy v0.8.0-alpha.7
error[E0412]: cannot find type `AtomicI64` in module `core::sync::atomic`
    --> /home/dhardy/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.8.0-alpha.7/src/util.rs:434:29
     |
434  |           core::sync::atomic::AtomicI64 [i64],
     |                               ^^^^^^^^^ help: a struct with a similar name exists: `AtomicI16`
     |
    ::: /home/dhardy-extra/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:3055:1
     |
3055 | / atomic_int! {
3056 | |     cfg(target_has_atomic = "16"),
3057 | |     cfg(target_has_atomic_equal_alignment = "16"),
3058 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
3070 | |     i16 AtomicI16
3071 | | }
     | |_- similarly named struct `AtomicI16` defined here

error[E0412]: cannot find type `AtomicU64` in module `core::sync::atomic`
    --> /home/dhardy/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.8.0-alpha.7/src/util.rs:435:29
     |
435  |           core::sync::atomic::AtomicU64 [u64],
     |                               ^^^^^^^^^ help: a struct with a similar name exists: `AtomicU16`
     |
    ::: /home/dhardy-extra/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:3073:1
     |
3073 | / atomic_int! {
3074 | |     cfg(target_has_atomic = "16"),
3075 | |     cfg(target_has_atomic_equal_alignment = "16"),
3076 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
...    |
3088 | |     u16 AtomicU16
3089 | | }
     | |_- similarly named struct `AtomicU16` defined here

For more information about this error, try `rustc --explain E0412`.
error: could not compile `zerocopy` (lib) due to 2 previous errors

This came up in rand CI. Alpha 6 passes.

Thanks for the report! We'll add thumbv6m-none-eabi to our CI and gate the internal use of the unavailable atomics accordingly.

In progress in #1087.

@dhardy Do you happen to know if there's a way to detect thumbv6m-none-eabi in particular, or at least a family of targets with similar architectures? Per this StackOverflow answer:

    {
        "target": "thumbv6m-none-eabi", 
        "arch": "arm", 
        "os": null, 
        "target-family": null
    }, 

If I'm reading this correctly, there's no way using #[cfg(...)] to detect this target (or other "thumb" targets, which all use "arch": "arm"). We can't just disable on all arm platforms without disabling on some arm platforms that actually support AtomicI64 and AtomicU64.

In principle we could teach build.rs to detect these targets, but I'd really love to avoid build.rs if possible.

@joshlf I think we would want to use #[cfg(target_has_atomic)], see:

That way we could only compile the implementations for AtomicU64 if #[cfg(target_has_atomic = "64")], AtomicPtr if #[cfg(target_has_atomic = "ptr")], etc...

Note that this will be a slightly conservative check, as some platforms have AtomicU32 but don't have #[cfg(target_has_atomic = "32")]. This is because those platforms only support load/store but not swap/compare_and_swap. This includes thumbv6m. However, this gate is probably better than nothing.

@joshlf I'm working on a fix for this, should be up soon

EDIT: Fix is #1091