aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/resolve.rs
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-02-21 10:04:14 +0000
committerVille Penttinen <[email protected]>2019-02-21 10:25:55 +0000
commit816971ebc9207c5fb5779d448613dd171c27f398 (patch)
treefe49d209a852bb1b4a51eea9d40449dcf2845209 /crates/ra_hir/src/resolve.rs
parentc84561bb624280b84eb2fe6c6b2a6b9fe3f1dbf7 (diff)
Implement basic support for Associated Methods and Constants
This is done in `infer_path_expr`. When `Resolver::resolve_path` returns `PartiallyResolved`, we use the returned `Resolution` together with the given `segment_index` to check if we can find something matching the segment at segment_index in the impls for that particular type.
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r--crates/ra_hir/src/resolve.rs46
1 files changed, 40 insertions, 6 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 91a531801..00b55eae9 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -33,6 +33,32 @@ pub(crate) struct ExprScope {
33} 33}
34 34
35#[derive(Debug, Clone)] 35#[derive(Debug, Clone)]
36pub enum PathResult {
37 /// Path was fully resolved
38 FullyResolved(PerNs<Resolution>),
39 /// Path was partially resolved, first element contains the resolution
40 /// second contains the index in the Path.segments which we were unable to resolve
41 PartiallyResolved(PerNs<Resolution>, usize),
42}
43
44impl PathResult {
45 pub fn segment_index(&self) -> Option<usize> {
46 match self {
47 PathResult::FullyResolved(_) => None,
48 PathResult::PartiallyResolved(_, ref i) => Some(*i),
49 }
50 }
51
52 /// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
53 pub fn into_per_ns(self) -> PerNs<Resolution> {
54 match self {
55 PathResult::FullyResolved(def) => def,
56 PathResult::PartiallyResolved(def, _) => def,
57 }
58 }
59}
60
61#[derive(Debug, Clone)]
36pub(crate) enum Scope { 62pub(crate) enum Scope {
37 /// All the items and imported names of a module 63 /// All the items and imported names of a module
38 ModuleScope(ModuleItemMap), 64 ModuleScope(ModuleItemMap),
@@ -67,18 +93,26 @@ impl Resolver {
67 resolution 93 resolution
68 } 94 }
69 95
70 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> { 96 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
97 use self::PathResult::*;
71 if let Some(name) = path.as_ident() { 98 if let Some(name) = path.as_ident() {
72 self.resolve_name(db, name) 99 FullyResolved(self.resolve_name(db, name))
73 } else if path.is_self() { 100 } else if path.is_self() {
74 self.resolve_name(db, &Name::self_param()) 101 FullyResolved(self.resolve_name(db, &Name::self_param()))
75 } else { 102 } else {
76 let (item_map, module) = match self.module() { 103 let (item_map, module) = match self.module() {
77 Some(m) => m, 104 Some(m) => m,
78 _ => return PerNs::none(), 105 _ => return FullyResolved(PerNs::none()),
79 }; 106 };
80 let module_res = item_map.resolve_path(db, module, path); 107 let (module_res, segment_index) = item_map.resolve_path(db, module, path);
81 module_res.map(Resolution::Def) 108
109 let def = module_res.map(Resolution::Def);
110
111 if let Some(index) = segment_index {
112 PartiallyResolved(def, index)
113 } else {
114 FullyResolved(def)
115 }
82 } 116 }
83 } 117 }
84 118