aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2018-12-29 21:59:18 +0000
committerFlorian Diebold <[email protected]>2019-01-04 18:12:29 +0000
commitd4db61b9a151a2a46c4067e61b0a4b1a9e3c73ec (patch)
tree67eb2ae28096c97ddc57840db39191ba31a1edcd /crates
parent111126ed3c4f6358e0c833f80226e5192778f749 (diff)
Resolve the self parameter during type inference
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/path.rs5
-rw-r--r--crates/ra_hir/src/ty.rs14
-rw-r--r--crates/ra_hir/src/ty/tests/data/0007_self.txt4
3 files changed, 19 insertions, 4 deletions
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 93f7203fe..9fdfa0d13 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -70,6 +70,11 @@ impl Path {
70 self.kind == PathKind::Plain && self.segments.len() == 1 70 self.kind == PathKind::Plain && self.segments.len() == 1
71 } 71 }
72 72
73 /// `true` if this path is just a standalone `self`
74 pub fn is_self(&self) -> bool {
75 self.kind == PathKind::Self_ && self.segments.len() == 0
76 }
77
73 /// If this path is a single identifier, like `foo`, return its name. 78 /// If this path is a single identifier, like `foo`, return its name.
74 pub fn as_ident(&self) -> Option<&Name> { 79 pub fn as_ident(&self) -> Option<&Name> {
75 if self.kind != PathKind::Plain || self.segments.len() > 1 { 80 if self.kind != PathKind::Plain || self.segments.len() > 1 {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index c762ec606..5ea62a14c 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -496,6 +496,8 @@ impl InferenceResult {
496struct InferenceContext<'a, D: HirDatabase> { 496struct InferenceContext<'a, D: HirDatabase> {
497 db: &'a D, 497 db: &'a D,
498 scopes: Arc<FnScopes>, 498 scopes: Arc<FnScopes>,
499 /// The self param for the current method, if it exists.
500 self_param: Option<LocalSyntaxPtr>,
499 module: Module, 501 module: Module,
500 var_unification_table: InPlaceUnificationTable<TypeVarId>, 502 var_unification_table: InPlaceUnificationTable<TypeVarId>,
501 type_of: FxHashMap<LocalSyntaxPtr, Ty>, 503 type_of: FxHashMap<LocalSyntaxPtr, Ty>,
@@ -506,6 +508,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
506 InferenceContext { 508 InferenceContext {
507 type_of: FxHashMap::default(), 509 type_of: FxHashMap::default(),
508 var_unification_table: InPlaceUnificationTable::new(), 510 var_unification_table: InPlaceUnificationTable::new(),
511 self_param: None, // set during parameter typing
509 db, 512 db,
510 scopes, 513 scopes,
511 module, 514 module,
@@ -628,6 +631,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
628 let ty = self.resolve_ty_as_possible(ty.clone()); 631 let ty = self.resolve_ty_as_possible(ty.clone());
629 return Ok(Some(ty)); 632 return Ok(Some(ty));
630 }; 633 };
634 } else if path.is_self() {
635 // resolve `self` param
636 let self_param = ctry!(self.self_param);
637 let ty = ctry!(self.type_of.get(&self_param));
638 let ty = self.resolve_ty_as_possible(ty.clone());
639 return Ok(Some(ty));
631 }; 640 };
632 641
633 // resolve in module 642 // resolve in module
@@ -940,8 +949,9 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceRe
940 ctx.new_type_var() 949 ctx.new_type_var()
941 }; 950 };
942 if let Some(self_kw) = self_param.self_kw() { 951 if let Some(self_kw) = self_param.self_kw() {
943 ctx.type_of 952 let self_param = LocalSyntaxPtr::new(self_kw.syntax());
944 .insert(LocalSyntaxPtr::new(self_kw.syntax()), self_type); 953 ctx.self_param = Some(self_param);
954 ctx.type_of.insert(self_param, self_type);
945 } 955 }
946 } 956 }
947 for param in param_list.params() { 957 for param in param_list.params() {
diff --git a/crates/ra_hir/src/ty/tests/data/0007_self.txt b/crates/ra_hir/src/ty/tests/data/0007_self.txt
index 3d3c8b260..0dd61da55 100644
--- a/crates/ra_hir/src/ty/tests/data/0007_self.txt
+++ b/crates/ra_hir/src/ty/tests/data/0007_self.txt
@@ -1,6 +1,6 @@
1[50; 54) 'self': [unknown] 1[50; 54) 'self': &S
2[34; 38) 'self': &S 2[34; 38) 'self': &S
3[40; 61) '{ ... }': () 3[40; 61) '{ ... }': ()
4[88; 109) '{ ... }': () 4[88; 109) '{ ... }': ()
5[98; 102) 'self': [unknown] 5[98; 102) 'self': &[unknown]
6[75; 79) 'self': &[unknown] 6[75; 79) 'self': &[unknown]