Skip to content

Commit d0429d6

Browse files
committed
---
yaml --- r: 229223 b: refs/heads/try c: 50dd497 h: refs/heads/master i: 229221: 8664d4c 229219: 36fbc79 229215: d86a610 v: v3
1 parent 36567db commit d0429d6

File tree

206 files changed

+1519
-861
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

206 files changed

+1519
-861
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 340c25aebfee25534b8b95fa7ed7afd35e0b2e4b
4+
refs/heads/try: 50dd4977fda23d857d27ebae432c7a22f60d7489
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/mk/main.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
######################################################################
1414

1515
# The version number
16-
CFG_RELEASE_NUM=1.3.0
16+
CFG_RELEASE_NUM=1.4.0
1717

1818
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
1919
# NB Make sure it starts with a dot to conform to semver pre-release

branches/try/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. Mostly critically, data accesses are how data races
130+
inconsistently as it wants. Most 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/try/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 design your own
10+
However the way Rust models concurrency makes it relatively easy to 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/try/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 nice because you don't need to worry about
123+
In general this works really nicely 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/try/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's possible to conditionally initialize, deinitialize, and
4+
We have seen that it'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/try/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 never read dangling references. However up to this point we have only ever
4+
that we 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/try/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 with through the `Send` and `Sync` traits.
6+
captures this 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 that they are correctly
14+
implement, and other unsafe code can assume 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/try/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 &'a str` would be a subtype of `&mut &'static str`,
97-
since `&'a str` is a subtype of `&'static str`. Therefore the lifetime of
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
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/try/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 has a destructor.
80+
before it ends, if it 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/try/src/doc/reference.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,9 @@ 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). In the transcriber, the designator is already known, and so
542-
only the name of a matched nonterminal comes after the dollar sign.
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.
543544

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

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

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

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.
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.
143155

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:
150156

151157
```ignore
152158
use std::thread;
153-
use std::sync::Mutex;
159+
use std::sync::Arc;
154160
155161
fn main() {
156-
let mut data = Mutex::new(vec![1, 2, 3]);
162+
let mut data = Arc::new(vec![1, 2, 3]);
157163
158164
for i in 0..3 {
159-
let data = data.lock().unwrap();
165+
let data = data.clone();
160166
thread::spawn(move || {
161167
data[i] += 1;
162168
});
@@ -166,29 +172,29 @@ fn main() {
166172
}
167173
```
168174

169-
Here's the error:
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.
170179

171180
```text
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-
^~~~~~~~~~~~~
181+
<anon>:11:24 error: cannot borrow immutable borrowed content as mutable
182+
<anon>:11 data[i] += 1;
183+
^~~~
178184
```
179185

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:
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.
183190

184-
```ignore
185-
fn lock(&self) -> LockResult<MutexGuard<T>>
186-
```
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.
187194

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

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

193199
```rust
194200
use std::sync::{Arc, Mutex};
@@ -209,9 +215,31 @@ fn main() {
209215
}
210216
```
211217

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:
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:
215243

216244
```rust
217245
# use std::sync::{Arc, Mutex};

branches/try/src/doc/trpl/generics.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Generics are called ‘parametric polymorphism’ in type theory,
66
which means that they are types or functions that have multiple forms (‘poly’
77
is multiple, ‘morph’ is form) over a given parameter (‘parametric’).
88

9-
Anyway, enough with type theory, let’s check out some generic code. Rust’s
9+
Anyway, enough type theory, let’s check out some generic code. Rust’s
1010
standard library provides a type, `Option<T>`, that’s generic:
1111

1212
```rust
@@ -27,7 +27,7 @@ let x: Option<i32> = Some(5);
2727

2828
In the type declaration, we say `Option<i32>`. Note how similar this looks to
2929
`Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
30-
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`.
30+
the right-hand side of the binding, we make a `Some(T)`, where `T` is `5`.
3131
Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t
3232
match, we’d get an error:
3333

@@ -101,11 +101,6 @@ fn takes_two_things<T, U>(x: T, y: U) {
101101
}
102102
```
103103

104-
Generic functions are most useful with ‘trait bounds’, which we’ll cover in the
105-
[section on traits][traits].
106-
107-
[traits]: traits.html
108-
109104
## Generic structs
110105

111106
You can store a generic type in a `struct` as well:
@@ -122,3 +117,28 @@ let float_origin = Point { x: 0.0, y: 0.0 };
122117

123118
Similarly to functions, the `<T>` is where we declare the generic parameters,
124119
and we then use `x: T` in the type declaration, too.
120+
121+
When you want to add an implementation for the generic struct, you just
122+
declare the type parameter after the `impl`:
123+
124+
```rust
125+
# struct Point<T> {
126+
# x: T,
127+
# y: T,
128+
# }
129+
#
130+
impl<T> Point<T> {
131+
fn swap(&mut self) {
132+
std::mem::swap(&mut self.x, &mut self.y);
133+
}
134+
}
135+
```
136+
137+
So far you’ve seen generics that take absolutely any type. These are useful in
138+
many cases: you’ve already seen `Option<T>`, and later you’ll meet universal
139+
container types like [`Vec<T>`][Vec]. On the other hand, often you want to
140+
trade that flexibility for increased expressive power. Read about [trait
141+
bounds][traits] to see why and how.
142+
143+
[traits]: traits.html
144+
[Vec]: ../std/vec/struct.Vec.html

branches/try/src/doc/trpl/operators-and-overloading.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,55 @@ will let you do this:
8181
let p: Point = // ...
8282
let x: f64 = p + 2i32;
8383
```
84+
85+
# Using operator traits in generic structs
86+
87+
Now that we know how operator traits are defined, we can define our `HasArea`
88+
trait and `Square` struct from the [traits chapter][traits] more generically:
89+
90+
[traits]: traits.html
91+
92+
```rust
93+
use std::ops::Mul;
94+
95+
trait HasArea<T> {
96+
fn area(&self) -> T;
97+
}
98+
99+
struct Square<T> {
100+
x: T,
101+
y: T,
102+
side: T,
103+
}
104+
105+
impl<T> HasArea<T> for Square<T>
106+
where T: Mul<Output=T> + Copy {
107+
fn area(&self) -> T {
108+
self.side * self.side
109+
}
110+
}
111+
112+
fn main() {
113+
let s = Square {
114+
x: 0.0f64,
115+
y: 0.0f64,
116+
side: 12.0f64,
117+
};
118+
119+
println!("Area of s: {}", s.area());
120+
}
121+
```
122+
123+
For `HasArea` and `Square`, we just declare a type parameter `T` and replace
124+
`f64` with it. The `impl` needs more involved modifications:
125+
126+
```ignore
127+
impl<T> HasArea<T> for Square<T>
128+
where T: Mul<Output=T> + Copy { ... }
129+
```
130+
131+
The `area` method requires that we can multiply the sides, so we declare that
132+
type `T` must implement `std::ops::Mul`. Like `Add`, mentioned above, `Mul`
133+
itself takes an `Output` parameter: since we know that numbers don't change
134+
type when multiplied, we also set it to `T`. `T` must also support copying, so
135+
Rust doesn't try to move `self.side` into the return value.

0 commit comments

Comments
 (0)