Extend rust reference with a section about type coercions · rust-lang/reference@4c39f37 (original) (raw)
`@@ -3619,6 +3619,126 @@ fn bar<'a>() {
`
3619
3619
`` Since 'static "lives longer" than 'a, &'static str is a subtype of
``
3620
3620
`` &'a str.
``
3621
3621
``
``
3622
`+
Type coercions
`
``
3623
+
``
3624
`+
Coercions are defined in RFC401. A coercion is implicit and has no syntax.
`
``
3625
+
``
3626
`+
`
``
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
`` +
letstatements where an explicit type is given.
``
``
3636
+
``
3637
`` +
In let _: U = e;, e is coerced to have type U.
``
``
3638
+
``
3639
`` +
staticandconststatements (similar toletstatements).
``
``
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 asFoo { 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 typeU, 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
`` +
TtoUifTis a subtype ofU(reflexive case).
``
``
3687
+
``
3688
`` +
T_1toT_3whereT_1coerces toT_2andT_2coerces toT_3
``
``
3689
`+
(transitive case).
`
``
3690
+
``
3691
`+
Note that this is not fully supported yet
`
``
3692
+
``
3693
`` +
&mut Tto&T.
``
``
3694
+
``
3695
`` +
*mut Tto*const T.
``
``
3696
+
``
3697
`` +
&Tto*const T.
``
``
3698
+
``
3699
`` +
&mut Tto*mut T.
``
``
3700
+
``
3701
`` +
&Tto&UifTimplementsDeref<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 Tto&mut UifTimplementsDerefMut<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) =UwhereTis 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
+
3622
3742
`# Special traits
`
3623
3743
``
3624
3744
`Several traits define special evaluation behavior.
`