dtolnay / linkme

Safe cross-platform linker shenanigans
Apache License 2.0
646 stars 41 forks source link

Try using `extern "Rust"` for extern statics #51

Closed dtolnay closed 2 years ago

dtolnay commented 2 years ago

The generated code for an distributed slice:

#[distributed_slice]
pub static MYSLICE: [&'static str] = [..];

currently contains something like:

#[cfg(any(target_os = "none", target_os = "linux", target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "illumos", target_os = "freebsd"))]
extern "C" {
    #[link_name = "__start_linkme_MYSLICE"]
    static LINKME_START: <[&'static str] as ::linkme::private::Slice>::Element;
    #[link_name = "__stop_linkme_MYSLICE"]
    static LINKME_STOP: <[&'static str] as ::linkme::private::Slice>::Element;
}

For identical code written by hand, ordinarily Rust would warn about the use of a repr(Rust) type in an extern "C" block. Maybe this warning is suppressed in macro-generated code, but anyway changing the block from extern "C" to extern "Rust" would eliminate it. These statics here only exist for interaction with other Rust compilation units, not C.

warning: `extern` block uses type `str`, which is not FFI-safe
  --> src/main.rs
   |
   |         static LINKME_START: <[&'static str] as ::linkme::private::Slice>::Element;
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
   |
   = note: `#[warn(improper_ctypes)]` on by default
   = help: consider using `*const u8` and a length instead
   = note: string slices have no C equivalent