aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model_impl
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-08 15:01:19 +0000
committerMarcus Klaas de Vries <[email protected]>2019-01-10 13:32:56 +0000
commit978de5cf8bfd2ff82696fc8d5369b41e147431c3 (patch)
tree27a25a5f2fb20a4afffed97cbb5b678b251d254b /crates/ra_hir/src/code_model_impl
parentaca14c591fea40b2f803bbf5f02c1571732348fb (diff)
Implement type inference for enum variants
Diffstat (limited to 'crates/ra_hir/src/code_model_impl')
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs38
1 files changed, 36 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 1cb408cff..d7d62e863 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -13,6 +13,7 @@ impl Module {
13 pub(crate) fn new(def_id: DefId) -> Self { 13 pub(crate) fn new(def_id: DefId) -> Self {
14 crate::code_model_api::Module { def_id } 14 crate::code_model_api::Module { def_id }
15 } 15 }
16
16 pub(crate) fn from_module_id( 17 pub(crate) fn from_module_id(
17 db: &impl HirDatabase, 18 db: &impl HirDatabase,
18 source_root_id: SourceRootId, 19 source_root_id: SourceRootId,
@@ -85,6 +86,7 @@ impl Module {
85 let module_id = loc.module_id.crate_root(&module_tree); 86 let module_id = loc.module_id.crate_root(&module_tree);
86 Module::from_module_id(db, loc.source_root_id, module_id) 87 Module::from_module_id(db, loc.source_root_id, module_id)
87 } 88 }
89
88 /// Finds a child module with the specified name. 90 /// Finds a child module with the specified name.
89 pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { 91 pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> {
90 let loc = self.def_id.loc(db); 92 let loc = self.def_id.loc(db);
@@ -92,12 +94,14 @@ impl Module {
92 let child_id = ctry!(loc.module_id.child(&module_tree, name)); 94 let child_id = ctry!(loc.module_id.child(&module_tree, name));
93 Module::from_module_id(db, loc.source_root_id, child_id).map(Some) 95 Module::from_module_id(db, loc.source_root_id, child_id).map(Some)
94 } 96 }
97
95 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { 98 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> {
96 let loc = self.def_id.loc(db); 99 let loc = self.def_id.loc(db);
97 let module_tree = db.module_tree(loc.source_root_id)?; 100 let module_tree = db.module_tree(loc.source_root_id)?;
98 let parent_id = ctry!(loc.module_id.parent(&module_tree)); 101 let parent_id = ctry!(loc.module_id.parent(&module_tree));
99 Module::from_module_id(db, loc.source_root_id, parent_id).map(Some) 102 Module::from_module_id(db, loc.source_root_id, parent_id).map(Some)
100 } 103 }
104
101 /// Returns a `ModuleScope`: a set of items, visible in this module. 105 /// Returns a `ModuleScope`: a set of items, visible in this module.
102 pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { 106 pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> {
103 let loc = self.def_id.loc(db); 107 let loc = self.def_id.loc(db);
@@ -105,6 +109,7 @@ impl Module {
105 let res = item_map.per_module[&loc.module_id].clone(); 109 let res = item_map.per_module[&loc.module_id].clone();
106 Ok(res) 110 Ok(res)
107 } 111 }
112
108 pub fn resolve_path_impl( 113 pub fn resolve_path_impl(
109 &self, 114 &self,
110 db: &impl HirDatabase, 115 db: &impl HirDatabase,
@@ -126,7 +131,7 @@ impl Module {
126 ); 131 );
127 132
128 let segments = &path.segments; 133 let segments = &path.segments;
129 for name in segments.iter() { 134 for (idx, name) in segments.iter().enumerate() {
130 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { 135 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() {
131 r 136 r
132 } else { 137 } else {
@@ -134,7 +139,35 @@ impl Module {
134 }; 139 };
135 let module = match curr.resolve(db)? { 140 let module = match curr.resolve(db)? {
136 Def::Module(it) => it, 141 Def::Module(it) => it,
137 // TODO here would be the place to handle enum variants... 142 Def::Enum(e) => {
143 if segments.len() == idx + 1 {
144 // enum variant
145 let matching_variant = e.variants(db)?.map(|variants| {
146 variants
147 .into_iter()
148 // FIXME: replace by match lol
149 .find(|variant| {
150 variant
151 .name(db)
152 .map(|o| o.map(|ref n| n == name))
153 .unwrap_or(Some(false))
154 .unwrap_or(false)
155 })
156 });
157
158 if let Some(Some(variant)) = matching_variant {
159 return Ok(PerNs::both(variant.def_id(), e.def_id()));
160 } else {
161 return Ok(PerNs::none());
162 }
163 } else if segments.len() == idx {
164 // enum
165 return Ok(PerNs::types(e.def_id()));
166 } else {
167 // malformed enum?
168 return Ok(PerNs::none());
169 }
170 }
138 _ => return Ok(PerNs::none()), 171 _ => return Ok(PerNs::none()),
139 }; 172 };
140 let scope = module.scope(db)?; 173 let scope = module.scope(db)?;
@@ -146,6 +179,7 @@ impl Module {
146 } 179 }
147 Ok(curr_per_ns) 180 Ok(curr_per_ns)
148 } 181 }
182
149 pub fn problems_impl( 183 pub fn problems_impl(
150 &self, 184 &self,
151 db: &impl HirDatabase, 185 db: &impl HirDatabase,