|
| 1 | +- Feature Name: dyn-keyword |
| 2 | +- Start Date: 2016-05-01 |
| 3 | +- RFC PR: (leave this empty) |
| 4 | +- Rust Issue: (leave this empty) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +Introduce a keyword, `dyn`, for denoting dynamic dispatch, with the motivation |
| 10 | +of avoid "accidental overhead" and making the costs more explicit, along with |
| 11 | +deprecation of the old syntax. |
| 12 | + |
| 13 | +# Motivation |
| 14 | +[motivation]: #motivation |
| 15 | + |
| 16 | +The current syntax for dynamic dispatch, making use of traits as unsized types, |
| 17 | +does not align very well with the Rust philosophy for two reasons: |
| 18 | + |
| 19 | +1. It hides the overhead: One would think that `Box<Trait>` simply carried the |
| 20 | + overhead of the allocation and indirection, but, in fact, the major overhead |
| 21 | + stems from dynamic dispatch. This expense is rather implicit, in that there |
| 22 | + is denotation nor sigil to signify this overhead. |
| 23 | +2. It is prone to subtle mistakes and unnecessary dynamic dispatch due to |
| 24 | + `Trait` appearing like a unsized type. |
| 25 | + |
| 26 | +Furthermore, it is worth noting that `Trait` is not a type, despite it may seem |
| 27 | +so. |
| 28 | + |
| 29 | +# Detailed design |
| 30 | +[design]: #detailed-design |
| 31 | + |
| 32 | +To overcome these hurdles, we introduce a new syntax: `dyn Trait`. |
| 33 | + |
| 34 | +`dyn Trait` is an unsized type, which is the dynamically dispatched form of |
| 35 | +`Trait`. Two things are essential to the semantics: |
| 36 | + |
| 37 | +1. `∀T.[dyn T]∊T`: namely that `dyn Trait` satisfy the bound `: Trait`. |
| 38 | +2. `∀t∊T.[c (dyn T) <: c t]`: meaning that `T` where `T: Trait` can coerce into |
| 39 | + `dyn Trait`. This rule is similar to the current trait object coercion rule. |
| 40 | + |
| 41 | +It is worth mentioning that `dyn` is not, and can not be, a type constructor. |
| 42 | +Traits are classes of types, not types them self. |
| 43 | + |
| 44 | +Secondly, we add a deprecation lint against the current syntax, where traits |
| 45 | +are treated like types. |
| 46 | + |
| 47 | +# Examples |
| 48 | + |
| 49 | +```rust |
| 50 | +let vec: Box<Any> = box 4; |
| 51 | +``` |
| 52 | + |
| 53 | +will now be |
| 54 | + |
| 55 | +```rust |
| 56 | +let vec: Box<dyn Any> = box 4; |
| 57 | +``` |
| 58 | + |
| 59 | +# Drawbacks |
| 60 | +[drawbacks]: #drawbacks |
| 61 | + |
| 62 | +This won't cause breakage, but deprecation is certainly a drawback. |
| 63 | + |
| 64 | +# Alternatives |
| 65 | +[alternatives]: #alternatives |
| 66 | + |
| 67 | +## Have a "magic" type constructor, `Object<Trait>`. |
| 68 | + |
| 69 | +Acting as a dynamic dispatcher for `Trait`. |
| 70 | + |
| 71 | +## Leave it as is. |
| 72 | + |
| 73 | +# Unresolved questions |
| 74 | +[unresolved]: #unresolved-questions |
| 75 | + |
| 76 | +None. |
0 commit comments