diff options
author | Aleksey Kladov <[email protected]> | 2019-01-25 17:02:53 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-25 17:02:53 +0000 |
commit | 0044514a4e5fe2484071dc81ae59fc291626c05a (patch) | |
tree | fed92822ffe01e0a0e22985df998ddda0d4d4c85 /crates/ra_hir | |
parent | dc5ecf446991c65359cf49d52098fcec5f1a1f68 (diff) |
remember where fields resolve to during inference
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index c57e222dd..97a876da8 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -732,8 +732,10 @@ pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | |||
732 | /// The result of type inference: A mapping from expressions and patterns to types. | 732 | /// The result of type inference: A mapping from expressions and patterns to types. |
733 | #[derive(Clone, PartialEq, Eq, Debug)] | 733 | #[derive(Clone, PartialEq, Eq, Debug)] |
734 | pub struct InferenceResult { | 734 | pub struct InferenceResult { |
735 | /// For each method call expr, record the function it resolved to. | 735 | /// For each method call expr, records the function it resolves to. |
736 | method_resolutions: FxHashMap<ExprId, Function>, | 736 | method_resolutions: FxHashMap<ExprId, Function>, |
737 | /// For each field access expr, records the field it resolves to. | ||
738 | field_resolutions: FxHashMap<ExprId, StructField>, | ||
737 | type_of_expr: ArenaMap<ExprId, Ty>, | 739 | type_of_expr: ArenaMap<ExprId, Ty>, |
738 | type_of_pat: ArenaMap<PatId, Ty>, | 740 | type_of_pat: ArenaMap<PatId, Ty>, |
739 | } | 741 | } |
@@ -770,6 +772,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
770 | impl_block: Option<ImplBlock>, | 772 | impl_block: Option<ImplBlock>, |
771 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 773 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
772 | method_resolutions: FxHashMap<ExprId, Function>, | 774 | method_resolutions: FxHashMap<ExprId, Function>, |
775 | field_resolutions: FxHashMap<ExprId, StructField>, | ||
773 | type_of_expr: ArenaMap<ExprId, Ty>, | 776 | type_of_expr: ArenaMap<ExprId, Ty>, |
774 | type_of_pat: ArenaMap<PatId, Ty>, | 777 | type_of_pat: ArenaMap<PatId, Ty>, |
775 | /// The return type of the function being inferred. | 778 | /// The return type of the function being inferred. |
@@ -861,6 +864,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
861 | ) -> Self { | 864 | ) -> Self { |
862 | InferenceContext { | 865 | InferenceContext { |
863 | method_resolutions: FxHashMap::default(), | 866 | method_resolutions: FxHashMap::default(), |
867 | field_resolutions: FxHashMap::default(), | ||
864 | type_of_expr: ArenaMap::default(), | 868 | type_of_expr: ArenaMap::default(), |
865 | type_of_pat: ArenaMap::default(), | 869 | type_of_pat: ArenaMap::default(), |
866 | var_unification_table: InPlaceUnificationTable::new(), | 870 | var_unification_table: InPlaceUnificationTable::new(), |
@@ -886,6 +890,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
886 | } | 890 | } |
887 | InferenceResult { | 891 | InferenceResult { |
888 | method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()), | 892 | method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()), |
893 | field_resolutions: mem::replace(&mut self.field_resolutions, Default::default()), | ||
889 | type_of_expr: expr_types, | 894 | type_of_expr: expr_types, |
890 | type_of_pat: pat_types, | 895 | type_of_pat: pat_types, |
891 | } | 896 | } |
@@ -899,6 +904,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
899 | self.method_resolutions.insert(expr, func); | 904 | self.method_resolutions.insert(expr, func); |
900 | } | 905 | } |
901 | 906 | ||
907 | fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { | ||
908 | self.field_resolutions.insert(expr, field); | ||
909 | } | ||
910 | |||
902 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { | 911 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { |
903 | self.type_of_pat.insert(pat, ty); | 912 | self.type_of_pat.insert(pat, ty); |
904 | } | 913 | } |
@@ -1251,9 +1260,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1251 | ty | 1260 | ty |
1252 | } | 1261 | } |
1253 | 1262 | ||
1254 | fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 1263 | fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
1255 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 1264 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
1256 | let ty = match &body[expr] { | 1265 | let ty = match &body[tgt_expr] { |
1257 | Expr::Missing => Ty::Unknown, | 1266 | Expr::Missing => Ty::Unknown, |
1258 | Expr::If { | 1267 | Expr::If { |
1259 | condition, | 1268 | condition, |
@@ -1344,7 +1353,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1344 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); | 1353 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
1345 | let method_ty = match resolved { | 1354 | let method_ty = match resolved { |
1346 | Some(func) => { | 1355 | Some(func) => { |
1347 | self.write_method_resolution(expr, func); | 1356 | self.write_method_resolution(tgt_expr, func); |
1348 | self.db.type_for_def(func.into()) | 1357 | self.db.type_for_def(func.into()) |
1349 | } | 1358 | } |
1350 | None => Ty::Unknown, | 1359 | None => Ty::Unknown, |
@@ -1389,7 +1398,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1389 | 1398 | ||
1390 | expected.ty | 1399 | expected.ty |
1391 | } | 1400 | } |
1392 | Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), | 1401 | Expr::Path(p) => self.infer_path_expr(tgt_expr, p).unwrap_or(Ty::Unknown), |
1393 | Expr::Continue => Ty::Never, | 1402 | Expr::Continue => Ty::Never, |
1394 | Expr::Break { expr } => { | 1403 | Expr::Break { expr } => { |
1395 | if let Some(expr) = expr { | 1404 | if let Some(expr) = expr { |
@@ -1436,9 +1445,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1436 | def_id: AdtDef::Struct(s), | 1445 | def_id: AdtDef::Struct(s), |
1437 | ref substs, | 1446 | ref substs, |
1438 | .. | 1447 | .. |
1439 | } => s | 1448 | } => s.field(self.db, name).map(|field| { |
1440 | .field(self.db, name) | 1449 | self.write_field_resolution(tgt_expr, field); |
1441 | .map(|field| field.ty(self.db).subst(substs)), | 1450 | field.ty(self.db).subst(substs) |
1451 | }), | ||
1442 | _ => None, | 1452 | _ => None, |
1443 | }) | 1453 | }) |
1444 | .unwrap_or(Ty::Unknown); | 1454 | .unwrap_or(Ty::Unknown); |
@@ -1545,7 +1555,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1545 | let ty = self.insert_type_vars_shallow(ty); | 1555 | let ty = self.insert_type_vars_shallow(ty); |
1546 | self.unify(&ty, &expected.ty); | 1556 | self.unify(&ty, &expected.ty); |
1547 | let ty = self.resolve_ty_as_possible(ty); | 1557 | let ty = self.resolve_ty_as_possible(ty); |
1548 | self.write_expr_ty(expr, ty.clone()); | 1558 | self.write_expr_ty(tgt_expr, ty.clone()); |
1549 | ty | 1559 | ty |
1550 | } | 1560 | } |
1551 | 1561 | ||