Skip to content

Commit c744eed

Browse files
committed
---
yaml --- r: 191191 b: refs/heads/try c: e4010d1 h: refs/heads/master i: 191189: 3050699 191187: 3014376 191183: 8d3ed03 v: v3
1 parent aa7248c commit c744eed

Some content is hidden

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

88 files changed

+465
-489
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 809a554fca2d0ebc2ba50077016fe282a4064752
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: c64d671671aea2e44ee7fc6eb00ee75fc30ed7b9
5-
refs/heads/try: 33751ff8a7e2e013609d79f43da3d9a6d2c1f71e
5+
refs/heads/try: e4010d1bf6451447607b40c12dc683b9a53a9c78
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
88
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ The other kind of comment is a doc comment. Doc comments use `///` instead of
2828
///
2929
/// * `name` - The name of the person you'd like to greet.
3030
///
31-
/// # Example
31+
/// # Examples
3232
///
3333
/// ```rust
3434
/// let name = "Steve";

branches/try/src/doc/trpl/static-and-dynamic-dispatch.md

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -102,49 +102,88 @@ reason.
102102
Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
103103
objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
104104
*any* type that implements the given trait, where the precise type can only be
105-
known at runtime. The methods of the trait can be called on a trait object via
106-
a special record of function pointers (created and managed by the compiler).
105+
known at runtime.
107106

108-
A function that takes a trait object is not specialized to each of the types
109-
that implements `Foo`: only one copy is generated, often (but not always)
110-
resulting in less code bloat. However, this comes at the cost of requiring
111-
slower virtual function calls, and effectively inhibiting any chance of
112-
inlining and related optimisations from occurring.
107+
A trait object can be obtained from a pointer to a concrete type that
108+
implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it
109+
(e.g. using `&x` as an argument to a function that takes `&Foo`).
113110

114-
Trait objects are both simple and complicated: their core representation and
115-
layout is quite straight-forward, but there are some curly error messages and
116-
surprising behaviors to discover.
111+
These trait object coercions and casts also work for pointers like `&mut T` to
112+
`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
113+
and casts are identical.
117114

118-
### Obtaining a trait object
115+
This operation can be seen as "erasing" the compiler's knowledge about the
116+
specific type of the pointer, and hence trait objects are sometimes referred to
117+
as "type erasure".
119118

120-
There's two similar ways to get a trait object value: casts and coercions. If
121-
`T` is a type that implements a trait `Foo` (e.g. `u8` for the `Foo` above),
122-
then the two ways to get a `Foo` trait object out of a pointer to `T` look
123-
like:
119+
Coming back to the example above, we can use the same trait to perform dynamic
120+
dispatch with trait objects by casting:
124121

125-
```{rust,ignore}
126-
let ref_to_t: &T = ...;
122+
```rust
123+
# trait Foo { fn method(&self) -> String; }
124+
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
125+
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
127126

128-
// `as` keyword for casting
129-
let cast = ref_to_t as &Foo;
127+
fn do_something(x: &Foo) {
128+
x.method();
129+
}
130130

131-
// using a `&T` in a place that has a known type of `&Foo` will implicitly coerce:
132-
let coerce: &Foo = ref_to_t;
131+
fn main() {
132+
let x = 5u8;
133+
do_something(&x as &Foo);
134+
}
135+
```
133136

134-
fn also_coerce(_unused: &Foo) {}
135-
also_coerce(ref_to_t);
137+
or by coercing:
138+
139+
```rust
140+
# trait Foo { fn method(&self) -> String; }
141+
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
142+
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
143+
144+
fn do_something(x: &Foo) {
145+
x.method();
146+
}
147+
148+
fn main() {
149+
let x = "Hello".to_string();
150+
do_something(&x);
151+
}
136152
```
137153

138-
These trait object coercions and casts also work for pointers like `&mut T` to
139-
`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
140-
and casts are identical.
154+
A function that takes a trait object is not specialized to each of the types
155+
that implements `Foo`: only one copy is generated, often (but not always)
156+
resulting in less code bloat. However, this comes at the cost of requiring
157+
slower virtual function calls, and effectively inhibiting any chance of
158+
inlining and related optimisations from occurring.
141159

142-
This operation can be seen as "erasing" the compiler's knowledge about the
143-
specific type of the pointer, and hence trait objects are sometimes referred to
144-
as "type erasure".
160+
### Why pointers?
161+
162+
Rust does not put things behind a pointer by default, unlike many managed
163+
languages, so types can have different sizes. Knowing the size of the value at
164+
compile time is important for things like passing it as an argument to a
165+
function, moving it about on the stack and allocating (and deallocating) space
166+
on the heap to store it.
167+
168+
For `Foo`, we would need to have a value that could be at least either a
169+
`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
170+
dependent crates may implement `Foo` (any number of bytes at all). There's no
171+
way to guarantee that this last point can work if the values are stored without
172+
a pointer, because those other types can be arbitrarily large.
173+
174+
Putting the value behind a pointer means the size of the value is not relevant
175+
when we are tossing a trait object around, only the size of the pointer itself.
145176

146177
### Representation
147178

179+
The methods of the trait can be called on a trait object via a special record
180+
of function pointers traditionally called a 'vtable' (created and managed by
181+
the compiler).
182+
183+
Trait objects are both simple and complicated: their core representation and
184+
layout is quite straight-forward, but there are some curly error messages and
185+
surprising behaviors to discover.
186+
148187
Let's start simple, with the runtime representation of a trait object. The
149188
`std::raw` module contains structs with layouts that are the same as the
150189
complicated built-in types, [including trait objects][stdraw]:
@@ -265,23 +304,3 @@ let y = TraitObject {
265304
If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
266305
`(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
267306
scope.
268-
269-
### Why pointers?
270-
271-
The use of language like "fat pointer" implies that a trait object is
272-
always a pointer of some form, but why?
273-
274-
Rust does not put things behind a pointer by default, unlike many managed
275-
languages, so types can have different sizes. Knowing the size of the value at
276-
compile time is important for things like passing it as an argument to a
277-
function, moving it about on the stack and allocating (and deallocating) space
278-
on the heap to store it.
279-
280-
For `Foo`, we would need to have a value that could be at least either a
281-
`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
282-
dependent crates may implement `Foo` (any number of bytes at all). There's no
283-
way to guarantee that this last point can work if the values are stored without
284-
a pointer, because those other types can be arbitrarily large.
285-
286-
Putting the value behind a pointer means the size of the value is not relevant
287-
when we are tossing a trait object around, only the size of the pointer itself.

branches/try/src/liballoc/arc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ use heap::deallocate;
8888

8989
/// An atomically reference counted wrapper for shared state.
9090
///
91-
/// # Example
91+
/// # Examples
9292
///
9393
/// In this example, a large vector of floats is shared between several tasks.
9494
/// With simple pipes, without `Arc`, a copy would have to be made for each

branches/try/src/liballoc/boxed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<T : ?Sized> Box<T> {
133133
/// automatically managed that may lead to memory or other resource
134134
/// leak.
135135
///
136-
/// # Example
136+
/// # Examples
137137
/// ```
138138
/// use std::boxed;
139139
///

branches/try/src/liballoc/rc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool {
264264
///
265265
/// If the `Rc<T>` is not unique, an `Err` is returned with the same `Rc<T>`.
266266
///
267-
/// # Example
267+
/// # Examples
268268
///
269269
/// ```
270270
/// use std::rc::{self, Rc};
@@ -298,7 +298,7 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
298298
///
299299
/// Returns `None` if the `Rc<T>` is not unique.
300300
///
301-
/// # Example
301+
/// # Examples
302302
///
303303
/// ```
304304
/// use std::rc::{self, Rc};

branches/try/src/libcollections/borrow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ impl<T> ToOwned for T where T: Clone {
127127
/// is desired, `to_mut` will obtain a mutable references to an owned
128128
/// value, cloning if necessary.
129129
///
130-
/// # Example
130+
/// # Examples
131131
///
132132
/// ```rust
133133
/// use std::borrow::Cow;

branches/try/src/libcollections/btree/map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
11771177
impl<K, V> BTreeMap<K, V> {
11781178
/// Gets an iterator over the entries of the map.
11791179
///
1180-
/// # Example
1180+
/// # Examples
11811181
///
11821182
/// ```
11831183
/// use std::collections::BTreeMap;

branches/try/src/libcollections/fmt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ use string;
420420
///
421421
/// * args - a structure of arguments generated via the `format_args!` macro.
422422
///
423-
/// # Example
423+
/// # Examples
424424
///
425425
/// ```rust
426426
/// use std::fmt;

branches/try/src/libcollections/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ mod prelude {
175175
}
176176

177177
/// An endpoint of a range of keys.
178+
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
178179
pub enum Bound<T> {
179180
/// An inclusive bound.
180181
Included(T),

branches/try/src/libcollections/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ macro_rules! vec {
4848
/// Use the syntax described in `std::fmt` to create a value of type `String`.
4949
/// See `std::fmt` for more information.
5050
///
51-
/// # Example
51+
/// # Examples
5252
///
5353
/// ```
5454
/// format!("test");

branches/try/src/libcollections/slice.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ pub trait SliceExt {
277277
///
278278
/// Panics if `size` is 0.
279279
///
280-
/// # Example
280+
/// # Examples
281281
///
282282
/// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`,
283283
/// `[3,4]`):
@@ -300,7 +300,7 @@ pub trait SliceExt {
300300
///
301301
/// Panics if `size` is 0.
302302
///
303-
/// # Example
303+
/// # Examples
304304
///
305305
/// Print the slice two elements at a time (i.e. `[1,2]`,
306306
/// `[3,4]`, `[5]`):
@@ -390,7 +390,7 @@ pub trait SliceExt {
390390
/// `Err` is returned, containing the index where a matching
391391
/// element could be inserted while maintaining sorted order.
392392
///
393-
/// # Example
393+
/// # Examples
394394
///
395395
/// Looks up a series of four elements. The first is found, with a
396396
/// uniquely determined position; the second and third are not
@@ -416,7 +416,7 @@ pub trait SliceExt {
416416

417417
/// Return the number of elements in the slice
418418
///
419-
/// # Example
419+
/// # Examples
420420
///
421421
/// ```
422422
/// let a = [1, 2, 3];
@@ -427,7 +427,7 @@ pub trait SliceExt {
427427

428428
/// Returns true if the slice has a length of 0
429429
///
430-
/// # Example
430+
/// # Examples
431431
///
432432
/// ```
433433
/// let a = [1, 2, 3];
@@ -529,7 +529,7 @@ pub trait SliceExt {
529529
///
530530
/// Panics if `a` or `b` are out of bounds.
531531
///
532-
/// # Example
532+
/// # Examples
533533
///
534534
/// ```rust
535535
/// let mut v = ["a", "b", "c", "d"];
@@ -549,7 +549,7 @@ pub trait SliceExt {
549549
///
550550
/// Panics if `mid > len`.
551551
///
552-
/// # Example
552+
/// # Examples
553553
///
554554
/// ```rust
555555
/// let mut v = [1, 2, 3, 4, 5, 6];
@@ -578,7 +578,7 @@ pub trait SliceExt {
578578

579579
/// Reverse the order of elements in a slice, in place.
580580
///
581-
/// # Example
581+
/// # Examples
582582
///
583583
/// ```rust
584584
/// let mut v = [1, 2, 3];
@@ -638,7 +638,7 @@ pub trait SliceExt {
638638
/// shorter of `self.len()` and `src.len()`). Returns the number
639639
/// of elements copied.
640640
///
641-
/// # Example
641+
/// # Examples
642642
///
643643
/// ```rust
644644
/// let mut dst = [0, 0, 0];
@@ -676,7 +676,7 @@ pub trait SliceExt {
676676
/// `Err` is returned, containing the index where a matching
677677
/// element could be inserted while maintaining sorted order.
678678
///
679-
/// # Example
679+
/// # Examples
680680
///
681681
/// Looks up a series of four elements. The first is found, with a
682682
/// uniquely determined position; the second and third are not
@@ -707,7 +707,7 @@ pub trait SliceExt {
707707
/// Returns `true` if successful and `false` if the slice is at the
708708
/// last-ordered permutation.
709709
///
710-
/// # Example
710+
/// # Examples
711711
///
712712
/// ```rust
713713
/// let v: &mut [_] = &mut [0, 1, 2];
@@ -727,7 +727,7 @@ pub trait SliceExt {
727727
/// Returns `true` if successful and `false` if the slice is at the
728728
/// first-ordered permutation.
729729
///
730-
/// # Example
730+
/// # Examples
731731
///
732732
/// ```rust
733733
/// let v: &mut [_] = &mut [1, 0, 2];

branches/try/src/libcollections/str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1377,7 +1377,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
13771377
///
13781378
/// Will return `Err` if it's not possible to parse `self` into the type.
13791379
///
1380-
/// # Example
1380+
/// # Examples
13811381
///
13821382
/// ```
13831383
/// assert_eq!("4".parse::<u32>(), Ok(4));

branches/try/src/libcore/finally.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
//! "finally" case. For advanced cases, the `try_finally` function can
1717
//! also be used. See that function for more details.
1818
//!
19-
//! # Example
19+
//! # Examples
2020
//!
2121
//! ```
2222
//! # #![feature(unboxed_closures)]
@@ -67,7 +67,7 @@ impl<T, F> Finally<T> for F where F: FnMut() -> T {
6767
/// function could have panicked at any point, so the values of the shared
6868
/// state may be inconsistent.
6969
///
70-
/// # Example
70+
/// # Examples
7171
///
7272
/// ```
7373
/// use std::finally::try_finally;

branches/try/src/libcore/fmt/num.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub struct RadixFmt<T, R>(T, R);
143143

144144
/// Constructs a radix formatter in the range of `2..36`.
145145
///
146-
/// # Example
146+
/// # Examples
147147
///
148148
/// ```
149149
/// use std::fmt::radix;

0 commit comments

Comments
 (0)