Skip to content

Commit 1d930c8

Browse files
committed
---
yaml --- r: 223167 b: refs/heads/auto c: 6e311e7 h: refs/heads/master i: 223165: 3688eb9 223163: 29f10da 223159: 6129ce1 223151: 52131a4 223135: 6bd6368 223103: 3316690 v: v3
1 parent 46de83c commit 1d930c8

30 files changed

+335
-481
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
88
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
99
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1010
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
11-
refs/heads/auto: 0dc2910c9c7dc322a5a459c91688dc62ccce603c
11+
refs/heads/auto: 6e311e7af44510f048cfcbe27830e1b2cbda190b
1212
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1313
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336
1414
refs/tags/0.2: 1754d02027f2924bed83b0160ee340c7f41d5ea1

branches/auto/src/doc/nomicon/atomics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fundamentally unsynchronized and compilers are free to aggressively optimize
127127
them. In particular, data accesses are free to be reordered by the compiler on
128128
the assumption that the program is single-threaded. The hardware is also free to
129129
propagate the changes made in data accesses to other threads as lazily and
130-
inconsistently as it wants. Most critically, data accesses are how data races
130+
inconsistently as it wants. Mostly critically, data accesses are how data races
131131
happen. Data accesses are very friendly to the hardware and compiler, but as
132132
we've seen they offer *awful* semantics to try to write synchronized code with.
133133
Actually, that's too weak.

branches/auto/src/doc/nomicon/concurrency.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ an abstraction over them in a relatively uncontroversial way. Message passing,
77
green threads, and async APIs are all diverse enough that any abstraction over
88
them tends to involve trade-offs that we weren't willing to commit to for 1.0.
99

10-
However the way Rust models concurrency makes it relatively easy to design your own
10+
However the way Rust models concurrency makes it relatively easy design your own
1111
concurrency paradigm as a library and have everyone else's code Just Work
1212
with yours. Just require the right lifetimes and Send and Sync where appropriate
1313
and you're off to the races. Or rather, off to the... not... having... races.

branches/auto/src/doc/nomicon/destructors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ enum Link {
120120
will have its inner Box field dropped if and only if an instance stores the
121121
Next variant.
122122

123-
In general this works really nicely because you don't need to worry about
123+
In general this works really nice because you don't need to worry about
124124
adding/removing drops when you refactor your data layout. Still there's
125125
certainly many valid usecases for needing to do trickier things with
126126
destructors.

branches/auto/src/doc/nomicon/drop-flags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
% Drop Flags
22

33
The examples in the previous section introduce an interesting problem for Rust.
4-
We have seen that it's possible to conditionally initialize, deinitialize, and
4+
We have seen that's possible to conditionally initialize, deinitialize, and
55
reinitialize locations of memory totally safely. For Copy types, this isn't
66
particularly notable since they're just a random pile of bits. However types
77
with destructors are a different story: Rust needs to know whether to call a

branches/auto/src/doc/nomicon/dropck.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
% Drop Check
22

33
We have seen how lifetimes provide us some fairly simple rules for ensuring
4-
that we never read dangling references. However up to this point we have only ever
4+
that never read dangling references. However up to this point we have only ever
55
interacted with the *outlives* relationship in an inclusive manner. That is,
66
when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
77
`'b`. At first glance, this seems to be a meaningless distinction. Nothing ever

branches/auto/src/doc/nomicon/send-and-sync.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
Not everything obeys inherited mutability, though. Some types allow you to
44
multiply alias a location in memory while mutating it. Unless these types use
55
synchronization to manage this access, they are absolutely not thread safe. Rust
6-
captures this through the `Send` and `Sync` traits.
6+
captures this with through the `Send` and `Sync` traits.
77

88
* A type is Send if it is safe to send it to another thread.
99
* A type is Sync if it is safe to share between threads (`&T` is Send).
1010

1111
Send and Sync are fundamental to Rust's concurrency story. As such, a
1212
substantial amount of special tooling exists to make them work right. First and
1313
foremost, they're [unsafe traits][]. This means that they are unsafe to
14-
implement, and other unsafe code can assume that they are correctly
14+
implement, and other unsafe code can that they are correctly
1515
implemented. Since they're *marker traits* (they have no associated items like
1616
methods), correctly implemented simply means that they have the intrinsic
1717
properties an implementor should have. Incorrectly implementing Send or Sync can

branches/auto/src/doc/nomicon/subtyping.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ fn main() {
9393

9494
The signature of `overwrite` is clearly valid: it takes mutable references to
9595
two values of the same type, and overwrites one with the other. If `&mut T` was
96-
variant over T, then `&mut &'static str` would be a subtype of `&mut &'a str`,
97-
since `&'static str` is a subtype of `&'a str`. Therefore the lifetime of
96+
variant over T, then `&mut &'a str` would be a subtype of `&mut &'static str`,
97+
since `&'a str` is a subtype of `&'static str`. Therefore the lifetime of
9898
`forever_str` would successfully be "shrunk" down to the shorter lifetime of
9999
`string`, and `overwrite` would be called successfully. `string` would
100100
subsequently be dropped, and `forever_str` would point to freed memory when we

branches/auto/src/doc/nomicon/unchecked-uninit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ contain any `Drop` types.
7777
However when working with uninitialized memory you need to be ever-vigilant for
7878
Rust trying to drop values you make like this before they're fully initialized.
7979
Every control path through that variable's scope must initialize the value
80-
before it ends, if it has a destructor.
80+
before it ends, if has a destructor.
8181
*[This includes code panicking](unwinding.html)*.
8282

8383
And that's about it for working with uninitialized memory! Basically nothing

branches/auto/src/doc/reference.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,8 @@ balanced, but they are otherwise not special.
538538
In the matcher, `$` _name_ `:` _designator_ matches the nonterminal in the Rust
539539
syntax named by _designator_. Valid designators are `item`, `block`, `stmt`,
540540
`pat`, `expr`, `ty` (type), `ident`, `path`, `tt` (either side of the `=>`
541-
in macro rules), and `meta` (contents of an attribute). In the transcriber, the
542-
designator is already known, and so only the name of a matched nonterminal comes
543-
after the dollar sign.
541+
in macro rules). In the transcriber, the designator is already known, and so
542+
only the name of a matched nonterminal comes after the dollar sign.
544543

545544
In both the matcher and transcriber, the Kleene star-like operator indicates
546545
repetition. The Kleene star operator consists of `$` and parentheses, optionally

branches/auto/src/doc/trpl/concurrency.md

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -135,34 +135,28 @@ This gives us an error:
135135
^~~~
136136
```
137137

138-
Rust knows this wouldn't be safe! If we had a reference to `data` in each
139-
thread, and the thread takes ownership of the reference, we'd have three
140-
owners!
141-
142-
So, we need some type that lets us have more than one reference to a value and
143-
that we can share between threads, that is it must implement `Sync`.
144-
145-
We'll use `Arc<T>`, rust's standard atomic reference count type, which
146-
wraps a value up with some extra runtime bookkeeping which allows us to
147-
share the ownership of the value between multiple references at the same time.
148-
149-
The bookkeeping consists of a count of how many of these references exist to
150-
the value, hence the reference count part of the name.
151-
152-
The Atomic part means `Arc<T>` can safely be accessed from multiple threads.
153-
To do this the compiler guarantees that mutations of the internal count use
154-
indivisible operations which can't have data races.
138+
In this case, we know that our code _should_ be safe, but Rust isn't sure. And
139+
it's actually not safe: if we had a reference to `data` in each thread, and the
140+
thread takes ownership of the reference, we have three owners! That's bad. We
141+
can fix this by using the `Arc<T>` type, which is an atomic reference counted
142+
pointer. The 'atomic' part means that it's safe to share across threads.
155143

144+
`Arc<T>` assumes one more property about its contents to ensure that it is safe
145+
to share across threads: it assumes its contents are `Sync`. But in our
146+
case, we want to be able to mutate the value. We need a type that can ensure
147+
only one person at a time can mutate what's inside. For that, we can use the
148+
`Mutex<T>` type. Here's the second version of our code. It still doesn't work,
149+
but for a different reason:
156150

157151
```ignore
158152
use std::thread;
159-
use std::sync::Arc;
153+
use std::sync::Mutex;
160154
161155
fn main() {
162-
let mut data = Arc::new(vec![1, 2, 3]);
156+
let mut data = Mutex::new(vec![1, 2, 3]);
163157
164158
for i in 0..3 {
165-
let data = data.clone();
159+
let data = data.lock().unwrap();
166160
thread::spawn(move || {
167161
data[i] += 1;
168162
});
@@ -172,29 +166,29 @@ fn main() {
172166
}
173167
```
174168

175-
We now call `clone()` on our `Arc<T>`, which increases the internal count.
176-
This handle is then moved into the new thread.
177-
178-
And... still gives us an error.
169+
Here's the error:
179170

180171
```text
181-
<anon>:11:24 error: cannot borrow immutable borrowed content as mutable
182-
<anon>:11 data[i] += 1;
183-
^~~~
172+
<anon>:9:9: 9:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
173+
<anon>:11 thread::spawn(move || {
174+
^~~~~~~~~~~~~
175+
<anon>:9:9: 9:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
176+
<anon>:11 thread::spawn(move || {
177+
^~~~~~~~~~~~~
184178
```
185179

186-
`Arc<T>` assumes one more property about its contents to ensure that it is safe
187-
to share across threads: it assumes its contents are `Sync`. This is true for
188-
our value if it's immutable, but we want to be able to mutate it, so we need
189-
something else to persuade the borrow checker we know what we're doing.
180+
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
181+
[`lock`](../std/sync/struct.Mutex.html#method.lock)
182+
method which has this signature:
190183

191-
It looks like we need some type that allows us to safely mutate a shared value,
192-
for example a type that that can ensure only one thread at a time is able to
193-
mutate the value inside it at any one time.
184+
```ignore
185+
fn lock(&self) -> LockResult<MutexGuard<T>>
186+
```
194187

195-
For that, we can use the `Mutex<T>` type!
188+
Because `Send` is not implemented for `MutexGuard<T>`, we can't transfer the
189+
guard across thread boundaries, which gives us our error.
196190

197-
Here's the working version:
191+
We can use `Arc<T>` to fix this. Here's the working version:
198192

199193
```rust
200194
use std::sync::{Arc, Mutex};
@@ -215,31 +209,9 @@ fn main() {
215209
}
216210
```
217211

218-
219-
If we'd tried to use `Mutex<T>` without wrapping it in an `Arc<T>` we would have
220-
seen another error like:
221-
222-
```text
223-
error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
224-
thread::spawn(move || {
225-
^~~~~~~~~~~~~
226-
note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
227-
thread::spawn(move || {
228-
^~~~~~~~~~~~~
229-
```
230-
231-
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
232-
[`lock`](../std/sync/struct.Mutex.html#method.lock)
233-
method which has this signature:
234-
235-
```ignore
236-
fn lock(&self) -> LockResult<MutexGuard<T>>
237-
```
238-
239-
and because `Send` is not implemented for `MutexGuard<T>`, we couldn't have
240-
transferred the guard across thread boundaries on it's own.
241-
242-
Let's examine the body of the thread more closely:
212+
We now call `clone()` on our `Arc`, which increases the internal count. This
213+
handle is then moved into the new thread. Let's examine the body of the
214+
thread more closely:
243215

244216
```rust
245217
# use std::sync::{Arc, Mutex};

0 commit comments

Comments
 (0)