Skip to content

Commit 593db00

Browse files
committed
Auto merge of #23681 - alexcrichton:rollup, r=alexcrichton
2 parents 123a754 + 3021d4c commit 593db00

File tree

171 files changed

+2212
-1034
lines changed

Some content is hidden

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

171 files changed

+2212
-1034
lines changed

src/doc/reference.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ be undesired.
12651265
* Sending signals
12661266
* Accessing/modifying the file system
12671267
* Unsigned integer overflow (well-defined as wrapping)
1268-
* Signed integer overflow (well-defined as two's complement representation
1268+
* Signed integer overflow (well-defined as twos complement representation
12691269
wrapping)
12701270

12711271
#### Diverging functions
@@ -2961,10 +2961,10 @@ meaning of the operators on standard types is given here.
29612961
: Exclusive or.
29622962
Calls the `bitxor` method of the `std::ops::BitXor` trait.
29632963
* `<<`
2964-
: Logical left shift.
2964+
: Left shift.
29652965
Calls the `shl` method of the `std::ops::Shl` trait.
29662966
* `>>`
2967-
: Logical right shift.
2967+
: Right shift.
29682968
Calls the `shr` method of the `std::ops::Shr` trait.
29692969

29702970
#### Lazy boolean operators

src/doc/trpl/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* [More Strings](more-strings.md)
2323
* [Patterns](patterns.md)
2424
* [Method Syntax](method-syntax.md)
25+
* [Associated Types](associated-types.md)
2526
* [Closures](closures.md)
2627
* [Iterators](iterators.md)
2728
* [Generics](generics.md)

src/doc/trpl/associated-types.md

+202
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
% Associated Types
2+
3+
Associated types are a powerful part of Rust's type system. They're related to
4+
the idea of a 'type family', in other words, grouping multiple types together. That
5+
description is a bit abstract, so let's dive right into an example. If you want
6+
to write a `Graph` trait, you have two types to be generic over: the node type
7+
and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
8+
this:
9+
10+
```rust
11+
trait Graph<N, E> {
12+
fn has_edge(&self, &N, &N) -> bool;
13+
fn edges(&self, &N) -> Vec<E>;
14+
// etc
15+
}
16+
```
17+
18+
While this sort of works, it ends up being awkward. For example, any function
19+
that wants to take a `Graph` as a parameter now _also_ needs to be generic over
20+
the `N`ode and `E`dge types too:
21+
22+
```rust,ignore
23+
fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... }
24+
```
25+
26+
Our distance calculation works regardless of our `Edge` type, so the `E` stuff in
27+
this signature is just a distraction.
28+
29+
What we really want to say is that a certain `E`dge and `N`ode type come together
30+
to form each kind of `Graph`. We can do that with associated types:
31+
32+
```rust
33+
trait Graph {
34+
type N;
35+
type E;
36+
37+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
38+
fn edges(&self, &Self::N) -> Vec<Self::E>;
39+
// etc
40+
}
41+
```
42+
43+
Now, our clients can be abstract over a given `Graph`:
44+
45+
```rust,ignore
46+
fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... }
47+
```
48+
49+
No need to deal with the `E`dge type here!
50+
51+
Let's go over all this in more detail.
52+
53+
## Defining associated types
54+
55+
Let's build that `Graph` trait. Here's the definition:
56+
57+
```rust
58+
trait Graph {
59+
type N;
60+
type E;
61+
62+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
63+
fn edges(&self, &Self::N) -> Vec<Self::E>;
64+
}
65+
```
66+
67+
Simple enough. Associated types use the `type` keyword, and go inside the body
68+
of the trait, with the functions.
69+
70+
These `type` declarations can have all the same thing as functions do. For example,
71+
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
72+
we could do this:
73+
74+
```rust
75+
use std::fmt;
76+
77+
trait Graph {
78+
type N: fmt::Display;
79+
type E;
80+
81+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
82+
fn edges(&self, &Self::N) -> Vec<Self::E>;
83+
}
84+
```
85+
86+
## Implementing associated types
87+
88+
Just like any trait, traits that use associated types use the `impl` keyword to
89+
provide implementations. Here's a simple implementation of Graph:
90+
91+
```rust
92+
# trait Graph {
93+
# type N;
94+
# type E;
95+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
96+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
97+
# }
98+
struct Node;
99+
100+
struct Edge;
101+
102+
struct MyGraph;
103+
104+
impl Graph for MyGraph {
105+
type N = Node;
106+
type E = Edge;
107+
108+
fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
109+
true
110+
}
111+
112+
fn edges(&self, n: &Node) -> Vec<Edge> {
113+
Vec::new()
114+
}
115+
}
116+
```
117+
118+
This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
119+
gives you an idea of how to implement this kind of thing. We first need three
120+
`struct`s, one for the graph, one for the node, and one for the edge. If it made
121+
more sense to use a different type, that would work as well, we're just going to
122+
use `struct`s for all three here.
123+
124+
Next is the `impl` line, which is just like implementing any other trait.
125+
126+
From here, we use `=` to define our associated types. The name the trait uses
127+
goes on the left of the `=`, and the concrete type we're `impl`ementing this
128+
for goes on the right. Finally, we use the concrete types in our function
129+
declarations.
130+
131+
## Trait objects with associated types
132+
133+
There’s one more bit of syntax we should talk about: trait objects. If you
134+
try to create a trait object from an associated type, like this:
135+
136+
```rust,ignore
137+
# trait Graph {
138+
# type N;
139+
# type E;
140+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
141+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
142+
# }
143+
# struct Node;
144+
# struct Edge;
145+
# struct MyGraph;
146+
# impl Graph for MyGraph {
147+
# type N = Node;
148+
# type E = Edge;
149+
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
150+
# true
151+
# }
152+
# fn edges(&self, n: &Node) -> Vec<Edge> {
153+
# Vec::new()
154+
# }
155+
# }
156+
let graph = MyGraph;
157+
let obj = Box::new(graph) as Box<Graph>;
158+
```
159+
160+
You’ll get two errors:
161+
162+
```text
163+
error: the value of the associated type `E` (from the trait `main::Graph`) must
164+
be specified [E0191]
165+
let obj = Box::new(graph) as Box<Graph>;
166+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167+
24:44 error: the value of the associated type `N` (from the trait
168+
`main::Graph`) must be specified [E0191]
169+
let obj = Box::new(graph) as Box<Graph>;
170+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171+
```
172+
173+
We can’t create a trait object like this, becuase we don’t know the associated
174+
types. Instead, we can write this:
175+
176+
```rust
177+
# trait Graph {
178+
# type N;
179+
# type E;
180+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
181+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
182+
# }
183+
# struct Node;
184+
# struct Edge;
185+
# struct MyGraph;
186+
# impl Graph for MyGraph {
187+
# type N = Node;
188+
# type E = Edge;
189+
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
190+
# true
191+
# }
192+
# fn edges(&self, n: &Node) -> Vec<Edge> {
193+
# Vec::new()
194+
# }
195+
# }
196+
let graph = MyGraph;
197+
let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
198+
```
199+
200+
The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N`
201+
type parameter. Same with `E=Edge`. If we didn’t proide this constraint, we
202+
couldn’t be sure which `impl` to match this trait object to.

src/doc/trpl/ownership.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ Otherwise, it is an error to elide an output lifetime.
513513

514514
### Examples
515515

516-
Here are some examples of functions with elided lifetimes, and the version of
517-
what the elided lifetimes are expand to:
516+
Here are some examples of functions with elided lifetimes. We've paired each
517+
example of an elided lifetime with its expanded form.
518518

519519
```{rust,ignore}
520520
fn print(s: &str); // elided

src/doc/trpl/unsafe.md

+9-8
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,16 @@ use std::ptr;
197197
198198
// Define a wrapper around the handle returned by the foreign code.
199199
// Unique<T> has the same semantics as Box<T>
200-
pub struct Unique<T> {
200+
//
201+
// NB: For simplicity and correctness, we require that T has kind Send
202+
// (owned boxes relax this restriction).
203+
pub struct Unique<T: Send> {
201204
// It contains a single raw, mutable pointer to the object in question.
202205
ptr: *mut T
203206
}
204207
205208
// Implement methods for creating and using the values in the box.
206209
207-
// NB: For simplicity and correctness, we require that T has kind Send
208-
// (owned boxes relax this restriction).
209210
impl<T: Send> Unique<T> {
210211
pub fn new(value: T) -> Unique<T> {
211212
unsafe {
@@ -239,11 +240,11 @@ impl<T: Send> Unique<T> {
239240
// Unique<T>, making the struct manage the raw pointer: when the
240241
// struct goes out of scope, it will automatically free the raw pointer.
241242
//
242-
// NB: This is an unsafe destructor, because rustc will not normally
243-
// allow destructors to be associated with parameterized types, due to
244-
// bad interaction with managed boxes. (With the Send restriction,
245-
// we don't have this problem.) Note that the `#[unsafe_destructor]`
246-
// feature gate is required to use unsafe destructors.
243+
// NB: This is an unsafe destructor; rustc will not normally allow
244+
// destructors to be associated with parameterized types (due to
245+
// historically failing to check them soundly). Note that the
246+
// `#[unsafe_destructor]` feature gate is currently required to use
247+
// unsafe destructors.
247248
#[unsafe_destructor]
248249
impl<T: Send> Drop for Unique<T> {
249250
fn drop(&mut self) {

src/etc/libc.c

+10
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ void posix88_consts() {
165165
put_const(S_IWUSR, int);
166166
put_const(S_IRUSR, int);
167167

168+
put_const(S_IRWXG, int);
169+
put_const(S_IXGRP, int);
170+
put_const(S_IWGRP, int);
171+
put_const(S_IRGRP, int);
172+
173+
put_const(S_IRWXO, int);
174+
put_const(S_IXOTH, int);
175+
put_const(S_IWOTH, int);
176+
put_const(S_IROTH, int);
177+
168178
#ifdef F_OK
169179
put_const(F_OK, int);
170180
#endif

src/liballoc/arc.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<T: Send + Sync + Clone> Arc<T> {
321321

322322
#[unsafe_destructor]
323323
#[stable(feature = "rust1", since = "1.0.0")]
324-
impl<T: Sync + Send> Drop for Arc<T> {
324+
impl<T> Drop for Arc<T> {
325325
/// Drops the `Arc<T>`.
326326
///
327327
/// This will decrement the strong reference count. If the strong reference
@@ -388,7 +388,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
388388

389389
#[unstable(feature = "alloc",
390390
reason = "Weak pointers may not belong in this module.")]
391-
impl<T: Sync + Send> Weak<T> {
391+
impl<T> Weak<T> {
392392
/// Upgrades a weak reference to a strong reference.
393393
///
394394
/// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
@@ -454,7 +454,7 @@ impl<T: Sync + Send> Clone for Weak<T> {
454454

455455
#[unsafe_destructor]
456456
#[stable(feature = "rust1", since = "1.0.0")]
457-
impl<T: Sync + Send> Drop for Weak<T> {
457+
impl<T> Drop for Weak<T> {
458458
/// Drops the `Weak<T>`.
459459
///
460460
/// This will decrement the weak reference count.

src/libarena/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ impl<T> TypedArenaChunk<T> {
429429
// Destroy the next chunk.
430430
let next = self.next;
431431
let size = calculate_size::<T>(self.capacity);
432-
deallocate(self as *mut TypedArenaChunk<T> as *mut u8, size,
432+
let self_ptr: *mut TypedArenaChunk<T> = self;
433+
deallocate(self_ptr as *mut u8, size,
433434
mem::min_align_of::<TypedArenaChunk<T>>());
434435
if !next.is_null() {
435436
let capacity = (*next).capacity;

src/libcollections/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
html_playground_url = "http://play.rust-lang.org/")]
2525
#![doc(test(no_crate_inject))]
2626

27+
#![allow(trivial_casts)]
28+
#![allow(trivial_numeric_casts)]
2729
#![feature(alloc)]
2830
#![feature(box_syntax)]
2931
#![feature(box_patterns)]

src/libcollections/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1199,8 +1199,8 @@ impl<T: PartialEq> Vec<T> {
11991199

12001200
// Avoid bounds checks by using unsafe pointers.
12011201
let p = self.as_mut_ptr();
1202-
let mut r = 1;
1203-
let mut w = 1;
1202+
let mut r: usize = 1;
1203+
let mut w: usize = 1;
12041204

12051205
while r < ln {
12061206
let p_r = p.offset(r as isize);

src/libcollectionstest/btree/set.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,21 @@ struct Counter<'a, 'b> {
4343
}
4444

4545
impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
46-
type Output = bool;
47-
4846
extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
4947
assert_eq!(x, self.expected[*self.i]);
5048
*self.i += 1;
5149
true
5250
}
5351
}
5452

53+
impl<'a, 'b, 'c> FnOnce<(&'c i32,)> for Counter<'a, 'b> {
54+
type Output = bool;
55+
56+
extern "rust-call" fn call_once(mut self, args: (&'c i32,)) -> bool {
57+
self.call_mut(args)
58+
}
59+
}
60+
5561
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
5662
// FIXME Replace Counter with `Box<FnMut(_) -> _>`
5763
F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,

src/libcore/any.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ use marker::Sized;
8282
// Any trait
8383
///////////////////////////////////////////////////////////////////////////////
8484

85-
/// The `Any` trait is implemented by all `'static` types, and can be used for
86-
/// dynamic typing
85+
/// A type to emulate dynamic typing. See the [module-level documentation][mod] for more details.
8786
///
88-
/// Every type with no non-`'static` references implements `Any`, so `Any` can
89-
/// be used as a trait object to emulate the effects dynamic typing.
87+
/// Every type with no non-`'static` references implements `Any`.
88+
///
89+
/// [mod]: ../index.html
9090
#[stable(feature = "rust1", since = "1.0.0")]
9191
pub trait Any: 'static {
9292
/// Get the `TypeId` of `self`

0 commit comments

Comments
 (0)