aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-25 17:02:53 +0000
committerAleksey Kladov <[email protected]>2019-01-25 17:02:53 +0000
commit0044514a4e5fe2484071dc81ae59fc291626c05a (patch)
treefed92822ffe01e0a0e22985df998ddda0d4d4c85
parentdc5ecf446991c65359cf49d52098fcec5f1a1f68 (diff)
remember where fields resolve to during inference
-rw-r--r--crates/ra_hir/src/ty.rs28
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)]
734pub struct InferenceResult { 734pub 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