11# Type coercions
22
3+ r[ coerce]
4+
5+ r[ coerce.intro]
36** Type coercions** are implicit operations that change the type of a value.
47They happen automatically at specific locations and are highly restricted in
58what types actually coerce.
69
10+ r[ cerce.as]
711Any conversions allowed by coercion can also be explicitly performed by the
812[ type cast operator] , ` as ` .
913
1014Coercions are originally defined in [ RFC 401] and expanded upon in [ RFC 1558] .
1115
1216## Coercion sites
1317
18+ r[ coerce.site]
19+
20+ r[ coerce.site.intro]
1421A coercion can only occur at certain coercion sites in a program; these are
1522typically places where the desired type is explicit or can be derived by
1623propagation from explicit types (without type inference). Possible coercion
1724sites are:
1825
26+ r[ coerce.site.let]
1927* ` let ` statements where an explicit type is given.
2028
2129 For example, ` &mut 42 ` is coerced to have type ` &i8 ` in the following:
@@ -24,8 +32,10 @@ sites are:
2432 let _ : & i8 = & mut 42 ;
2533 ```
2634
35+ r[ coerce.site.value]
2736* ` static ` and ` const ` item declarations (similar to ` let ` statements).
2837
38+ r[ coerce.site.argument]
2939* Arguments for function calls
3040
3141 The value being coerced is the actual parameter, and it is coerced to
@@ -44,6 +54,7 @@ sites are:
4454 For method calls, the receiver (` self ` parameter) type is coerced
4555 differently, see the documentation on [ method-call expressions] for details.
4656
57+ r[ coerce.site.constructor]
4758* Instantiations of struct, union, or enum variant fields
4859
4960 For example, ` &mut 42 ` is coerced to have type ` &i8 ` in the following:
@@ -56,6 +67,7 @@ sites are:
5667 }
5768 ```
5869
70+ r[ coerce.site.return]
5971* Function results&mdash ; either the final line of a block if it is not
6072 semicolon-terminated or any expression in a ` return ` statement
6173
@@ -68,48 +80,64 @@ sites are:
6880 }
6981 ```
7082
83+ r[ coerce.site.subexpr]
7184If the expression in one of these coercion sites is a coercion-propagating
7285expression, then the relevant sub-expressions in that expression are also
7386coercion sites. Propagation recurses from these new coercion sites.
7487Propagating expressions and their relevant sub-expressions are:
7588
89+ r[ coerce.site.array]
7690* Array literals, where the array has type ` [U; n] ` . Each sub-expression in
7791the array literal is a coercion site for coercion to type ` U ` .
7892
93+ r[ coerce.site.repeat]
7994* Array literals with repeating syntax, where the array has type ` [U; n] ` . The
8095repeated sub-expression is a coercion site for coercion to type ` U ` .
8196
97+ r[ coerce.site.tuple]
8298* Tuples, where a tuple is a coercion site to type ` (U_0, U_1, ..., U_n) ` .
8399Each sub-expression is a coercion site to the respective type, e.g. the
84100zeroth sub-expression is a coercion site to type ` U_0 ` .
85101
102+ r[ coerce.site.parenthesis]
86103* Parenthesized sub-expressions (` (e) ` ): if the expression has type ` U ` , then
87104the sub-expression is a coercion site to ` U ` .
88105
106+ r[ coerce.site.block]
89107* Blocks: if a block has type ` U ` , then the last expression in the block (if
90108it is not semicolon-terminated) is a coercion site to ` U ` . This includes
91109blocks which are part of control flow statements, such as ` if ` /` else ` , if
92110the block has a known type.
93111
94112## Coercion types
95113
114+ r[ coerce.types]
115+
116+ r[ coerce.types.intro]
96117Coercion is allowed between the following types:
97118
119+ r[ coerce.types.reflexive]
98120* ` T ` to ` U ` if ` T ` is a [ subtype] of ` U ` (* reflexive case* )
99121
122+ r[ coerce.types.transitive]
100123* ` T_1 ` to ` T_3 ` where ` T_1 ` coerces to ` T_2 ` and ` T_2 ` coerces to ` T_3 `
101124(* transitive case* )
102125
103126 Note that this is not fully supported yet.
104127
128+ r[ coerce.types.mut-reborrow]
105129* ` &mut T ` to ` &T `
106130
131+ r[ coerce.types.mut-pointer]
107132* ` *mut T ` to ` *const T `
108133
134+ r[ coerce.types.ref-to-pointer]
109135* ` &T ` to ` *const T `
110136
137+ r[ coerce.types.mut-to-pointer]
111138* ` &mut T ` to ` *mut T `
112139
140+ r[ coerce.types.deref]
113141* ` &T ` or ` &mut T ` to ` &U ` if ` T ` implements ` Deref<Target = U> ` . For example:
114142
115143 ``` rust
@@ -135,8 +163,10 @@ Coercion is allowed between the following types:
135163 }
136164 ```
137165
166+ r[ coerce.types.deref-mut]
138167* ` &mut T ` to ` &mut U ` if ` T ` implements ` DerefMut<Target = U> ` .
139168
169+ r[ coerce.types.unsize]
140170* TyCtor(` T ` ) to TyCtor(` U ` ), where TyCtor(` T ` ) is one of
141171 - ` &T `
142172 - ` &mut T `
@@ -150,35 +180,46 @@ Coercion is allowed between the following types:
150180 structs. In addition, coercions from subtraits to supertraits will be
151181 added. See [RFC 401] for more details.-->
152182
183+ r[ coerce.types.fn]
153184* Function item types to ` fn ` pointers
154185
186+ r[ coerce.types.closure]
155187* Non capturing closures to ` fn ` pointers
156188
189+ r[ coerce.types.never]
157190* ` ! ` to any ` T `
158191
159192### Unsized Coercions
160193
194+ r[ coerce.unsize]
195+
196+ r[ coerce.unsize.intro]
161197The following coercions are called ` unsized coercions ` , since they
162198relate to converting sized types to unsized types, and are permitted in a few
163199cases where other coercions are not, as described above. They can still happen
164200anywhere else a coercion can occur.
165201
202+ r[ coerce.unsize.trait]
166203Two traits, [ ` Unsize ` ] and [ ` CoerceUnsized ` ] , are used
167204to assist in this process and expose it for library use. The following
168205coercions are built-ins and, if ` T ` can be coerced to ` U ` with one of them, then
169206an implementation of ` Unsize<U> ` for ` T ` will be provided:
170207
208+ r[ coerce.unsize.slice]
171209* ` [T; n] ` to ` [T] ` .
172210
211+ r[ coerce.unsize.trait-object]
173212* ` T ` to ` dyn U ` , when ` T ` implements ` U + Sized ` , and ` U ` is [ object safe] .
174213
214+ r[ coerce.unsized.composite]
175215* ` Foo<..., T, ...> ` to ` Foo<..., U, ...> ` , when:
176216 * ` Foo ` is a struct.
177217 * ` T ` implements ` Unsize<U> ` .
178218 * The last field of ` Foo ` has a type involving ` T ` .
179219 * If that field has type ` Bar<T> ` , then ` Bar<T> ` implements ` Unsized<Bar<U>> ` .
180220 * T is not part of the type of any other fields.
181221
222+ r[ coerce.unsized.pointer]
182223Additionally, a type ` Foo<T> ` can implement ` CoerceUnsized<Foo<U>> ` when ` T `
183224implements ` Unsize<U> ` or ` CoerceUnsized<Foo<U>> ` . This allows it to provide an
184225unsized coercion to ` Foo<U> ` .
@@ -189,6 +230,9 @@ unsized coercion to `Foo<U>`.
189230
190231## Least upper bound coercions
191232
233+ r[ coerce.least-upper-bound]
234+
235+ r[ coerce.least-upper-bound]
192236In some contexts, the compiler must coerce together multiple types to try and
193237find the most general type. This is called a "Least Upper Bound" coercion.
194238LUB coercion is used and only used in the following situations:
@@ -199,15 +243,24 @@ LUB coercion is used and only used in the following situations:
199243+ To find the type for the return type of a closure with multiple return statements.
200244+ To check the type for the return type of a function with multiple return statements.
201245
246+ r[ coerce.least-upper-bound.target]
202247In each such case, there are a set of types ` T0..Tn ` to be mutually coerced
203- to some target type ` T_t ` , which is unknown to start. Computing the LUB
248+ to some target type ` T_t ` , which is unknown to start.
249+
250+ r[ coerce.least-upper-bound.computation]
251+ Computing the LUB
204252coercion is done iteratively. The target type ` T_t ` begins as the type ` T0 ` .
205253For each new type ` Ti ` , we consider whether
206254
255+ r[ coerce.least-upper-bound.computation-identity]
207256+ If ` Ti ` can be coerced to the current target type ` T_t ` , then no change is made.
257+
258+ r[ coerce.least-upper-bound.computation-replace]
208259+ Otherwise, check whether ` T_t ` can be coerced to ` Ti ` ; if so, the ` T_t ` is
209260changed to ` Ti ` . (This check is also conditioned on whether all of the source
210261expressions considered thus far have implicit coercions.)
262+
263+ r[ coerce.least-upper-bound.computation-unify]
211264+ If not, try to compute a mutual supertype of ` T_t ` and ` Ti ` , which will become the new target type.
212265
213266### Examples:
0 commit comments