aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/impl_block.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-01 22:37:59 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-01 22:37:59 +0000
commit4447019f4b5f24728bb7b91b161755ddb373c74c (patch)
treec53ff3531cbbad182e821eb92fa9ad201d2bff0c /crates/ra_hir/src/impl_block.rs
parent2b5c226e86892113bcab478cdf4c9adaf1e7b2f6 (diff)
parentc5852f422ff45adaa21815c1a15e03b067a56a82 (diff)
Merge #693
693: Name resolution refactoring r=matklad a=flodiebold This is still very WIP, but it's becoming quite big and I want to make sure this isn't going in a completely bad direction :sweat_smile:. I'm not really happy with how the path resolution looks, and I'm not sure `PerNs<Resolution>` is the best return type -- there are 'this cannot happen in the (types/values) namespace' cases everywhere. I also want to unify the `resolver` and `nameres` namespaces once I'm done switching everything to `Resolver`. Also, `Resolver` only has a lifetime because it needs to have a reference to the `ItemMap` during import resolution :confused: The differences in the completion snapshots are almost completely just ordering (except it completes `Self` as well now), so I changed it to sort the completions before snapshotting. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/impl_block.rs')
-rw-r--r--crates/ra_hir/src/impl_block.rs69
1 files changed, 49 insertions, 20 deletions
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 36d72b103..738c58fbe 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -7,11 +7,13 @@ use ra_syntax::{
7ast::{self, AstNode}}; 7ast::{self, AstNode}};
8 8
9use crate::{ 9use crate::{
10 Const, Type, 10 Const, Type, Function, HirFileId,
11 Function, HirFileId, 11 HirDatabase, PersistentHirDatabase,
12 PersistentHirDatabase, 12 ModuleDef, Trait, Resolution,
13 type_ref::TypeRef, 13 type_ref::TypeRef,
14 ids::LocationCtx, 14 ids::LocationCtx,
15 resolve::Resolver,
16 ty::Ty,
15}; 17};
16 18
17use crate::code_model_api::{Module, ModuleSource}; 19use crate::code_model_api::{Module, ModuleSource};
@@ -69,7 +71,11 @@ impl ImplBlock {
69 &self.module_impl_blocks.impls[self.impl_id] 71 &self.module_impl_blocks.impls[self.impl_id]
70 } 72 }
71 73
72 pub fn target_trait(&self) -> Option<&TypeRef> { 74 pub fn module(&self) -> Module {
75 self.module_impl_blocks.module.clone()
76 }
77
78 pub fn target_trait_ref(&self) -> Option<&TypeRef> {
73 self.impl_data().target_trait() 79 self.impl_data().target_trait()
74 } 80 }
75 81
@@ -77,9 +83,32 @@ impl ImplBlock {
77 self.impl_data().target_type() 83 self.impl_data().target_type()
78 } 84 }
79 85
86 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
87 Ty::from_hir(db, &self.resolver(db), self.target_type())
88 }
89
90 pub fn target_trait(&self, db: &impl HirDatabase) -> Option<Trait> {
91 if let Some(TypeRef::Path(path)) = self.target_trait_ref() {
92 let resolver = self.resolver(db);
93 if let Some(Resolution::Def(ModuleDef::Trait(tr))) =
94 resolver.resolve_path(db, path).take_types()
95 {
96 return Some(tr);
97 }
98 }
99 None
100 }
101
80 pub fn items(&self) -> &[ImplItem] { 102 pub fn items(&self) -> &[ImplItem] {
81 self.impl_data().items() 103 self.impl_data().items()
82 } 104 }
105
106 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
107 let r = self.module().resolver(db);
108 // TODO: add generics
109 let r = r.push_impl_block_scope(self.clone());
110 r
111 }
83} 112}
84 113
85#[derive(Debug, Clone, PartialEq, Eq)] 114#[derive(Debug, Clone, PartialEq, Eq)]
@@ -162,25 +191,24 @@ impl_arena_id!(ImplId);
162/// we don't need to do the second step again. 191/// we don't need to do the second step again.
163#[derive(Debug, PartialEq, Eq)] 192#[derive(Debug, PartialEq, Eq)]
164pub struct ModuleImplBlocks { 193pub struct ModuleImplBlocks {
194 module: Module,
165 pub(crate) impls: Arena<ImplId, ImplData>, 195 pub(crate) impls: Arena<ImplId, ImplData>,
166 impls_by_def: FxHashMap<ImplItem, ImplId>, 196 impls_by_def: FxHashMap<ImplItem, ImplId>,
167} 197}
168 198
169impl ModuleImplBlocks { 199impl ModuleImplBlocks {
170 fn new() -> Self {
171 ModuleImplBlocks {
172 impls: Arena::default(),
173 impls_by_def: FxHashMap::default(),
174 }
175 }
176
177 fn collect( 200 fn collect(
178 &mut self,
179 db: &impl PersistentHirDatabase, 201 db: &impl PersistentHirDatabase,
180 module: Module, 202 module: Module,
181 source_map: &mut ImplSourceMap, 203 source_map: &mut ImplSourceMap,
182 ) { 204 ) -> Self {
183 let (file_id, module_source) = module.definition_source(db); 205 let mut m = ModuleImplBlocks {
206 module,
207 impls: Arena::default(),
208 impls_by_def: FxHashMap::default(),
209 };
210
211 let (file_id, module_source) = m.module.definition_source(db);
184 let file_id: HirFileId = file_id.into(); 212 let file_id: HirFileId = file_id.into();
185 let node = match &module_source { 213 let node = match &module_source {
186 ModuleSource::SourceFile(node) => node.syntax(), 214 ModuleSource::SourceFile(node) => node.syntax(),
@@ -191,14 +219,16 @@ impl ModuleImplBlocks {
191 }; 219 };
192 220
193 for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { 221 for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) {
194 let impl_block = ImplData::from_ast(db, file_id, module, impl_block_ast); 222 let impl_block = ImplData::from_ast(db, file_id, m.module, impl_block_ast);
195 let id = self.impls.alloc(impl_block); 223 let id = m.impls.alloc(impl_block);
196 for &impl_item in &self.impls[id].items { 224 for &impl_item in &m.impls[id].items {
197 self.impls_by_def.insert(impl_item, id); 225 m.impls_by_def.insert(impl_item, id);
198 } 226 }
199 227
200 source_map.insert(id, impl_block_ast); 228 source_map.insert(id, impl_block_ast);
201 } 229 }
230
231 m
202 } 232 }
203} 233}
204 234
@@ -208,8 +238,7 @@ pub(crate) fn impls_in_module_with_source_map_query(
208) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { 238) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) {
209 let mut source_map = ImplSourceMap::default(); 239 let mut source_map = ImplSourceMap::default();
210 240
211 let mut result = ModuleImplBlocks::new(); 241 let result = ModuleImplBlocks::collect(db, module, &mut source_map);
212 result.collect(db, module, &mut source_map);
213 242
214 (Arc::new(result), Arc::new(source_map)) 243 (Arc::new(result), Arc::new(source_map))
215} 244}