@@ -32,21 +32,6 @@ more ergonomic alternatives.
32
32
33
33
34
34
35
- # Auto-Deref
36
-
37
- (Maybe nix this in favour of receiver coercions)
38
-
39
- Deref is a trait that allows you to overload the unary ` * ` to specify a type
40
- you dereference to. This is largely only intended to be implemented by pointer
41
- types like ` & ` , ` Box ` , and ` Rc ` . The dot operator will automatically perform
42
- automatic dereferencing, so that foo.bar() will work uniformly on ` Foo ` , ` &Foo ` , `
43
- &&Foo` , ` &Rc<Box<&mut&Box<Foo >>>` and so-on. Search bottoms out on the * first* match,
44
- so implementing methods on pointers is generally to be avoided, as it will shadow
45
- "actual" methods.
46
-
47
-
48
-
49
-
50
35
# Coercions
51
36
52
37
Types can implicitly be coerced to change in certain contexts. These changes are
@@ -58,118 +43,75 @@ Here's all the kinds of coercion:
58
43
59
44
Coercion is allowed between the following types:
60
45
61
- * ` T ` to ` U ` if ` T ` is a [ subtype] ( lifetimes.html#subtyping-and-variance )
62
- of ` U ` (the 'identity' case);
63
-
64
- * ` T_1 ` to ` T_3 ` where ` T_1 ` coerces to ` T_2 ` and ` T_2 ` coerces to ` T_3 `
65
- (transitivity case);
66
-
67
- * ` &mut T ` to ` &T ` ;
68
-
69
- * ` *mut T ` to ` *const T ` ;
70
-
71
- * ` &T ` to ` *const T ` ;
72
-
73
- * ` &mut T ` to ` *mut T ` ;
74
-
75
- * ` T ` to ` U ` if ` T ` implements ` CoerceUnsized<U> ` (see below) and ` T = Foo<...> `
76
- and ` U = Foo<...> ` ;
77
-
78
- * From TyCtor(` T ` ) to TyCtor(coerce_inner(` T ` ));
79
-
80
- where TyCtor(` T ` ) is one of ` &T ` , ` &mut T ` , ` *const T ` , ` *mut T ` , or ` Box<T> ` .
81
- And where coerce_inner is defined as
82
-
83
- * coerce_inner(` [T, ..n] ` ) = ` [T] ` ;
84
-
85
- * coerce_inner(` T ` ) = ` U ` where ` T ` is a concrete type which implements the
86
- trait ` U ` ;
87
-
88
- * coerce_inner(` T ` ) = ` U ` where ` T ` is a sub-trait of ` U ` ;
89
-
90
- * coerce_inner(` Foo<..., T, ...> ` ) = ` Foo<..., coerce_inner(T), ...> ` where
91
- ` Foo ` is a struct and only the last field has type ` T ` and ` T ` is not part of
92
- the type of any other fields;
93
-
94
- * coerce_inner(` (..., T) ` ) = ` (..., coerce_inner(T)) ` .
95
-
96
- Coercions only occur at a * coercion site* . Exhaustively, the coercion sites
97
- are:
98
-
99
- * In ` let ` statements where an explicit type is given: in ` let _: U = e; ` , ` e `
100
- is coerced to to have type ` U ` ;
101
-
102
- * In statics and consts, similarly to ` let ` statements;
103
-
104
- * In argument position for function calls. The value being coerced is the actual
105
- parameter and it is coerced to the type of the formal parameter. For example,
106
- where ` foo ` is defined as ` fn foo(x: U) { ... } ` and is called with ` foo(e); ` ,
107
- ` e ` is coerced to have type ` U ` ;
108
-
109
- * Where a field of a struct or variant is instantiated. E.g., where `struct Foo
110
- { x: U }` and the instantiation is ` Foo { x: e }` , ` e` is coerced to to have
111
- type ` U ` ;
112
-
113
- * The result of a function, either the final line of a block if it is not semi-
114
- colon terminated or any expression in a ` return ` statement. For example, for
115
- ` fn foo() -> U { e } ` , ` e ` is coerced to to have type ` U ` ;
116
-
117
- If the expression in one of these coercion sites is a coercion-propagating
118
- expression, then the relevant sub-expressions in that expression are also
119
- coercion sites. Propagation recurses from these new coercion sites. Propagating
120
- expressions and their relevant sub-expressions are:
121
-
122
- * array literals, where the array has type ` [U, ..n] ` , each sub-expression in
123
- the array literal is a coercion site for coercion to type ` U ` ;
124
-
125
- * array literals with repeating syntax, where the array has type ` [U, ..n] ` , the
126
- repeated sub-expression is a coercion site for coercion to type ` U ` ;
127
-
128
- * tuples, where a tuple is a coercion site to type ` (U_0, U_1, ..., U_n) ` , each
129
- sub-expression is a coercion site for the respective type, e.g., the zero-th
130
- sub-expression is a coercion site to ` U_0 ` ;
131
-
132
- * the box expression, if the expression has type ` Box<U> ` , the sub-expression is
133
- a coercion site to ` U ` ;
134
-
135
- * parenthesised sub-expressions (` (e) ` ), if the expression has type ` U ` , then
136
- the sub-expression is a coercion site to ` U ` ;
137
-
138
- * blocks, if a block has type ` U ` , then the last expression in the block (if it
139
- is not semicolon-terminated) is a coercion site to ` U ` . This includes blocks
140
- which are part of control flow statements, such as ` if ` /` else ` , if the block
141
- has a known type.
142
-
46
+ * Subtyping: ` T ` to ` U ` if ` T ` is a [ subtype] ( lifetimes.html#subtyping-and-variance )
47
+ of ` U `
48
+ * Transitivity: ` T_1 ` to ` T_3 ` where ` T_1 ` coerces to ` T_2 ` and ` T_2 ` coerces to ` T_3 `
49
+ * Pointer Weakening:
50
+ * ` &mut T ` to ` &T `
51
+ * ` *mut T ` to ` *const T `
52
+ * ` &T ` to ` *const T `
53
+ * ` &mut T ` to ` *mut T `
54
+ * Unsizing: ` T ` to ` U ` if ` T ` implements ` CoerceUnsized<U> `
55
+
56
+ ` CoerceUnsized<Pointer<U>> for Pointer<T> ` where T: Unsize<U > is implemented
57
+ for all pointer types (including smart pointers like Box and Rc). Unsize is
58
+ only implemented automatically, and enables the following transformations:
59
+
60
+ * ` [T, ..n] ` => ` [T] `
61
+ * ` T ` => ` Trait ` where ` T: Trait `
62
+ * ` SubTrait ` => ` Trait ` where ` SubTrait: Trait ` (TODO: is this now implied by the previous?)
63
+ * ` Foo<..., T, ...> ` => ` Foo<..., U, ...> ` where:
64
+ * T: Unsize<U >
65
+ * ` Foo ` is a struct
66
+ * Only the last field has type ` T `
67
+ * ` T ` is not part of the type of any other fields
68
+ (note that this also applies to to tuples as an anonymous struct ` Tuple3<T, U, V> ` )
69
+
70
+ Coercions occur at a * coercion site* . Any location that is explicitly typed
71
+ will cause a coercion to its type. If inference is necessary, the coercion will
72
+ not be performed. Exhaustively, the coercion sites for an expression ` e ` to
73
+ type ` U ` are:
74
+
75
+ * let statements, statics, and consts: ` let x: U = e `
76
+ * Arguments to functions: ` takes_a_U(e) `
77
+ * Any expression that will be returned: ` fn foo() -> U { e } `
78
+ * Struct literals: ` Foo { some_u: e } `
79
+ * Array literals: ` let x: [U; 10] = [e, ..] `
80
+ * Tuple literals: ` let x: (U, ..) = (e, ..) `
81
+ * The last expression in a block: ` let x: U = { ..; e } `
143
82
144
83
Note that we do not perform coercions when matching traits (except for
145
84
receivers, see below). If there is an impl for some type ` U ` and ` T ` coerces to
146
85
` U ` , that does not constitute an implementation for ` T ` . For example, the
147
86
following will not type check, even though it is OK to coerce ` t ` to ` &T ` and
148
87
there is an impl for ` &T ` :
149
88
150
- ```
151
- struct T;
89
+ ``` rust
152
90
trait Trait {}
153
91
154
92
fn foo <X : Trait >(t : X ) {}
155
93
156
- impl<'a> Trait for &'a T {}
94
+ impl <'a > Trait for & 'a i32 {}
157
95
158
96
159
97
fn main () {
160
- let t: &mut T = &mut T ;
161
- foo(t); //~ ERROR failed to find an implementation of trait Trait for &mut T
98
+ let t : & mut i32 = & mut 0 ;
99
+ foo (t );
162
100
}
163
101
```
164
102
165
- In a cast expression, ` e as U ` , the compiler will first attempt to coerce ` e ` to
166
- ` U ` , only if that fails will the conversion rules for casts (see below) be
167
- applied.
168
-
103
+ ``` text
104
+ <anon>:10:5: 10:8 error: the trait `Trait` is not implemented for the type `&mut i32` [E0277]
105
+ <anon>:10 foo(t);
106
+ ^~~
107
+ ```
169
108
109
+ # The Dot Operator
170
110
171
- TODO: receiver coercions?
111
+ The dot operator will perform a lot of magic to convert types. It will perform
112
+ auto-referencing, auto-dereferencing, and coercion until types match.
172
113
114
+ TODO: steal information from http://stackoverflow.com/questions/28519997/what-are-rusts-exact-auto-dereferencing-rules/28552082#28552082
173
115
174
116
# Casts
175
117
@@ -178,21 +120,21 @@ cast, but some conversions *require* a cast. These "true casts" are generally re
178
120
as dangerous or problematic actions. True casts revolve around raw pointers and
179
121
the primitive numeric types. True casts aren't checked.
180
122
181
- Here's an exhaustive list of all the true casts:
182
-
183
- * ` e ` has type ` T ` and ` T ` coerces to ` U ` ; * coercion-cast *
184
- * ` e ` has type ` *T ` , ` U ` is ` *U_0 ` , and either ` U_0 : Sized` or
185
- unsize_kind( ` T ` ) = unsize_kind( ` U_0 ` ); * ptr-ptr-cast *
186
- * ` e ` has type ` *T ` and ` U ` is a numeric type, while ` T: Sized ` ; * ptr-addr-cast *
187
- * ` e ` is an integer and ` U ` is ` *U_0 ` , while ` U_0: Sized ` ; * addr-ptr-cast *
188
- * ` e ` has type ` T ` and ` T ` and ` U ` are any numeric types; * numeric-cast *
189
- * ` e ` is a C-like enum and ` U ` is an integer type; * enum-cast *
190
- * ` e ` has type ` bool ` or ` char ` and ` U ` is an integer; * prim-int-cast *
191
- * ` e ` has type ` u8 ` and ` U ` is ` char ` ; * u8-char-cast *
192
- * ` e ` has type ` &[T; n] ` and ` U ` is ` *const T ` ; * array-ptr-cast *
193
- * ` e ` is a function pointer type and ` U ` has type ` *T ` ,
194
- while ` T: Sized ` ; * fptr-ptr-cast *
195
- * ` e ` is a function pointer type and ` U ` is an integer; * fptr-addr-cast *
123
+ Here's an exhaustive list of all the true casts. For brevity, we will use ` * `
124
+ to denote either a ` *const ` or ` *mut ` , and ` integer ` to denote any integral primitive:
125
+
126
+ * ` *T as * U` where ` T, U : Sized`
127
+ * ` *T as *U ` TODO: explain unsized situation
128
+ * ` *T as integer `
129
+ * ` integer as *T `
130
+ * ` number as number `
131
+ * ` C-like- enum as integer `
132
+ * ` bool as integer `
133
+ * ` char as integer `
134
+ * ` u8 as char `
135
+ * ` &[T; n] as *const T `
136
+ * ` fn as *T ` where ` T: Sized `
137
+ * ` fn as integer`
196
138
197
139
where ` &.T ` and ` *T ` are references of either mutability,
198
140
and where unsize_kind(` T ` ) is the kind of the unsize info
0 commit comments