Skip to content

Rollup of 7 pull requests #25377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 55 additions & 7 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,8 @@ vtable when the trait is used as a [trait object](#trait-objects).
Traits are implemented for specific types through separate
[implementations](#implementations).

Consider the following trait:

```
# type Surface = i32;
# type BoundingBox = i32;
Expand All @@ -1360,6 +1362,20 @@ This defines a trait with two methods. All values that have
`draw` and `bounding_box` methods called, using `value.bounding_box()`
[syntax](#method-call-expressions).

Traits can include default implementations of methods, as in:

```
trait Foo {
fn bar(&self);

fn baz(&self) { println!("We called baz."); }
}
```

Here the `baz` method has a default implementation, so types that implement
`Foo` need only implement `bar`. It is also possible for implementing types
to override a method that has a default implementation.

Type parameters can be specified for a trait to make it generic. These appear
after the trait name, using the same syntax used in [generic
functions](#generic-functions).
Expand All @@ -1372,6 +1388,30 @@ trait Seq<T> {
}
```

It is also possible to define associated types for a trait. Consider the
following example of a `Container` trait. Notice how the type is available
for use in the method signatures:

```
trait Container {
type E;
fn empty() -> Self;
fn insert(&mut self, Self::E);
}
```

In order for a type to implement this trait, it must not only provide
implementations for every method, but it must specify the type `E`. Here's
an implementation of `Container` for the standard library type `Vec`:

```
impl<T> Container for Vec<T> {
type E = T;
fn empty() -> Vec<T> { Vec::new() }
fn insert(&mut self, x: T) { self.push(x); }
}
```

Generic functions may use traits as _bounds_ on their type parameters. This
will have two effects: only types that have the trait may instantiate the
parameter, and within the generic function, the methods of the trait can be
Expand Down Expand Up @@ -3470,13 +3510,21 @@ more of the closure traits:

### Trait objects

Every trait item (see [traits](#traits)) defines a type with the same name as
the trait. This type is called the _trait object_ of the trait. Trait objects
permit "late binding" of methods, dispatched using _virtual method tables_
("vtables"). Whereas most calls to trait methods are "early bound" (statically
resolved) to specific implementations at compile time, a call to a method on an
trait objects is only resolved to a vtable entry at compile time. The actual
implementation for each vtable entry can vary on an object-by-object basis.
In Rust, a type like `&SomeTrait` or `Box<SomeTrait>` is called a _trait object_.
Each instance of a trait object includes:

- a pointer to an instance of a type `T` that implements `SomeTrait`
- a _virtual method table_, often just called a _vtable_, which contains, for
each method of `SomeTrait` that `T` implements, a pointer to `T`'s
implementation (i.e. a function pointer).

The purpose of trait objects is to permit "late binding" of methods. A call to
a method on a trait object is only resolved to a vtable entry at compile time.
The actual implementation for each vtable entry can vary on an object-by-object
basis.

Note that for a trait object to be instantiated, the trait must be
_object-safe_. Object safety rules are defined in [RFC 255][rfc255].

Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
implements trait `R`, casting `E` to the corresponding pointer type `&R` or
Expand Down
2 changes: 1 addition & 1 deletion src/doc/trpl/dining-philosophers.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ which blocks execution until the thread has completed execution. This ensures
that the threads complete their work before the program exits.

If you run this program, you’ll see that the philosophers eat out of order!
We have mult-threading!
We have multi-threading!

```text
Gilles Deleuze is eating.
Expand Down
2 changes: 2 additions & 0 deletions src/doc/trpl/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ match version {
This function makes use of an enum, `ParseError`, to enumerate the various
errors that can occur.

The [`Debug`](../core/fmt/trait.Debug.html) trait is what let's us print the enum value using the `{:?}` format operation.

# Non-recoverable errors with `panic!`

In the case of an error that is unexpected and not recoverable, the `panic!`
Expand Down
22 changes: 12 additions & 10 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,41 @@
//! You can explicitly create a `Vec<T>` with `new()`:
//!
//! ```
//! let xs: Vec<i32> = Vec::new();
//! let v: Vec<i32> = Vec::new();
//! ```
//!
//! ...or by using the `vec!` macro:
//!
//! ```
//! let ys: Vec<i32> = vec![];
//! let v: Vec<i32> = vec![];
//!
//! let zs = vec![1i32, 2, 3, 4, 5];
//! let v = vec![1, 2, 3, 4, 5];
//!
//! let v = vec![0; 10]; // ten zeroes
//! ```
//!
//! You can `push` values onto the end of a vector (which will grow the vector as needed):
//!
//! ```
//! let mut xs = vec![1i32, 2];
//! let mut v = vec![1, 2];
//!
//! xs.push(3);
//! v.push(3);
//! ```
//!
//! Popping values works in much the same way:
//!
//! ```
//! let mut xs = vec![1i32, 2];
//! let mut v = vec![1, 2];
//!
//! let two = xs.pop();
//! let two = v.pop();
//! ```
//!
//! Vectors also support indexing (through the `Index` and `IndexMut` traits):
//!
//! ```
//! let mut xs = vec![1i32, 2, 3];
//! let three = xs[2];
//! xs[1] = xs[1] + 5;
//! let mut v = vec![1, 2, 3];
//! let three = v[2];
//! v[1] = v[1] + 5;
//! ```

#![stable(feature = "rust1", since = "1.0.0")]
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ macro_rules! try {
})
}

/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
/// Use the `format!` syntax to write data into a buffer of type `&mut Write`.
/// See `std::fmt` for more information.
///
/// # Examples
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,8 @@ be taken.

E0271: r##"
This is because of a type mismatch between the associated type of some
trait (e.g. T::Bar, where T implements trait Quux { type Bar; })
and another type U that is required to be equal to T::Bar, but is not.
trait (e.g. `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
and another type `U` that is required to be equal to `T::Bar`, but is not.
Examples follow.

Here is a basic example:
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
// Variable declaration before import
Expand All @@ -33,6 +34,7 @@ The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
use std::io::Read;
Expand All @@ -52,6 +54,7 @@ The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
Expand All @@ -61,6 +64,7 @@ The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
Expand All @@ -71,6 +75,7 @@ E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

Expand Down
Loading