Skip to content

Commit 02f7734

Browse files
committed
---
yaml --- r: 229224 b: refs/heads/try c: 4a68a7e h: refs/heads/master v: v3
1 parent d0429d6 commit 02f7734

File tree

6 files changed

+19
-152
lines changed

6 files changed

+19
-152
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: 50dd4977fda23d857d27ebae432c7a22f60d7489
4+
refs/heads/try: 4a68a7e1986c55855727c818ef272108f8fed32e
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

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

Lines changed: 7 additions & 27 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 type theory, let’s check out some generic code. Rust’s
9+
Anyway, enough with 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 make a `Some(T)`, where `T` is `5`.
30+
the right-hand side of the binding, we do 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,6 +101,11 @@ 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+
104109
## Generic structs
105110

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

118123
Similarly to functions, the `<T>` is where we declare the generic parameters,
119124
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: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -81,55 +81,3 @@ 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.

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

Lines changed: 7 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ As you can see, the `trait` block looks very similar to the `impl` block,
4747
but we don’t define a body, just a type signature. When we `impl` a trait,
4848
we use `impl Trait for Item`, rather than just `impl Item`.
4949

50-
## Traits bounds for generic functions
51-
52-
Traits are useful because they allow a type to make certain promises about its
53-
behavior. Generic functions can exploit this to constrain the types they
54-
accept. Consider this function, which does not compile:
50+
We can use traits to constrain our generics. Consider this function, which
51+
does not compile:
5552

5653
```rust,ignore
5754
fn print_area<T>(shape: T) {
@@ -78,7 +75,7 @@ fn print_area<T: HasArea>(shape: T) {
7875
}
7976
```
8077

81-
The syntax `<T: HasArea>` means any type that implements the `HasArea` trait.”
78+
The syntax `<T: HasArea>` means `any type that implements the HasArea trait`.
8279
Because traits define function type signatures, we can be sure that any type
8380
which implements `HasArea` will have an `.area()` method.
8481

@@ -155,63 +152,6 @@ We get a compile-time error:
155152
error: the trait `HasArea` is not implemented for the type `_` [E0277]
156153
```
157154

158-
## Traits bounds for generic structs
159-
160-
Your generic structs can also benefit from trait constraints. All you need to
161-
do is append the constraint when you declare type parameters. Here is a new
162-
type `Rectangle<T>` and its operation `is_square()`:
163-
164-
```rust
165-
struct Rectangle<T> {
166-
x: T,
167-
y: T,
168-
width: T,
169-
height: T,
170-
}
171-
172-
impl<T: PartialEq> Rectangle<T> {
173-
fn is_square(&self) -> bool {
174-
self.width == self.height
175-
}
176-
}
177-
178-
fn main() {
179-
let mut r = Rectangle {
180-
x: 0,
181-
y: 0,
182-
width: 47,
183-
height: 47,
184-
};
185-
186-
assert!(r.is_square());
187-
188-
r.height = 42;
189-
assert!(!r.is_square());
190-
}
191-
```
192-
193-
`is_square()` needs to check that the sides are equal, so the sides must be of
194-
a type that implements the [`core::cmp::PartialEq`][PartialEq] trait:
195-
196-
```ignore
197-
impl<T: PartialEq> Rectangle<T> { ... }
198-
```
199-
200-
Now, a rectangle can be defined in terms of any type that can be compared for
201-
equality.
202-
203-
[PartialEq]: ../core/cmp/trait.PartialEq.html
204-
205-
Here we defined a new struct `Rectangle` that accepts numbers of any
206-
precision—really, objects of pretty much any type—as long as they can be
207-
compared for equality. Could we do the same for our `HasArea` structs, `Square`
208-
and `Circle`? Yes, but they need multiplication, and to work with that we need
209-
to know more about [operator traits][operators-and-overloading].
210-
211-
[operators-and-overloading]: operators-and-overloading.html
212-
213-
# Rules for implementing traits
214-
215155
So far, we’ve only added trait implementations to structs, but you can
216156
implement a trait for any type. So technically, we _could_ implement `HasArea`
217157
for `i32`:
@@ -235,7 +175,7 @@ impl HasArea for i32 {
235175
It is considered poor style to implement methods on such primitive types, even
236176
though it is possible.
237177

238-
This may seem like the Wild West, but there are two restrictions around
178+
This may seem like the Wild West, but there are two other restrictions around
239179
implementing traits that prevent this from getting out of hand. The first is
240180
that if the trait isn’t defined in your scope, it doesn’t apply. Here’s an
241181
example: the standard library provides a [`Write`][write] trait which adds
@@ -400,10 +340,10 @@ This shows off the additional feature of `where` clauses: they allow bounds
400340
where the left-hand side is an arbitrary type (`i32` in this case), not just a
401341
plain type parameter (like `T`).
402342

403-
# Default methods
343+
## Default methods
404344

405-
If you already know how a typical implementor will define a method, you can
406-
let your trait supply a default:
345+
There’s one last feature of traits we should cover: default methods. It’s
346+
easiest just to show an example:
407347

408348
```rust
409349
trait Foo {

branches/try/src/libcollections/borrow.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ use self::Cow::*;
3838
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
3939
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
4040
///
41+
/// If you are implementing `Borrow` and both `Self` and `Borrowed` implement
42+
/// `Hash`, `Eq`, and/or `Ord`, they must produce the same result.
43+
///
4144
/// `Borrow` is very similar to, but different than, `AsRef`. See
4245
/// [the book][book] for more.
4346
///

branches/try/src/libcore/marker.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,7 @@ macro_rules! impls{
273273
/// even though it does not. This allows you to inform the compiler about certain safety properties
274274
/// of your code.
275275
///
276-
/// # A ghastly note 👻👻👻
277-
///
278-
/// Though they both have scary names, `PhantomData<T>` and 'phantom types' are related, but not
279-
/// identical. Phantom types are a more general concept that don't require `PhantomData<T>` to
280-
/// implement, but `PhantomData<T>` is the most common way to implement them in a correct manner.
276+
/// Though they both have scary names, `PhantomData<T>` and "phantom types" are unrelated. 👻👻👻
281277
///
282278
/// # Examples
283279
///

0 commit comments

Comments
 (0)