]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | # Opaque types (type alias `impl Trait`) |
2 | ||
3 | Opaque types are syntax to declare an opaque type alias that only | |
4 | exposes a specific set of traits as their interface; the concrete type in the | |
5 | background is inferred from a certain set of use sites of the opaque type. | |
6 | ||
7 | This is expressed by using `impl Trait` within type aliases, for example: | |
8 | ||
9 | ```rust,ignore | |
10 | type Foo = impl Bar; | |
11 | ``` | |
12 | ||
13 | This declares an opaque type named `Foo`, of which the only information is that | |
14 | it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, | |
15 | but nothing else (regardless of whether it implements any other traits). | |
16 | ||
6a06907d XL |
17 | Since there needs to be a concrete background type, you can (as of <!-- date: |
18 | 2021-01 --> January 2021) express that type by using the opaque type in a | |
19 | "defining use site". | |
e1599b0c XL |
20 | |
21 | ```rust,ignore | |
22 | struct Struct; | |
23 | impl Bar for Struct { /* stuff */ } | |
24 | fn foo() -> Foo { | |
25 | Struct | |
26 | } | |
27 | ``` | |
28 | ||
29 | Any other "defining use site" needs to produce the exact same type. | |
30 | ||
31 | ## Defining use site(s) | |
32 | ||
33 | Currently only the return value of a function can be a defining use site | |
34 | of an opaque type (and only if the return type of that function contains | |
35 | the opaque type). | |
36 | ||
37 | The defining use of an opaque type can be any code *within* the parent | |
38 | of the opaque type definition. This includes any siblings of the | |
39 | opaque type and all children of the siblings. | |
40 | ||
41 | The initiative for *"not causing fatal brain damage to developers due to | |
42 | accidentally running infinite loops in their brain while trying to | |
43 | comprehend what the type system is doing"* has decided to disallow children | |
44 | of opaque types to be defining use sites. | |
45 | ||
46 | ### Associated opaque types | |
47 | ||
48 | Associated opaque types can be defined by any other associated item | |
49 | on the same trait `impl` or a child of these associated items. For instance: | |
50 | ||
51 | ```rust,ignore | |
52 | trait Baz { | |
53 | type Foo; | |
54 | fn foo() -> Self::Foo; | |
55 | } | |
56 | ||
57 | struct Quux; | |
58 | ||
59 | impl Baz for Quux { | |
60 | type Foo = impl Bar; | |
61 | fn foo() -> Self::Foo { ... } | |
62 | } | |
63 | ``` |