3 Coercions are defined in [RFC 401]. [RFC 1558] then expanded on that.
4 A coercion is implicit and has no syntax.
6 [RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
7 [RFC 1558]: https://github.com/rust-lang/rfcs/blob/master/text/1558-closure-to-fn-coercion.md
11 A coercion can only occur at certain coercion sites in a program; these are
12 typically places where the desired type is explicit or can be derived by
13 propagation from explicit types (without type inference). Possible coercion
16 * `let` statements where an explicit type is given.
18 For example, `42` is coerced to have type `i8` in the following:
24 * `static` and `const` statements (similar to `let` statements).
26 * Arguments for function calls
28 The value being coerced is the actual parameter, and it is coerced to
29 the type of the formal parameter.
31 For example, `42` is coerced to have type `i8` in the following:
41 * Instantiations of struct or variant fields
43 For example, `42` is coerced to have type `i8` in the following:
53 * Function results, either the final line of a block if it is not
54 semicolon-terminated or any expression in a `return` statement
56 For example, `42` is coerced to have type `i8` in the following:
64 If the expression in one of these coercion sites is a coercion-propagating
65 expression, then the relevant sub-expressions in that expression are also
66 coercion sites. Propagation recurses from these new coercion sites.
67 Propagating expressions and their relevant sub-expressions are:
69 * Array literals, where the array has type `[U; n]`. Each sub-expression in
70 the array literal is a coercion site for coercion to type `U`.
72 * Array literals with repeating syntax, where the array has type `[U; n]`. The
73 repeated sub-expression is a coercion site for coercion to type `U`.
75 * Tuples, where a tuple is a coercion site to type `(U_0, U_1, ..., U_n)`.
76 Each sub-expression is a coercion site to the respective type, e.g. the
77 zeroth sub-expression is a coercion site to type `U_0`.
79 * Parenthesized sub-expressions (`(e)`): if the expression has type `U`, then
80 the sub-expression is a coercion site to `U`.
82 * Blocks: if a block has type `U`, then the last expression in the block (if
83 it is not semicolon-terminated) is a coercion site to `U`. This includes
84 blocks which are part of control flow statements, such as `if`/`else`, if
85 the block has a known type.
89 Coercion is allowed between the following types:
91 * `T` to `U` if `T` is a subtype of `U` (*reflexive case*)
93 * `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to `T_3`
96 Note that this is not fully supported yet
100 * `*mut T` to `*const T`
104 * `&mut T` to `*mut T`
106 * `&T` to `&U` if `T` implements `Deref<Target = U>`. For example:
111 struct CharContainer {
115 impl Deref for CharContainer {
118 fn deref<'a>(&'a self) -> &'a char {
123 fn foo(arg: &char) {}
126 let x = &mut CharContainer { value: 'y' };
127 foo(x); //&mut CharContainer is coerced to &char.
131 * `&mut T` to `&mut U` if `T` implements `DerefMut<Target = U>`.
133 * TyCtor(`T`) to TyCtor(coerce_inner(`T`)), where TyCtor(`T`) is one of
141 - coerce_inner(`[T, ..n]`) = `[T]`
142 - coerce_inner(`T`) = `U` where `T` is a concrete type which implements the
145 <!--In the future, coerce_inner will be recursively extended to tuples and
146 structs. In addition, coercions from sub-traits to super-traits will be
147 added. See [RFC 401] for more details.-->
149 * Non capturing closures to `fn` pointers