Skip to content

Commit 0835189

Browse files
committed
Auto merge of #25308 - nham:audit_ref_traits, r=alexcrichton
cc #16676
2 parents 222cd73 + b2f486f commit 0835189

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

src/doc/reference.md

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,8 @@ vtable when the trait is used as a [trait object](#trait-objects).
13461346
Traits are implemented for specific types through separate
13471347
[implementations](#implementations).
13481348

1349+
Consider the following trait:
1350+
13491351
```
13501352
# type Surface = i32;
13511353
# type BoundingBox = i32;
@@ -1360,6 +1362,20 @@ This defines a trait with two methods. All values that have
13601362
`draw` and `bounding_box` methods called, using `value.bounding_box()`
13611363
[syntax](#method-call-expressions).
13621364

1365+
Traits can include default implementations of methods, as in:
1366+
1367+
```
1368+
trait Foo {
1369+
fn bar(&self);
1370+
1371+
fn baz(&self) { println!("We called baz."); }
1372+
}
1373+
```
1374+
1375+
Here the `baz` method has a default implementation, so types that implement
1376+
`Foo` need only implement `bar`. It is also possible for implementing types
1377+
to override a method that has a default implementation.
1378+
13631379
Type parameters can be specified for a trait to make it generic. These appear
13641380
after the trait name, using the same syntax used in [generic
13651381
functions](#generic-functions).
@@ -1372,6 +1388,30 @@ trait Seq<T> {
13721388
}
13731389
```
13741390

1391+
It is also possible to define associated types for a trait. Consider the
1392+
following example of a `Container` trait. Notice how the type is available
1393+
for use in the method signatures:
1394+
1395+
```
1396+
trait Container {
1397+
type E;
1398+
fn empty() -> Self;
1399+
fn insert(&mut self, Self::E);
1400+
}
1401+
```
1402+
1403+
In order for a type to implement this trait, it must not only provide
1404+
implementations for every method, but it must specify the type `E`. Here's
1405+
an implementation of `Container` for the standard library type `Vec`:
1406+
1407+
```
1408+
impl<T> Container for Vec<T> {
1409+
type E = T;
1410+
fn empty() -> Vec<T> { Vec::new() }
1411+
fn insert(&mut self, x: T) { self.push(x); }
1412+
}
1413+
```
1414+
13751415
Generic functions may use traits as _bounds_ on their type parameters. This
13761416
will have two effects: only types that have the trait may instantiate the
13771417
parameter, and within the generic function, the methods of the trait can be
@@ -3470,13 +3510,21 @@ more of the closure traits:
34703510

34713511
### Trait objects
34723512

3473-
Every trait item (see [traits](#traits)) defines a type with the same name as
3474-
the trait. This type is called the _trait object_ of the trait. Trait objects
3475-
permit "late binding" of methods, dispatched using _virtual method tables_
3476-
("vtables"). Whereas most calls to trait methods are "early bound" (statically
3477-
resolved) to specific implementations at compile time, a call to a method on an
3478-
trait objects is only resolved to a vtable entry at compile time. The actual
3479-
implementation for each vtable entry can vary on an object-by-object basis.
3513+
In Rust, a type like `&SomeTrait` or `Box<SomeTrait>` is called a _trait object_.
3514+
Each instance of a trait object includes:
3515+
3516+
- a pointer to an instance of a type `T` that implements `SomeTrait`
3517+
- a _virtual method table_, often just called a _vtable_, which contains, for
3518+
each method of `SomeTrait` that `T` implements, a pointer to `T`'s
3519+
implementation (i.e. a function pointer).
3520+
3521+
The purpose of trait objects is to permit "late binding" of methods. A call to
3522+
a method on a trait object is only resolved to a vtable entry at compile time.
3523+
The actual implementation for each vtable entry can vary on an object-by-object
3524+
basis.
3525+
3526+
Note that for a trait object to be instantiated, the trait must be
3527+
_object-safe_. Object safety rules are defined in [RFC 255][rfc255].
34803528

34813529
Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
34823530
implements trait `R`, casting `E` to the corresponding pointer type `&R` or

0 commit comments

Comments
 (0)