16
16
use std:: ops:: Index ;
17
17
use std:: sync:: Arc ;
18
18
19
- use chalk_ir:: { cast:: Cast , DebruijnIndex , Mutability } ;
19
+ use chalk_ir:: { cast:: Cast , DebruijnIndex , Mutability , Safety } ;
20
20
use hir_def:: {
21
21
body:: Body ,
22
22
data:: { ConstData , FunctionData , StaticData } ,
@@ -103,12 +103,20 @@ impl Default for BindingMode {
103
103
}
104
104
105
105
#[ derive( Debug ) ]
106
- pub ( crate ) struct InferOk {
106
+ pub ( crate ) struct InferOk < T > {
107
+ value : T ,
107
108
goals : Vec < InEnvironment < Goal > > ,
108
109
}
110
+
111
+ impl < T > InferOk < T > {
112
+ fn map < U > ( self , f : impl FnOnce ( T ) -> U ) -> InferOk < U > {
113
+ InferOk { value : f ( self . value ) , goals : self . goals }
114
+ }
115
+ }
116
+
109
117
#[ derive( Debug ) ]
110
118
pub ( crate ) struct TypeError ;
111
- pub ( crate ) type InferResult = Result < InferOk , TypeError > ;
119
+ pub ( crate ) type InferResult < T > = Result < InferOk < T > , TypeError > ;
112
120
113
121
#[ derive( Debug , PartialEq , Eq , Clone ) ]
114
122
pub enum InferenceDiagnostic {
@@ -134,6 +142,78 @@ impl Default for InternedStandardTypes {
134
142
}
135
143
}
136
144
145
+ #[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
146
+ pub struct Adjustment {
147
+ pub kind : Adjust ,
148
+ pub target : Ty ,
149
+ }
150
+
151
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
152
+ pub enum Adjust {
153
+ /// Go from ! to any type.
154
+ NeverToAny ,
155
+
156
+ /// Dereference once, producing a place.
157
+ Deref ( Option < OverloadedDeref > ) ,
158
+
159
+ /// Take the address and produce either a `&` or `*` pointer.
160
+ Borrow ( AutoBorrow ) ,
161
+
162
+ Pointer ( PointerCast ) ,
163
+ }
164
+
165
+ // impl fmt::Display for Adjust {
166
+ // fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167
+ // match self {
168
+ // Adjust::NeverToAny => write!(f, "NeverToAny"),
169
+ // Adjust::Deref(_) => write!(f, "Deref"), // FIXME
170
+ // Adjust::Borrow(AutoBorrow::Ref(mt)) => write!(f, "BorrowRef{:?}", mt),
171
+ // Adjust::Borrow(AutoBorrow::RawPtr(mt)) => write!(f, "BorrowRawPtr{:?}", mt),
172
+ // Adjust::Pointer(cast) => write!(f, "PtrCast{:?}", cast),
173
+ // }
174
+ // }
175
+ // }
176
+
177
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
178
+ pub struct OverloadedDeref ( Mutability ) ;
179
+
180
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
181
+ pub enum AutoBorrow {
182
+ Ref ( Mutability ) ,
183
+ RawPtr ( Mutability ) ,
184
+ }
185
+
186
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
187
+ pub enum PointerCast {
188
+ /// Go from a fn-item type to a fn-pointer type.
189
+ ReifyFnPointer ,
190
+
191
+ /// Go from a safe fn pointer to an unsafe fn pointer.
192
+ UnsafeFnPointer ,
193
+
194
+ /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
195
+ /// It cannot convert a closure that requires unsafe.
196
+ ClosureFnPointer ( Safety ) ,
197
+
198
+ /// Go from a mut raw pointer to a const raw pointer.
199
+ MutToConstPointer ,
200
+
201
+ /// Go from `*const [T; N]` to `*const T`
202
+ ArrayToPointer ,
203
+
204
+ /// Unsize a pointer/reference value, e.g., `&[T; n]` to
205
+ /// `&[T]`. Note that the source could be a thin or fat pointer.
206
+ /// This will do things like convert thin pointers to fat
207
+ /// pointers, or convert structs containing thin pointers to
208
+ /// structs containing fat pointers, or convert between fat
209
+ /// pointers. We don't store the details of how the transform is
210
+ /// done (in fact, we don't know that, because it might depend on
211
+ /// the precise type parameters). We just store the target
212
+ /// type. Codegen backends and miri figure out what has to be done
213
+ /// based on the precise source/target type at hand.
214
+ Unsize ,
215
+ }
216
+
137
217
/// The result of type inference: A mapping from expressions and patterns to types.
138
218
#[ derive( Clone , PartialEq , Eq , Debug , Default ) ]
139
219
pub struct InferenceResult {
@@ -156,7 +236,8 @@ pub struct InferenceResult {
156
236
/// Interned Unknown to return references to.
157
237
standard_types : InternedStandardTypes ,
158
238
/// Stores the types which were implicitly dereferenced in pattern binding modes.
159
- pub pat_adjustments : FxHashMap < PatId , Vec < Ty > > ,
239
+ pub pat_adjustments : FxHashMap < PatId , Vec < Adjustment > > ,
240
+ pub expr_adjustments : FxHashMap < ExprId , Vec < Adjustment > > ,
160
241
}
161
242
162
243
impl InferenceResult {
@@ -303,6 +384,10 @@ impl<'a> InferenceContext<'a> {
303
384
self . result . type_of_expr . insert ( expr, ty) ;
304
385
}
305
386
387
+ fn write_expr_adj ( & mut self , expr : ExprId , adjustments : Vec < Adjustment > ) {
388
+ self . result . expr_adjustments . insert ( expr, adjustments) ;
389
+ }
390
+
306
391
fn write_method_resolution ( & mut self , expr : ExprId , func : FunctionId , subst : Substitution ) {
307
392
self . result . method_resolutions . insert ( expr, ( func, subst) ) ;
308
393
}
0 commit comments