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.intro] 
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