How to mark *const Foo as Sync?

Rust 1.10 refuses to compile encoding_rs (it compiled under Rust 1.9), because in the FFI part I'm declaring pub static ISO_8859_8_I_ENCODING: *const Encoding = ISO_8859_8_I; and *const Encoding is not Sync.

The constant being assigned is pub const ISO_8859_8_I: &'static Encoding and Encoding has only immutable members.

Since the pointers don't change and point to immutable data, they should, in fact, be Sync.

How do I declare that this is the case? (unsafe impl Sync for *const Encoding {} is a syntax error.)

The best way is probably to create a new type to represent the constants and declare that Sync. I tried doing this on play and discovered to my surprise that the newtype doesn't require an explicit Sync declaration: Rust Playground

Oh, haha. My last example used static mut, which is the other thing you can do to make it work.

Here's the real newtype solution: Rust Playground

1 Like

Thank you. This works.

In retrospect, I should have set up Travis earlier so that I'd have seen this coming up with the trains.

Is there a reason you can't simply export a &'static Encoding?

AFAICT, Rust doesn't guarantee the ABI of &'static Encoding but does guarantee the ABI of *const Encoding. I need the ABI to match the ABI of extern const Encoding* const ISO_8859_8_I_ENCODING; in C.

If Rust actually guarantees that the ABI of pub static ISO_8859_8_I_ENCODING: &'static Encoding is the ABI of extern const Encoding* const ISO_8859_8_I_ENCODING;, that would make things easier. Is this actually guaranteed?

At runtime, a raw pointer * and a reference pointing to the same piece of data have an identical representation.

https://doc.rust-lang.org/stable/book/raw-pointers.html#references-and-raw-pointers