Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8.2 "Send and Sync" appears to misdefine "Send" #453

Open
sethp opened this issue Jun 3, 2024 · 0 comments
Open

8.2 "Send and Sync" appears to misdefine "Send" #453

sethp opened this issue Jun 3, 2024 · 0 comments

Comments

@sethp
Copy link

sethp commented Jun 3, 2024

In reading https://doc.rust-lang.org/nomicon/send-and-sync.html for a definition of Send, I noticed that:

  1. When initially presented, Send is defined in terms of itself:

    A type is Send if it is safe to send it to another thread.

    Which should maybe read something like "if it is safe to pass ownership from one thread to another" or "if it is safe for the same inhabitant of the type to be used in different threads at different times."

  2. Later in the chapter, Send appears to be confused for Sync:

    Finally, let's think about whether our Carton is Send and Sync. Something can safely be Send unless it shares mutable state with something else without enforcing exclusive access to it. Each Carton has a unique pointer, so we're good.

    The middle sentence describes what it means to be !Sync, I believe, rather than !Send. I'm also not convinced a unique pointer is sufficient to imply that a type is Send—consider that the referent may be in the thread's local storage, or on the stack.

As a suggestion, it's probably more useful to provide counter-examples (what makes a type !Send) than attempting a constructive proof here. There's an excellent post on the user forums that discusses what it means to be !Send + Sync: https://users.rust-lang.org/t/example-of-a-type-that-is-not-send/59835/3

It might be further worth breaking down what it means to be each of:

  • !Send + !Sync (statics are a great example here)
  • Send + !Sync ("must be called on the main UI thread" functions, perhaps?)
  • !Send + Sync (as above)

Finally, it might be worth addressing types that are temporarily !Sync near when they are sent across threads; I'm imagining a sample data race repaired by adding appropriate memory barriers or adjusting atomic ordering constraints. I believe such types to contain potentially correct & useful programs that the (current) Rust typing system does not have a way to accept: a topic that seems like a good fit for the 'nomicon.

See also:

#92 —which I believe a fix to this issue would also address
#307 —a quick fix in the same neighborhood (though to be honest I just skipped the initial sentence)
#436 —section 10.1.2 muddies the waters further by appearing to use T: Send + Sync as a stand-in for T is "thread-safe" without being particularly explicit about the differences. It might be more clear to discuss what happens to Arc<T>'s Send-soundness when T: !Sync, and vice versa (e.g. why is Arc<T>: !Sync when T: !Send?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant