Skip to content

Commit 3050699

Browse files
author
Dave Huseby
committed
---
yaml --- r: 191189 b: refs/heads/try c: 8e082f7 h: refs/heads/master i: 191187: 3014376 v: v3
1 parent 2d76ea2 commit 3050699

Some content is hidden

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

89 files changed

+491
-466
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: 7a9ef60e60bd9f8afd003387a62715131f1b1fb1
5+
refs/heads/try: 8e082f77cf71ad7651820b93ec0a2b7f5ff62769
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
88
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

branches/try/configure

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,9 @@ fi
760760
# Force bitrig to build with clang; gcc doesn't like us there
761761
if [ $CFG_OSTYPE = unknown-bitrig ]
762762
then
763-
step_msg "on Bitrig, forcing use of clang"
763+
step_msg "on Bitrig, forcing use of clang, disabling jemalloc"
764764
CFG_ENABLE_CLANG=1
765+
CFG_ENABLE_JEMALLOC=0
765766
fi
766767

767768
if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]

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-
/// # Examples
31+
/// # Example
3232
///
3333
/// ```rust
3434
/// let name = "Steve";

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

Lines changed: 49 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -102,87 +102,48 @@ 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.
106-
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`).
110-
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.
114-
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".
118-
119-
Coming back to the example above, we can use the same trait to perform dynamic
120-
dispatch with trait objects by casting:
121-
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) } }
126-
127-
fn do_something(x: &Foo) {
128-
x.method();
129-
}
130-
131-
fn main() {
132-
let x = 5u8;
133-
do_something(&x as &Foo);
134-
}
135-
```
136-
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-
}
152-
```
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).
153107

154108
A function that takes a trait object is not specialized to each of the types
155109
that implements `Foo`: only one copy is generated, often (but not always)
156110
resulting in less code bloat. However, this comes at the cost of requiring
157111
slower virtual function calls, and effectively inhibiting any chance of
158112
inlining and related optimisations from occurring.
159113

160-
### Why pointers?
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.
161117

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.
118+
### Obtaining a trait object
167119

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

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.
125+
```{rust,ignore}
126+
let ref_to_t: &T = ...;
176127
177-
### Representation
128+
// `as` keyword for casting
129+
let cast = ref_to_t as &Foo;
178130
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).
131+
// using a `&T` in a place that has a known type of `&Foo` will implicitly coerce:
132+
let coerce: &Foo = ref_to_t;
182133
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.
134+
fn also_coerce(_unused: &Foo) {}
135+
also_coerce(ref_to_t);
136+
```
137+
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.
141+
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".
145+
146+
### Representation
186147

187148
Let's start simple, with the runtime representation of a trait object. The
188149
`std::raw` module contains structs with layouts that are the same as the
@@ -304,3 +265,23 @@ let y = TraitObject {
304265
If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
305266
`(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
306267
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-
/// # Examples
91+
/// # Example
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-
/// # Examples
136+
/// # Example
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-
/// # Examples
267+
/// # Example
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-
/// # Examples
301+
/// # Example
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-
/// # Examples
130+
/// # Example
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-
/// # Examples
1180+
/// # Example
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-
/// # Examples
423+
/// # Example
424424
///
425425
/// ```rust
426426
/// use std::fmt;

branches/try/src/libcollections/lib.rs

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

177177
/// An endpoint of a range of keys.
178-
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
179178
pub enum Bound<T> {
180179
/// An inclusive bound.
181180
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-
/// # Examples
51+
/// # Example
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-
/// # Examples
280+
/// # Example
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-
/// # Examples
303+
/// # Example
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-
/// # Examples
393+
/// # Example
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-
/// # Examples
419+
/// # Example
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-
/// # Examples
430+
/// # Example
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-
/// # Examples
532+
/// # Example
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-
/// # Examples
552+
/// # Example
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-
/// # Examples
581+
/// # Example
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-
/// # Examples
641+
/// # Example
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-
/// # Examples
679+
/// # Example
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-
/// # Examples
710+
/// # Example
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-
/// # Examples
730+
/// # Example
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-
/// # Examples
1380+
/// # Example
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-
//! # Examples
19+
//! # Example
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-
/// # Examples
70+
/// # Example
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-
/// # Examples
146+
/// # Example
147147
///
148148
/// ```
149149
/// use std::fmt::radix;

0 commit comments

Comments
 (0)