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

Remove unneeded Send/Sync bounds on Arc, Mutex, RwLock and sync::mpsc #23176

Merged
merged 3 commits into from
Apr 2, 2015

Conversation

huonw
Copy link
Member

@huonw huonw commented Mar 8, 2015

These types had many instances of T: Send + Sync in places they were not necessary.

In fact, the only place they are required is when considering under what circumstances can Arc<T> (etc.) be sent/shared across thread boundaries, i.e. the only place it matters is the unsafe impls of Send and Sync. It is perfectly safe for an Arc<T> to stay on and be used on a single thread if T doesn't satisfy the necessary bounds. It just acts like a (expensive) Rc<T>. The added flexibility may be convenient in generic code. (Similar reasoning applies to Mutex, RwLock and sync::mpsc. See commit messages for some more details.)

This also fixes a hole, where Arc::new has no bounds on T, but Drop for Arc<T> requires T: Send + Sync (meaning one could theoretically create an Arc type which has no destructor, although the compiler mishandles this case anyway).

huonw added 2 commits March 8, 2015 21:59
The requirement `T: Send + Sync` only matters if the `Arc` crosses
thread boundaries, and that is adequately controlled by the impls of
`Send`/`Sync` for `Arc` itself. If `T` doesn't satisfy the bounds, then
the `Arc` cannot cross thread boundaries and so everything is still
safe (`Arc` just acts like an expensive `Rc`).
The requirements `T: Send` and `T: Send + Sync` for `Mutex` and `RwLock`
respectively only matter if those types are shared/sent across thread
boundaries, and that is adequately controlled by the impls of
`Send`/`Sync` for them. If `T` doesn't satisfy the bounds, then
the types cannot cross thread boundaries and so everything is still
safe (the two types just act like an expensive `RefCell`).
@rust-highfive
Copy link
Collaborator

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

The requirements `T: Send` only matter if the channel crosses thread
boundaries i.e. the `Sender` or `Reciever` are sent across thread
boundaries, and which is adequately controlled by the impls of `Send`
for them. If `T` doesn't satisfy the bounds, then the types cannot cross
thread boundaries and so everything is still safe (the pair of types
collectively behave like a `Rc<RefCell<VecDeque>>`, or something of that
nature).
@huonw
Copy link
Member Author

huonw commented Mar 8, 2015

Alternatively, we could tighten up these types and make them require the relevant bounds everywhere (closing the Arc hole), "just in case". Taking that approach should be able to be relaxed to the approach in this PR backwards compatibly (unless we get some sort of implied bounds and use them for Arc). cc rust-lang/rfcs#590

@alexcrichton
Copy link
Member

I've seen this definitely assist in #[derive] implementations in the past (as you don't have to insert the extra bounds manually). My only (very minor) concern would be about error messages. Previously channel::<Rc<T>> would provide a nice error message on construction, but I presume it yields basically the same error message when it crosses threads? It's a little unfortunate to get the error much later, but I also prefer this as it's strictly more flexibly (especially with generics as you say).

r+ from me, but would like a second opinion from @brson or @aturon as well.

@brson
Copy link
Contributor

brson commented Mar 9, 2015

It seems like there's a policy that is unclear here, and these bounds may be tighter than necessary on purpose. I do have a vague recollection that we wanted bounds on types at some point for reasons similar to what @alexcrichton was saying.

@aturon
Copy link
Member

aturon commented Mar 10, 2015

I am inclined not to take this step, and instead to further tighten up the use of Send per rust-lang/rfcs#590

Like @alexcrichton, I'm worried about error messages and clarity here.

Further, I'm not convinced about the generic programming angle. In a case where you're generic enough to not be able to send an Arc value, you are therefore unable to make use of Arc beyond what Rc offers. In other words, the only reason to choose Arc is if you do want to communicate between threads, and you can only do that if you have sufficient type constraints anyway.

Finally, as you point out, keeping the bounds tighter is the more conservative option.

huonw added a commit to huonw/rust that referenced this pull request Apr 1, 2015
These types are purely designed for concurrent code, and, at the moment,
are restricted to be used in those situations. This solidifies that goal
by imposing a strict restriction on the generic types from the start,
i.e. in the definition itself.

This is the opposite to rust-lang#23176 which relaxes the bounds entirely (it is
backwards compatible to switch to that more flexible approach).

Unfortunately the message-passing primitives in std (the return value
from a thread, and sync::mpsc) aren't great about how they work with
mutability and sharing, and so require hacky error-prone `unsafe impl`s.
However, they are purely implementation details: the interface isn't
affected by having to make that internal change, and clean-ups to the
code should be able to remove the hacks.
@huonw
Copy link
Member Author

huonw commented Apr 1, 2015

Tighter bounds implemented in #23954.

@huonw huonw closed this Apr 1, 2015
@huonw huonw deleted the rm-bounds branch April 1, 2015 22:27
@huonw huonw restored the rm-bounds branch April 1, 2015 22:27
@huonw huonw reopened this Apr 1, 2015
@huonw
Copy link
Member Author

huonw commented Apr 1, 2015

@aturon relaxed his objection after discussion on IRC (start, end).

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Apr 1, 2015

📌 Commit 0f6b43a has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Apr 2, 2015

⌛ Testing commit 0f6b43a with merge c271382...

@bors
Copy link
Contributor

bors commented Apr 2, 2015

💔 Test failed - auto-mac-64-opt

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Apr 2, 2015
@bors bors merged commit 0f6b43a into rust-lang:master Apr 2, 2015
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

Successfully merging this pull request may close these issues.

6 participants