Skip to content

Commit fbf6895

Browse files
committed
Moar trait object verbiage.
1. While it's "obvious", it should be stated that trait objects actually implement the traits they are for. 2. Added lifetime bounds to the syntactical description and aliasing rules of trait objects. I'm not sure if the aliasing part is correct. 3. Added a big fat warning to the method call expression about trait objects having an inherent impl define a method with the same name as one of the methods the trait object has from the trait. I think that trait objects following different rules than other types should be changed.
1 parent ea1c7f5 commit fbf6895

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

src/expressions/method-call-expr.md

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,22 @@ let log_pi = pi.unwrap_or(1.0).log(2.72);
1515
```
1616

1717
When resolving method calls on an expression of type `A`, Rust will use the
18-
following order, only looking at methods that are
19-
[visible](visibility-and-privacy.html). If the type of `A` is a type parameter
20-
or `Self` in a trait definitition then steps 2-4 first consider traits from
21-
bounds on the type paramter, then the traits that are in scope. For other
22-
types, only the traits that are in scope are considered.
18+
following order, only looking at methods that are [visible]. If the type of `A`
19+
is a type parameter or `Self` in a trait definitition then steps 2-4 first
20+
consider traits from bounds on the type paramter, then the traits that are in
21+
scope. For other types, only the traits that are in scope are considered.
2322

2423
1. Inherent methods, with receiver of type `A`, `&A`, `&mut A`.
2524
1. Trait methods with receiver of type `A`.
2625
1. Trait methods with receiver of type `&A`.
2726
1. Trait methods with receiver of type `&mut A`.
2827
1. If it's possible, Rust will then repeat steps 1-5 with
2928
`<A as std::ops::Deref>::Target`, and insert a dereference operator.
30-
1. If `A` is now an [array](types.html#array-and-slice-types) type, then
31-
repeat steps 1-4 with the corresponding slice type.
29+
1. If `A` is now an [array] type, then repeat steps 1-4 with the corresponding
30+
slice type.
3231

33-
Note: that in steps 1-4 the receiver is used, not the type of `Self` nor the
34-
type of `A`. For example
32+
Note: In steps 1-4, the receiver is used, not the type of `Self` nor the
33+
type of `A`. For example:
3534

3635
```rust,ignore
3736
// `Self` is `&A`, receiver is `&A`.
@@ -48,10 +47,21 @@ Another note: this process does not use the mutability or lifetime of the
4847
receiver, or whether `unsafe` methods can currently be called to resolve
4948
methods. These constraints instead lead to compiler errors.
5049

51-
If a step is reached where there is more than one possible method (where
52-
generic methods or traits are considered the same), then it is a compiler
53-
error. These cases require a [more specific
54-
syntax.](expressions/call-expr.html#disambiguating-function-calls) for method
50+
If a step is reached where there is more than one possible method, such as where
51+
generic methods or traits are considered the same, then it is a compiler
52+
error. These cases require a [disambiguating function call syntax] for method
5553
and function invocation.
5654

57-
[IDENTIFIER]: identifiers.html
55+
> Warning: For [trait objects], if there is an inherent method of the same name
56+
> as a trait method, it will give a compiler error when trying to call the
57+
> method in a method call expression. Instead, you can call the method using
58+
> [disambiguating function call syntax], in which case it calls the trait
59+
> method, not the inherent method. There is no way to call the inherent method.
60+
> Just don't define inherent methods on trait objects with the same name a trait
61+
> method and you'll be fine.
62+
63+
[IDENTIFIER]: identifiers.html
64+
[visible]: visibility-and-privacy.html
65+
[array]: types.html#array-and-slice-types
66+
[trait objects]: types.html#trait-objects
67+
[disambiguating function call syntax]: expressions/call-expr.html#disambiguating-function-calls

src/types.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,19 @@ A *trait object* is an opaque value of another type that implements a set of
403403
traits. The set of traits is made up of an [object safe] *base trait* plus any
404404
number of [auto traits].
405405

406+
Trait objects implement the base trait, its auto traits, and any super traits
407+
of the base trait.
408+
406409
Trait objects are written as the path to the base trait followed by the list
407-
of auto traits all separated by `+`. For example, given a trait `Trait`, the
408-
following are all trait objects: `Trait`, `Trait + Send`, `Trait + Send + Sync`.
410+
of auto traits followed optionally by a lifetime bound all separated by `+`. For
411+
example, given a trait `Trait`, the following are all trait objects: `Trait`,
412+
`Trait + Send`, `Trait + Send + Sync`, `Trait + 'static`,
413+
`Trait + Send + 'static`.
409414

410415
Two trait object types alias each other if the base traits alias each other and
411-
if the sets of auto traits are the same. For example,
412-
`Trait + Send + UnwindSafe` is the same as `Trait + Unwindsafe + Send`.
416+
if the sets of auto traits are the same and the lifetime bounds are the same.
417+
For example, `Trait + Send + UnwindSafe` is the same as
418+
`Trait + Unwindsafe + Send`.
413419

414420
> Warning: With two trait object types, even when the complete set of traits is
415421
> the same, if the base traits differ, the type is different. For example,

0 commit comments

Comments
 (0)