@@ -3619,6 +3619,126 @@ fn bar<'a>() {
36193619Since ` 'static ` "lives longer" than ` 'a ` , ` &'static str ` is a subtype of
36203620` &'a str ` .
36213621
3622+ ## Type coercions
3623+
3624+ Coercions are defined in [ RFC401] . A coercion is implicit and has no syntax.
3625+
3626+ [ RFC401 ] : https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
3627+
3628+ ### Coercion sites
3629+
3630+ A coercion can only occur at certain coercion sites in a program; these are
3631+ typically places where the desired type is explicit or can be dervied by
3632+ propagation from explicit types (without type inference). Possible coercion
3633+ sites are:
3634+
3635+ * ` let ` statements where an explicit type is given.
3636+
3637+ In ` let _: U = e; ` , ` e ` is coerced to have type ` U ` .
3638+
3639+ * ` static ` and ` const ` statements (similar to ` let ` statements).
3640+
3641+ * arguments for function calls.
3642+
3643+ The value being coerced is the
3644+ actual parameter and it is coerced to the type of the formal parameter. For
3645+ example, let ` foo ` be defined as ` fn foo(x: U) { ... } ` and call it as
3646+ ` foo(e); ` . Then ` e ` is coerced to have type ` U ` ;
3647+
3648+ * instantiations of struct or variant fields.
3649+
3650+ Assume we have a `struct
3651+ Foo { x: U }` and instantiate it as ` Foo { x: e }` . Then ` e` is coerced to
3652+ have type ` U ` .
3653+
3654+ * function results (either the final line of a block if it is not semicolon
3655+ terminated or any expression in a ` return ` statement).
3656+
3657+ In `fn foo() -> U { e }`, `e` is coerced to to have type `U`.
3658+
3659+ If the expression in one of these coercion sites is a coercion-propagating
3660+ expression, then the relevant sub-expressions in that expression are also
3661+ coercion sites. Propagation recurses from these new coercion sites.
3662+ Propagating expressions and their relevant sub-expressions are:
3663+
3664+ * array literals, where the array has type ` [U; n] ` . Each sub-expression in
3665+ the array literal is a coercion site for coercion to type ` U ` .
3666+
3667+ * array literals with repeating syntax, where the array has type ` [U; n] ` . The
3668+ repeated sub-expression is a coercion site for coercion to type ` U ` .
3669+
3670+ * tuples, where a tuple is a coercion site to type ` (U_0, U_1, ..., U_n) ` .
3671+ Each sub-expression is a coercion site to the respective type, e.g. the
3672+ zeroth sub-expression is a coercion site to type ` U_0 ` .
3673+
3674+ * parenthesised sub-expressions (` (e) ` ). If the expression has type ` U ` , then
3675+ the sub-expression is a coercion site to ` U ` .
3676+
3677+ * blocks. If a block has type ` U ` , then the last expression in the block (if
3678+ it is not semicolon-terminated) is a coercion site to ` U ` . This includes
3679+ blocks which are part of control flow statements, such as ` if ` /` else ` , if
3680+ the block has a known type.
3681+
3682+ ### Coercion types
3683+
3684+ Coercion is allowed between the following types:
3685+
3686+ * ` T ` to ` U ` if ` T ` is a subtype of ` U ` (* reflexive case* ).
3687+
3688+ * ` T_1 ` to ` T_3 ` where ` T_1 ` coerces to ` T_2 ` and ` T_2 ` coerces to ` T_3 `
3689+ (* transitive case* ).
3690+
3691+ Note that this is not fully supported yet
3692+
3693+ * ` &mut T ` to ` &T ` .
3694+
3695+ * ` *mut T ` to ` *const T ` .
3696+
3697+ * ` &T ` to ` *const T ` .
3698+
3699+ * ` &mut T ` to ` *mut T ` .
3700+
3701+ * ` &T ` to ` &U ` if ` T ` implements ` Deref<Target = U> ` . For example:
3702+ ```
3703+ use std::ops::Deref;
3704+
3705+ struct CharContainer {
3706+ value: char
3707+ }
3708+
3709+ impl Deref for CharContainer {
3710+ type Target = char;
3711+
3712+ fn deref<'a>(&'a self) -> &'a char {
3713+ &self.value
3714+ }
3715+ }
3716+
3717+ fn foo(arg: &char) {}
3718+
3719+ fn main() {
3720+ let x = &mut CharContainer { value: 'y' };
3721+ foo(x); //&mut CharContainer is coerced to &char.
3722+ }
3723+ ```
3724+ * `&mut T` to `&mut U` if `T` implements `DerefMut<Target = U>`.
3725+
3726+ * TyCtor(`T`) to TyCtor(coerce_inner(`T`)), where TyCtor(`T`) is one of
3727+ - `&T`
3728+ - `&mut T`
3729+ - `*const T`
3730+ - `*mut T`
3731+ - `Box<T>`
3732+
3733+ and where
3734+ - coerce_inner(`[T, ..n]`) = `[T]`
3735+ - coerce_inner(`T`) = `U` where `T` is a concrete type which implements the
3736+ trait `U`.
3737+
3738+ In the future, coerce_inner will be recursively extended to tuples and
3739+ structs. In addition, coercions from sub-traits to super-traits will be
3740+ added. See [RFC401] for more details.
3741+
36223742# Special traits
36233743
36243744Several traits define special evaluation behavior.
0 commit comments