How to ensure that Sync is implemented?

I am writing a library that exposes a few structs that I want to be Sync. What is the best way to ensure at compile time that it is implementing what I think it is? Right now I have some test code that passes a reference of the struct to a function fn is_sync(a :&Sync). That is pretty lame though.

Is there a way to annotate structs to say "I believe this is Sync/Send/Whatever" and generate an error if the compiler derives something else.

Thanks!

2 Likes

From the documentation for std::marker::Sync:

As one would expect, primitive types like u8 and f64 are all Sync, and so are simple aggregate types containing them

This means that any struct you implement that contains only fields which are Sync will automatically be Sync. To get a little more of a guarantee that a struct is Sync when you start doing things with it, there are a couple things you can do.

First of all, if your struct doesn't contain nothing but types that are obviously Sync, like the types mentioned in the docs there- for instance, if you have a generic parameter- you can use trait constraints like so:

struct<T: SomeTrait + Sync> MyStruct {
  some_thing: T
}

This way, even if you don't know right away what T is, you have specified that it must be Sync in any case.

Now, secondly, you can write functions to require its argument(s) be Sync also by using trait constraints.

fn do_a_thing<T: Sync>(thing: T) {
   // ... do something ...
}

Note that, in this case, the function do_a_thing would accept any argument that is Sync, so you'd probably want to also constrain T further by requiring it satisfy some other traits.

If all of this feels like too much work to make this requirement explicit, I'd suggest just relying on the fact that the compiler will make your struct Sync as long as all of its contents are Sync. You can safely rely on it to do that and, if you ever tried to use the struct in a way that violates Sync, it will tell you.

Well I'm looking for a way to have that error come up without using it. I declare this struct in a library and its used by another crate. I was looking for a way to annotate that struct to say "I think this is sync" and the compiler would error if it thinks otherwise.

A better definition for is_sync would be fn is_sync<T: Sync>() { }. Then you can test if the struct is Sync without having to construct an instance by doing is_sync::<MyStruct>(). I think checking in a test is the best option here but if you really want another option, you could do something like:

trait IsSync: Sync { } impl IsSync for MyStruct { }

4 Likes

This is the closest to what I was looking for. I was hoping for something provided by the language or stdlib though. Thanks!