What shall Sync mean across an .await?

Automatic derivation has a downside when you consider breaking changes. If your type is Sync and a change makes it not Sync anymore, that’s a breaking change that’s possibly overlooked. With the current rules at least the rule is very easy and the same for any auto trait. Adding special extra rules for Sync makes this a lot more brittle.

Furthermore every struct does offer something that can be done with a shared reference: Access fields. Even if they’re private, it is possible inside the implementation of the struct. It would then need to be the case that from the point of view of the implementor of a type’s API, that type is not Sync, whereas looking from outside it is. Quite a novel concept that probably has lots of problems attached to it.

The first problem here is that Stream does have a by-reference method

fn size_hint(&self) -> (usize, Option<usize>)

But apart from that, impl Stream usually means that the thing actually has a concrete type that’s just not mentioned. If you’re not careful about what you allow, a shared reference to it could actually be shared with some different code that knows the actual type and can do something with it. I’m not saying it’s impossible to argue like this, maybe the compiler could deduce something of the like in a sound manner. But even then the stability problem kicks in again. Best demonstrated by Stream itself, which didn’t have the size_hint method in the past. Adding that method would, in the presence of such new rules, have been a breaking change, and IMO quite surprisingly so.

I would also believe, regarding the argument of nothing can be done with a shared reference of a type, it can be Sync, that the wrapper type I proposed above does allow everything you could need. Using it furthermore would demonstrate some commitment to the fact that your type is indeed supposed to be Sync and will stay Sync (so no surprising breaking changes by accident). If you only apply the wrapper to non-Sync fields, you could even implement Stream with a sensible size_hint; the implementation of that method just can’t access some of the fields.

1 Like