From 05a2df52a497dbb2d5e2099b74e66fbcbfeac5b9 Mon Sep 17 00:00:00 2001 From: Daniel Franklin Date: Tue, 23 Mar 2021 20:37:35 +0000 Subject: [PATCH] Fix missing trait bounds --- src/send-and-sync.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/send-and-sync.md b/src/send-and-sync.md index 69845d6..87c8b6a 100644 --- a/src/send-and-sync.md +++ b/src/send-and-sync.md @@ -167,8 +167,8 @@ we're good. ```rust,ignore // Safety: No one besides us has the raw pointer, so we can safely transfer the -// Carton to another thread. -unsafe impl Send for Carton {} +// Carton to another thread if T can be safely transferred. +unsafe impl Send for Carton where T: Send {} ``` What about Sync? For `Carton` to be Sync we have to enforce that you can't @@ -181,8 +181,20 @@ sync either. ```rust,ignore // Safety: Our implementation of DerefMut requires writers to mutably borrow the // Carton, so the borrow checker will only let us have references to the Carton -// on multiple threads if no one has a mutable reference to the Carton. -unsafe impl Sync for Carton {} +// on multiple threads if no one has a mutable reference to the Carton. This +// means we are Sync if T is Sync. +unsafe impl Sync for Carton where T: Sync {} +``` + +When we assert our type is Send and Sync we need to enforce that every +contained type is Send and Sync. When writing custom types that behave like +standard library types we can assert that we have the same requirements. +For example, the following code asserts that a Carton is Send if the same +sort of Box would be Send, which in this case is the same as saying T is Send. + +```rust +# struct Carton(std::ptr::NonNull); +unsafe impl Send for Carton where Box: Send {} ``` TODO: better explain what can or can't be Send or Sync. Sufficient to appeal