@@ -507,10 +507,10 @@ Because captures are often by reference, the following general rules arise:
507
507
508
508
> ** <sup >Syntax</sup >**
509
509
> _ TraitObjectType_ :
510
- >   ;  ; _ LifetimeOrPath_ ( ` + ` _ LifetimeOrPath_ )<sup >\* </sup > ` + ` <sup >?</sup >
510
+ >   ;  ; ` dyn ` < sup >?</ sup > _ LifetimeOrPath_ ( ` + ` _ LifetimeOrPath_ )<sup >\* </sup > ` + ` <sup >?</sup >
511
511
>
512
512
> _ LifetimeOrPath_ :
513
- >   ;  ; [ _ Path_ ] | [ _ LIFETIME_OR_LABEL_ ]
513
+ >   ;  ; [ _ Path_ ] | ` ( ` [ _ Path _ ] ` ) ` | [ _ LIFETIME_OR_LABEL_ ]
514
514
515
515
A * trait object* is an opaque value of another type that implements a set of
516
516
traits. The set of traits is made up of an [ object safe] * base trait* plus any
@@ -519,31 +519,52 @@ number of [auto traits].
519
519
Trait objects implement the base trait, its auto traits, and any super traits
520
520
of the base trait.
521
521
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.
528
548
529
549
Two trait object types alias each other if the base traits alias each other and
530
550
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` .
533
553
534
554
> Warning: With two trait object types, even when the complete set of traits is
535
555
> 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] .
537
558
538
559
> 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] .
541
562
542
563
Due to the opaqueness of which concrete type the value is of, trait objects are
543
564
[ dynamically sized types] . Like all
544
565
<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:
547
568
548
569
- a pointer to an instance of a type ` T ` that implements ` SomeTrait `
549
570
- a _ virtual method table_ , often just called a _ vtable_ , which contains, for
@@ -567,12 +588,12 @@ impl Printable for i32 {
567
588
fn stringify (& self ) -> String { self . to_string () }
568
589
}
569
590
570
- fn print (a : Box <Printable >) {
591
+ fn print (a : Box <dyn Printable >) {
571
592
println! (" {}" , a . stringify ());
572
593
}
573
594
574
595
fn main () {
575
- print (Box :: new (10 ) as Box <Printable >);
596
+ print (Box :: new (10 ) as Box <dyn Printable >);
576
597
}
577
598
```
578
599
0 commit comments