diff options
author | Florian Diebold <[email protected]> | 2018-12-29 21:59:18 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-01-04 18:12:29 +0000 |
commit | d4db61b9a151a2a46c4067e61b0a4b1a9e3c73ec (patch) | |
tree | 67eb2ae28096c97ddc57840db39191ba31a1edcd /crates/ra_hir/src | |
parent | 111126ed3c4f6358e0c833f80226e5192778f749 (diff) |
Resolve the self parameter during type inference
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/path.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/0007_self.txt | 4 |
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 { | |||
496 | struct InferenceContext<'a, D: HirDatabase> { | 496 | struct 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] |