Skip to content

Commit f0a7e73

Browse files
authored
Merge pull request rust-lang#327 from Havvy/dyn-trait
Dyn trait
2 parents 0041343 + 571a120 commit f0a7e73

File tree

2 files changed

+53
-21
lines changed

2 files changed

+53
-21
lines changed

src/keywords.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,22 @@ them to use these keywords.
8787
These keywords have special meaning only in certain contexts. For example, it
8888
is possible to declare a variable or method with the name `union`.
8989

90-
* `union` is used to declare a [union]
91-
* `'static` is used for a static lifetime
90+
* `union` is used to declare a [union] and is only a keyword when used in a
91+
union declaration.
92+
* `'static` is used for the static lifetime and cannot be used as a generic
93+
lifetime parameter
94+
95+
```compile_fail
96+
// error[E0262]: invalid lifetime parameter name: `'static`
97+
fn invalid_lifetime_parameter<'static>(s: &'static str) -> &'static str { s }
98+
```
99+
* `dyn` denotes a [trait object] and is a keyword when used in a type position
100+
followed by a path that does not start with `::`.
92101

93102
> **<sup>Lexer</sup>**
94-
> KW_UNION : `union`
95-
> KW_STATICLIFETIME : `'static`
103+
> KW_UNION : `union`
104+
> KW_STATICLIFETIME : `'static`
105+
> KW_DYN : `dyn`
96106
97107
[items]: items.html
98108
[Variables]: variables.html
@@ -104,3 +114,4 @@ is possible to declare a variable or method with the name `union`.
104114
[Crates]: crates-and-source-files.html
105115
[union]: items/unions.html
106116
[variants]: items/enumerations.html
117+
[trait object]: types.html#trait-objects

src/types.md

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,10 @@ Because captures are often by reference, the following general rules arise:
507507

508508
> **<sup>Syntax</sup>**
509509
> _TraitObjectType_ :
510-
> &nbsp;&nbsp; _LifetimeOrPath_ ( `+` _LifetimeOrPath_ )<sup>\*</sup> `+`<sup>?</sup>
510+
> &nbsp;&nbsp; `dyn`<sup>?</sup> _LifetimeOrPath_ ( `+` _LifetimeOrPath_ )<sup>\*</sup> `+`<sup>?</sup>
511511
>
512512
> _LifetimeOrPath_ :
513-
> &nbsp;&nbsp; [_Path_] | [_LIFETIME_OR_LABEL_]
513+
> &nbsp;&nbsp; [_Path_] | `(` [_Path_] `)` | [_LIFETIME_OR_LABEL_]
514514
515515
A *trait object* is an opaque value of another type that implements a set of
516516
traits. The set of traits is made up of an [object safe] *base trait* plus any
@@ -519,31 +519,52 @@ number of [auto traits].
519519
Trait objects implement the base trait, its auto traits, and any super traits
520520
of the base trait.
521521

522-
Trait objects are written the same as trait bounds, but with the following
523-
restrictions. All traits except the first trait must be auto traits, there may
524-
not be more than one lifetime, and opt-out bounds (e.g. `?sized`) are not
525-
allowed. For example, given a trait `Trait`, the following are all trait
526-
objects: `Trait`, `Trait + Send`, `Trait + Send + Sync`, `Trait + 'static`,
527-
`Trait + Send + 'static`, `Trait +`, `'static + Trait`.
522+
Trait objects are written as the optional keyword `dyn` followed by a set of
523+
trait bounds, but with the following restrictions on the trait bounds. All
524+
traits except the first trait must be auto traits, there may not be more than
525+
one lifetime, and opt-out bounds (e.g. `?sized`) are not allowed. Furthermore,
526+
paths to traits may be parenthesized.
527+
528+
For example, given a trait `Trait`, the following are all trait objects:
529+
530+
* `Trait`
531+
* `dyn Trait`
532+
* `dyn Trait + Send`
533+
* `dyn Trait + Send + Sync`
534+
* `dyn Trait + 'static`
535+
* `dyn Trait + Send + 'static`
536+
* `dyn Trait +`
537+
* `dyn 'static + Trait`.
538+
* `dyn (Trait)`
539+
540+
If the first bound of the trait object is a path that starts with `::`, then the
541+
`dyn` will be treated as a part of the path. The first path can be put in
542+
parenthesis to get around this. As such, if you want a trait object with the
543+
trait `::your_module::Trait`, you should write it as
544+
`dyn (::your_module::Trait)`.
545+
546+
> Note: For clarity, it is recommended to always use the `dyn` keyword on your
547+
> trait objects unless your codebase supports compiling with Rust 1.26 or lower.
528548
529549
Two trait object types alias each other if the base traits alias each other and
530550
if the sets of auto traits are the same and the lifetime bounds are the same.
531-
For example, `Trait + Send + UnwindSafe` is the same as
532-
`Trait + Unwindsafe + Send`.
551+
For example, `dyn Trait + Send + UnwindSafe` is the same as
552+
`dyn Trait + Unwindsafe + Send`.
533553

534554
> Warning: With two trait object types, even when the complete set of traits is
535555
> the same, if the base traits differ, the type is different. For example,
536-
> `Send + Sync` is a different type from `Sync + Send`. See [issue 33140].
556+
> `dyn Send + Sync` is a different type from `dyn Sync + Send`. See
557+
> [issue 33140].
537558
538559
> Warning: Including the same auto trait multiple times is allowed, and each
539-
> instance is considered a unique type. As such, `Trait + Send` is a distinct
540-
> type than `Trait + Send + Send`. See [issue 47010].
560+
> instance is considered a unique type. As such, `dyn Trait + Send` is a
561+
> distinct type to `dyn Trait + Send + Send`. See [issue 47010].
541562
542563
Due to the opaqueness of which concrete type the value is of, trait objects are
543564
[dynamically sized types]. Like all
544565
<abbr title="dynamically sized types">DSTs</abbr>, trait objects are used
545-
behind some type of pointer; for example `&SomeTrait` or `Box<SomeTrait>`. Each
546-
instance of a pointer to a trait object includes:
566+
behind some type of pointer; for example `&dyn SomeTrait` or
567+
`Box<dyn SomeTrait>`. Each instance of a pointer to a trait object includes:
547568

548569
- a pointer to an instance of a type `T` that implements `SomeTrait`
549570
- a _virtual method table_, often just called a _vtable_, which contains, for
@@ -567,12 +588,12 @@ impl Printable for i32 {
567588
fn stringify(&self) -> String { self.to_string() }
568589
}
569590

570-
fn print(a: Box<Printable>) {
591+
fn print(a: Box<dyn Printable>) {
571592
println!("{}", a.stringify());
572593
}
573594

574595
fn main() {
575-
print(Box::new(10) as Box<Printable>);
596+
print(Box::new(10) as Box<dyn Printable>);
576597
}
577598
```
578599

0 commit comments

Comments
 (0)