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