diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 36189e20d..0e030576d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -107,7 +107,7 @@ impl Default for BindingMode { | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /// The result of type inference: A mapping from expressions and patterns to types. | 109 | /// The result of type inference: A mapping from expressions and patterns to types. |
110 | #[derive(Clone, PartialEq, Eq, Debug)] | 110 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
111 | pub struct InferenceResult { | 111 | pub struct InferenceResult { |
112 | /// For each method call expr, records the function it resolves to. | 112 | /// For each method call expr, records the function it resolves to. |
113 | method_resolutions: FxHashMap<ExprId, Function>, | 113 | method_resolutions: FxHashMap<ExprId, Function>, |
@@ -172,13 +172,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
172 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 172 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
173 | trait_env: Arc<TraitEnvironment>, | 173 | trait_env: Arc<TraitEnvironment>, |
174 | obligations: Vec<Obligation>, | 174 | obligations: Vec<Obligation>, |
175 | method_resolutions: FxHashMap<ExprId, Function>, | 175 | result: InferenceResult, |
176 | field_resolutions: FxHashMap<ExprId, StructField>, | ||
177 | variant_resolutions: FxHashMap<ExprId, VariantDef>, | ||
178 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | ||
179 | type_of_expr: ArenaMap<ExprId, Ty>, | ||
180 | type_of_pat: ArenaMap<PatId, Ty>, | ||
181 | diagnostics: Vec<InferenceDiagnostic>, | ||
182 | /// The return type of the function being inferred. | 176 | /// The return type of the function being inferred. |
183 | return_ty: Ty, | 177 | return_ty: Ty, |
184 | } | 178 | } |
@@ -186,13 +180,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
186 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 180 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
187 | fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self { | 181 | fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self { |
188 | InferenceContext { | 182 | InferenceContext { |
189 | method_resolutions: FxHashMap::default(), | 183 | result: InferenceResult::default(), |
190 | field_resolutions: FxHashMap::default(), | ||
191 | variant_resolutions: FxHashMap::default(), | ||
192 | assoc_resolutions: FxHashMap::default(), | ||
193 | type_of_expr: ArenaMap::default(), | ||
194 | type_of_pat: ArenaMap::default(), | ||
195 | diagnostics: Vec::default(), | ||
196 | var_unification_table: InPlaceUnificationTable::new(), | 184 | var_unification_table: InPlaceUnificationTable::new(), |
197 | obligations: Vec::default(), | 185 | obligations: Vec::default(), |
198 | return_ty: Ty::Unknown, // set in collect_fn_signature | 186 | return_ty: Ty::Unknown, // set in collect_fn_signature |
@@ -205,50 +193,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
205 | 193 | ||
206 | fn resolve_all(mut self) -> InferenceResult { | 194 | fn resolve_all(mut self) -> InferenceResult { |
207 | // FIXME resolve obligations as well (use Guidance if necessary) | 195 | // FIXME resolve obligations as well (use Guidance if necessary) |
196 | let mut result = mem::replace(&mut self.result, InferenceResult::default()); | ||
208 | let mut tv_stack = Vec::new(); | 197 | let mut tv_stack = Vec::new(); |
209 | let mut expr_types = mem::replace(&mut self.type_of_expr, ArenaMap::default()); | 198 | for ty in result.type_of_expr.values_mut() { |
210 | for ty in expr_types.values_mut() { | ||
211 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); | 199 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); |
212 | *ty = resolved; | 200 | *ty = resolved; |
213 | } | 201 | } |
214 | let mut pat_types = mem::replace(&mut self.type_of_pat, ArenaMap::default()); | 202 | for ty in result.type_of_pat.values_mut() { |
215 | for ty in pat_types.values_mut() { | ||
216 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); | 203 | let resolved = self.resolve_ty_completely(&mut tv_stack, mem::replace(ty, Ty::Unknown)); |
217 | *ty = resolved; | 204 | *ty = resolved; |
218 | } | 205 | } |
219 | InferenceResult { | 206 | result |
220 | method_resolutions: self.method_resolutions, | ||
221 | field_resolutions: self.field_resolutions, | ||
222 | variant_resolutions: self.variant_resolutions, | ||
223 | assoc_resolutions: self.assoc_resolutions, | ||
224 | type_of_expr: expr_types, | ||
225 | type_of_pat: pat_types, | ||
226 | diagnostics: self.diagnostics, | ||
227 | } | ||
228 | } | 207 | } |
229 | 208 | ||
230 | fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) { | 209 | fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) { |
231 | self.type_of_expr.insert(expr, ty); | 210 | self.result.type_of_expr.insert(expr, ty); |
232 | } | 211 | } |
233 | 212 | ||
234 | fn write_method_resolution(&mut self, expr: ExprId, func: Function) { | 213 | fn write_method_resolution(&mut self, expr: ExprId, func: Function) { |
235 | self.method_resolutions.insert(expr, func); | 214 | self.result.method_resolutions.insert(expr, func); |
236 | } | 215 | } |
237 | 216 | ||
238 | fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { | 217 | fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { |
239 | self.field_resolutions.insert(expr, field); | 218 | self.result.field_resolutions.insert(expr, field); |
240 | } | 219 | } |
241 | 220 | ||
242 | fn write_variant_resolution(&mut self, expr: ExprId, variant: VariantDef) { | 221 | fn write_variant_resolution(&mut self, expr: ExprId, variant: VariantDef) { |
243 | self.variant_resolutions.insert(expr, variant); | 222 | self.result.variant_resolutions.insert(expr, variant); |
244 | } | 223 | } |
245 | 224 | ||
246 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { | 225 | fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { |
247 | self.assoc_resolutions.insert(id, item); | 226 | self.result.assoc_resolutions.insert(id, item); |
248 | } | 227 | } |
249 | 228 | ||
250 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { | 229 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { |
251 | self.type_of_pat.insert(pat, ty); | 230 | self.result.type_of_pat.insert(pat, ty); |
231 | } | ||
232 | |||
233 | fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) { | ||
234 | self.result.diagnostics.push(diagnostic); | ||
252 | } | 235 | } |
253 | 236 | ||
254 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { | 237 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { |
@@ -565,7 +548,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
565 | Some(ty) | 548 | Some(ty) |
566 | } | 549 | } |
567 | Resolution::LocalBinding(pat) => { | 550 | Resolution::LocalBinding(pat) => { |
568 | let ty = self.type_of_pat.get(pat)?.clone(); | 551 | let ty = self.result.type_of_pat.get(pat)?.clone(); |
569 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 552 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); |
570 | Some(ty) | 553 | Some(ty) |
571 | } | 554 | } |
@@ -1090,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1090 | .and_then(|it| match it.field(self.db, &field.name) { | 1073 | .and_then(|it| match it.field(self.db, &field.name) { |
1091 | Some(field) => Some(field), | 1074 | Some(field) => Some(field), |
1092 | None => { | 1075 | None => { |
1093 | self.diagnostics.push(InferenceDiagnostic::NoSuchField { | 1076 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
1094 | expr: tgt_expr, | 1077 | expr: tgt_expr, |
1095 | field: field_idx, | 1078 | field: field_idx, |
1096 | }); | 1079 | }); |