aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_api.rs11
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs17
-rw-r--r--crates/ra_hir/src/db.rs23
-rw-r--r--crates/ra_hir/src/nameres.rs44
-rw-r--r--crates/ra_hir/src/nameres/lower.rs213
-rw-r--r--crates/ra_hir/src/path.rs25
-rw-r--r--crates/ra_hir/src/query_definitions.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs11
-rw-r--r--crates/ra_ide_api/src/db.rs3
9 files changed, 284 insertions, 65 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 0cf7deac9..865e5e809 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -7,7 +7,7 @@ use ra_syntax::{ast, TreeArc, SyntaxNode};
7use crate::{ 7use crate::{
8 Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId, 8 Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId,
9 type_ref::TypeRef, 9 type_ref::TypeRef,
10 nameres::ModuleScope, 10 nameres::{ModuleScope, lower::LoweredImport},
11 db::HirDatabase, 11 db::HirDatabase,
12 expr::BodySyntaxMapping, 12 expr::BodySyntaxMapping,
13 ty::InferenceResult, 13 ty::InferenceResult,
@@ -96,6 +96,15 @@ impl Module {
96 self.declaration_source_impl(db) 96 self.declaration_source_impl(db)
97 } 97 }
98 98
99 /// Returns the syntax of the last path segment corresponding to this import
100 pub fn import_source(
101 &self,
102 db: &impl HirDatabase,
103 import: LoweredImport,
104 ) -> TreeArc<ast::PathSegment> {
105 self.import_source_impl(db, import)
106 }
107
99 /// Returns the crate this module is part of. 108 /// Returns the crate this module is part of.
100 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { 109 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
101 self.krate_impl(db) 110 self.krate_impl(db)
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index a5c032d69..f110548c6 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -5,7 +5,7 @@ use crate::{
5 Module, ModuleSource, Problem, 5 Module, ModuleSource, Problem,
6 Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, 6 Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 nameres::ModuleScope, 8 nameres::{ModuleScope, lower::LoweredImport},
9 db::HirDatabase, 9 db::HirDatabase,
10}; 10};
11 11
@@ -37,7 +37,7 @@ impl Module {
37 Some(link.name(&module_tree).clone()) 37 Some(link.name(&module_tree).clone())
38 } 38 }
39 39
40 pub fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { 40 pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) {
41 let loc = self.def_id.loc(db); 41 let loc = self.def_id.loc(db);
42 let file_id = loc.source_item_id.file_id.as_original_file(); 42 let file_id = loc.source_item_id.file_id.as_original_file();
43 let syntax_node = db.file_item(loc.source_item_id); 43 let syntax_node = db.file_item(loc.source_item_id);
@@ -50,7 +50,7 @@ impl Module {
50 (file_id, module_source) 50 (file_id, module_source)
51 } 51 }
52 52
53 pub fn declaration_source_impl( 53 pub(crate) fn declaration_source_impl(
54 &self, 54 &self,
55 db: &impl HirDatabase, 55 db: &impl HirDatabase,
56 ) -> Option<(FileId, TreeArc<ast::Module>)> { 56 ) -> Option<(FileId, TreeArc<ast::Module>)> {
@@ -66,6 +66,17 @@ impl Module {
66 Some((file_id, src)) 66 Some((file_id, src))
67 } 67 }
68 68
69 pub(crate) fn import_source_impl(
70 &self,
71 db: &impl HirDatabase,
72 import: LoweredImport,
73 ) -> TreeArc<ast::PathSegment> {
74 let loc = self.def_id.loc(db);
75 let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id);
76 let (_, source) = self.definition_source(db);
77 source_map.get(&source, import)
78 }
79
69 pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> { 80 pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> {
70 let root = self.crate_root(db); 81 let root = self.crate_root(db);
71 let loc = root.def_id.loc(db); 82 let loc = root.def_id.loc(db);
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 4a3e0fed2..ccc53c454 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -10,7 +10,7 @@ use crate::{
10 FnSignature, FnScopes, 10 FnSignature, FnScopes,
11 macros::MacroExpansion, 11 macros::MacroExpansion,
12 module_tree::{ModuleId, ModuleTree}, 12 module_tree::{ModuleId, ModuleTree},
13 nameres::{ItemMap, lower::InputModuleItems}, 13 nameres::{ItemMap, lower::{InputModuleItems, LoweredModule, ImportSourceMap}},
14 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks}, 14 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks},
15 adt::{StructData, EnumData, EnumVariantData}, 15 adt::{StructData, EnumData, EnumVariantData},
16 impl_block::ModuleImplBlocks, 16 impl_block::ModuleImplBlocks,
@@ -65,6 +65,27 @@ pub trait HirDatabase:
65 module_id: ModuleId, 65 module_id: ModuleId,
66 ) -> Arc<InputModuleItems>; 66 ) -> Arc<InputModuleItems>;
67 67
68 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
69 fn lower_module(
70 &self,
71 source_root_id: SourceRootId,
72 module_id: ModuleId,
73 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
74
75 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)]
76 fn lower_module_module(
77 &self,
78 source_root_id: SourceRootId,
79 module_id: ModuleId,
80 ) -> Arc<LoweredModule>;
81
82 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
83 fn lower_module_source_map(
84 &self,
85 source_root_id: SourceRootId,
86 module_id: ModuleId,
87 ) -> Arc<ImportSourceMap>;
88
68 #[salsa::invoke(query_definitions::item_map)] 89 #[salsa::invoke(query_definitions::item_map)]
69 fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>; 90 fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>;
70 91
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index aea95e08c..ab0a9041d 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -60,7 +60,7 @@ pub struct Resolution {
60 /// None for unresolved 60 /// None for unresolved
61 pub def_id: PerNs<DefId>, 61 pub def_id: PerNs<DefId>,
62 /// ident by whitch this is imported into local scope. 62 /// ident by whitch this is imported into local scope.
63 pub import: Option<NamedImport>, 63 pub import: Option<LoweredImport>,
64} 64}
65 65
66#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 66#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -151,10 +151,10 @@ impl<T> PerNs<T> {
151 151
152pub(crate) struct Resolver<'a, DB> { 152pub(crate) struct Resolver<'a, DB> {
153 db: &'a DB, 153 db: &'a DB,
154 input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, 154 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
155 source_root: SourceRootId, 155 source_root: SourceRootId,
156 module_tree: Arc<ModuleTree>, 156 module_tree: Arc<ModuleTree>,
157 processed_imports: FxHashSet<(ModuleId, usize)>, 157 processed_imports: FxHashSet<(ModuleId, LoweredImport)>,
158 result: ItemMap, 158 result: ItemMap,
159} 159}
160 160
@@ -164,7 +164,7 @@ where
164{ 164{
165 pub(crate) fn new( 165 pub(crate) fn new(
166 db: &'a DB, 166 db: &'a DB,
167 input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, 167 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
168 source_root: SourceRootId, 168 source_root: SourceRootId,
169 module_tree: Arc<ModuleTree>, 169 module_tree: Arc<ModuleTree>,
170 ) -> Resolver<'a, DB> { 170 ) -> Resolver<'a, DB> {
@@ -197,7 +197,7 @@ where
197 self.result 197 self.result
198 } 198 }
199 199
200 fn populate_module(&mut self, module_id: ModuleId, input: Arc<InputModuleItems>) { 200 fn populate_module(&mut self, module_id: ModuleId, input: Arc<LoweredModule>) {
201 let mut module_items = ModuleScope::default(); 201 let mut module_items = ModuleScope::default();
202 202
203 // Populate extern crates prelude 203 // Populate extern crates prelude
@@ -220,14 +220,14 @@ where
220 } 220 }
221 }; 221 };
222 } 222 }
223 for import in input.imports.iter() { 223 for (import_id, import_data) in input.imports.iter() {
224 if let Some(name) = import.path.segments.iter().last() { 224 if let Some(name) = import_data.path.segments.iter().last() {
225 if let ImportKind::Named(import) = import.kind { 225 if !import_data.is_glob {
226 module_items.items.insert( 226 module_items.items.insert(
227 name.clone(), 227 name.clone(),
228 Resolution { 228 Resolution {
229 def_id: PerNs::none(), 229 def_id: PerNs::none(),
230 import: Some(import), 230 import: Some(import_id),
231 }, 231 },
232 ); 232 );
233 } 233 }
@@ -281,23 +281,27 @@ where
281 } 281 }
282 282
283 fn resolve_imports(&mut self, module_id: ModuleId) { 283 fn resolve_imports(&mut self, module_id: ModuleId) {
284 for (i, import) in self.input[&module_id].imports.iter().enumerate() { 284 for (import_id, import_data) in self.input[&module_id].imports.iter() {
285 if self.processed_imports.contains(&(module_id, i)) { 285 if self.processed_imports.contains(&(module_id, import_id)) {
286 // already done 286 // already done
287 continue; 287 continue;
288 } 288 }
289 if self.resolve_import(module_id, import) { 289 if self.resolve_import(module_id, import_id, import_data) {
290 log::debug!("import {:?} resolved (or definite error)", import); 290 log::debug!("import {:?} resolved (or definite error)", import_id);
291 self.processed_imports.insert((module_id, i)); 291 self.processed_imports.insert((module_id, import_id));
292 } 292 }
293 } 293 }
294 } 294 }
295 295
296 fn resolve_import(&mut self, module_id: ModuleId, import: &Import) -> bool { 296 fn resolve_import(
297 &mut self,
298 module_id: ModuleId,
299 import_id: LoweredImport,
300 import: &ImportData,
301 ) -> bool {
297 log::debug!("resolving import: {:?}", import); 302 log::debug!("resolving import: {:?}", import);
298 let ptr = match import.kind { 303 if import.is_glob {
299 ImportKind::Glob => return false, 304 return false;
300 ImportKind::Named(ptr) => ptr,
301 }; 305 };
302 306
303 let mut curr: ModuleId = match import.path.kind { 307 let mut curr: ModuleId = match import.path.kind {
@@ -358,7 +362,7 @@ where
358 self.update(module_id, |items| { 362 self.update(module_id, |items| {
359 let res = Resolution { 363 let res = Resolution {
360 def_id, 364 def_id,
361 import: Some(ptr), 365 import: Some(import_id),
362 }; 366 };
363 items.items.insert(name.clone(), res); 367 items.items.insert(name.clone(), res);
364 }); 368 });
@@ -394,7 +398,7 @@ where
394 self.update(module_id, |items| { 398 self.update(module_id, |items| {
395 let res = Resolution { 399 let res = Resolution {
396 def_id, 400 def_id,
397 import: Some(ptr), 401 import: Some(import_id),
398 }; 402 };
399 items.items.insert(name.clone(), res); 403 items.items.insert(name.clone(), res);
400 }) 404 })
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index 35bdbafbf..6bca14444 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -1,10 +1,11 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 TextRange, SyntaxKind, AstNode, 4 TextRange, SyntaxKind, AstNode, SourceFile, TreeArc,
5 ast::{self, ModuleItemOwner}, 5 ast::{self, ModuleItemOwner},
6}; 6};
7use ra_db::{FileId, SourceRootId}; 7use ra_db::{SourceRootId, LocalSyntaxPtr};
8use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
8 9
9use crate::{ 10use crate::{
10 SourceItemId, SourceFileItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, 11 SourceItemId, SourceFileItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems,
@@ -139,12 +140,12 @@ impl InputModuleItems {
139 fn add_use_item(&mut self, file_items: &SourceFileItems, item: &ast::UseItem) { 140 fn add_use_item(&mut self, file_items: &SourceFileItems, item: &ast::UseItem) {
140 let file_item_id = file_items.id_of_unchecked(item.syntax()); 141 let file_item_id = file_items.id_of_unchecked(item.syntax());
141 let start_offset = item.syntax().range().start(); 142 let start_offset = item.syntax().range().start();
142 Path::expand_use_item(item, |path, range| { 143 Path::expand_use_item(item, |path, segment| {
143 let kind = match range { 144 let kind = match segment {
144 None => ImportKind::Glob, 145 None => ImportKind::Glob,
145 Some(range) => ImportKind::Named(NamedImport { 146 Some(segment) => ImportKind::Named(NamedImport {
146 file_item_id, 147 file_item_id,
147 relative_range: range - start_offset, 148 relative_range: segment.syntax().range() - start_offset,
148 }), 149 }),
149 }; 150 };
150 self.imports.push(Import { kind, path }) 151 self.imports.push(Import { kind, path })
@@ -199,22 +200,194 @@ pub struct NamedImport {
199 pub relative_range: TextRange, 200 pub relative_range: TextRange,
200} 201}
201 202
202impl NamedImport {
203 // FIXME: this is only here for one use-case in completion. Seems like a
204 // pretty gross special case.
205 pub fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange {
206 let source_item_id = SourceItemId {
207 file_id: file_id.into(),
208 item_id: Some(self.file_item_id),
209 };
210 let syntax = db.file_item(source_item_id);
211 let offset = syntax.range().start();
212 self.relative_range + offset
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq)] 203#[derive(Debug, Clone, PartialEq, Eq)]
217pub(super) enum ImportKind { 204pub(super) enum ImportKind {
218 Glob, 205 Glob,
219 Named(NamedImport), 206 Named(NamedImport),
220} 207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
210pub struct LoweredImport(RawId);
211impl_arena_id!(LoweredImport);
212
213#[derive(Debug, PartialEq, Eq)]
214pub(super) struct ImportData {
215 pub(super) path: Path,
216 pub(super) is_glob: bool,
217}
218
219#[derive(Debug, Default, PartialEq, Eq)]
220pub struct LoweredModule {
221 pub(super) items: Vec<ModuleItem>,
222 pub(super) imports: Arena<LoweredImport, ImportData>,
223}
224
225#[derive(Debug, Default, PartialEq, Eq)]
226pub struct ImportSourceMap {
227 map: ArenaMap<LoweredImport, LocalSyntaxPtr>,
228}
229
230impl ImportSourceMap {
231 fn insert(&mut self, import: LoweredImport, segment: &ast::PathSegment) {
232 self.map
233 .insert(import, LocalSyntaxPtr::new(segment.syntax()))
234 }
235
236 pub fn get(&self, source: &ModuleSource, import: LoweredImport) -> TreeArc<ast::PathSegment> {
237 let file = match source {
238 ModuleSource::SourceFile(file) => &*file,
239 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
240 };
241
242 ast::PathSegment::cast(&self.map[import].resolve(file))
243 .unwrap()
244 .to_owned()
245 }
246}
247
248impl LoweredModule {
249 pub(crate) fn lower_module_module_query(
250 db: &impl HirDatabase,
251 source_root_id: SourceRootId,
252 module_id: ModuleId,
253 ) -> Arc<LoweredModule> {
254 db.lower_module(source_root_id, module_id).0
255 }
256
257 pub(crate) fn lower_module_source_map_query(
258 db: &impl HirDatabase,
259 source_root_id: SourceRootId,
260 module_id: ModuleId,
261 ) -> Arc<ImportSourceMap> {
262 db.lower_module(source_root_id, module_id).1
263 }
264
265 pub(crate) fn lower_module_query(
266 db: &impl HirDatabase,
267 source_root_id: SourceRootId,
268 module_id: ModuleId,
269 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
270 let module_tree = db.module_tree(source_root_id);
271 let source = module_id.source(&module_tree);
272 let file_id = source.file_id;
273 let source = ModuleSource::from_source_item_id(db, source);
274 let mut source_map = ImportSourceMap::default();
275 let mut res = LoweredModule::default();
276 match source {
277 ModuleSource::SourceFile(it) => res.fill(
278 &mut source_map,
279 db,
280 source_root_id,
281 module_id,
282 file_id,
283 &mut it.items_with_macros(),
284 ),
285 ModuleSource::Module(it) => {
286 if let Some(item_list) = it.item_list() {
287 res.fill(
288 &mut source_map,
289 db,
290 source_root_id,
291 module_id,
292 file_id,
293 &mut item_list.items_with_macros(),
294 )
295 }
296 }
297 };
298 (Arc::new(res), Arc::new(source_map))
299 }
300
301 fn fill(
302 &mut self,
303 source_map: &mut ImportSourceMap,
304 db: &impl HirDatabase,
305 source_root_id: SourceRootId,
306 module_id: ModuleId,
307 file_id: HirFileId,
308 items: &mut Iterator<Item = ast::ItemOrMacro>,
309 ) {
310 let file_items = db.file_items(file_id);
311
312 for item in items {
313 match item {
314 ast::ItemOrMacro::Item(it) => {
315 self.add_item(source_map, file_id, &file_items, it);
316 }
317 ast::ItemOrMacro::Macro(macro_call) => {
318 let item_id = file_items.id_of_unchecked(macro_call.syntax());
319 let loc = MacroCallLoc {
320 source_root_id,
321 module_id,
322 source_item_id: SourceItemId {
323 file_id,
324 item_id: Some(item_id),
325 },
326 };
327 let id = loc.id(db);
328 let file_id = HirFileId::from(id);
329 let file_items = db.file_items(file_id);
330 //FIXME: expand recursively
331 for item in db.hir_source_file(file_id).items() {
332 self.add_item(source_map, file_id, &file_items, item);
333 }
334 }
335 }
336 }
337 }
338
339 fn add_item(
340 &mut self,
341 source_map: &mut ImportSourceMap,
342 file_id: HirFileId,
343 file_items: &SourceFileItems,
344 item: &ast::ModuleItem,
345 ) -> Option<()> {
346 match item.kind() {
347 ast::ModuleItemKind::StructDef(it) => {
348 self.items.push(ModuleItem::new(file_id, file_items, it)?)
349 }
350 ast::ModuleItemKind::EnumDef(it) => {
351 self.items.push(ModuleItem::new(file_id, file_items, it)?)
352 }
353 ast::ModuleItemKind::FnDef(it) => {
354 self.items.push(ModuleItem::new(file_id, file_items, it)?)
355 }
356 ast::ModuleItemKind::TraitDef(it) => {
357 self.items.push(ModuleItem::new(file_id, file_items, it)?)
358 }
359 ast::ModuleItemKind::TypeDef(it) => {
360 self.items.push(ModuleItem::new(file_id, file_items, it)?)
361 }
362 ast::ModuleItemKind::ImplBlock(_) => {
363 // impls don't define items
364 }
365 ast::ModuleItemKind::UseItem(it) => self.add_use_item(source_map, it),
366 ast::ModuleItemKind::ExternCrateItem(_) => {
367 // TODO
368 }
369 ast::ModuleItemKind::ConstDef(it) => {
370 self.items.push(ModuleItem::new(file_id, file_items, it)?)
371 }
372 ast::ModuleItemKind::StaticDef(it) => {
373 self.items.push(ModuleItem::new(file_id, file_items, it)?)
374 }
375 ast::ModuleItemKind::Module(it) => {
376 self.items.push(ModuleItem::new(file_id, file_items, it)?)
377 }
378 }
379 Some(())
380 }
381
382 fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
383 Path::expand_use_item(item, |path, segment| {
384 let import = self.imports.alloc(ImportData {
385 path,
386 is_glob: segment.is_none(),
387 });
388 if let Some(segment) = segment {
389 source_map.insert(import, segment)
390 }
391 })
392 }
393}
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 370e10bb8..7b0ce3b61 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -1,4 +1,4 @@
1use ra_syntax::{ast, AstNode, TextRange}; 1use ra_syntax::{ast, AstNode};
2 2
3use crate::{Name, AsName}; 3use crate::{Name, AsName};
4 4
@@ -18,7 +18,10 @@ pub enum PathKind {
18 18
19impl Path { 19impl Path {
20 /// Calls `cb` with all paths, represented by this use item. 20 /// Calls `cb` with all paths, represented by this use item.
21 pub fn expand_use_item(item: &ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) { 21 pub fn expand_use_item<'a>(
22 item: &'a ast::UseItem,
23 mut cb: impl FnMut(Path, Option<&'a ast::PathSegment>),
24 ) {
22 if let Some(tree) = item.use_tree() { 25 if let Some(tree) = item.use_tree() {
23 expand_use_tree(None, tree, &mut cb); 26 expand_use_tree(None, tree, &mut cb);
24 } 27 }
@@ -98,10 +101,10 @@ impl From<Name> for Path {
98 } 101 }
99} 102}
100 103
101fn expand_use_tree( 104fn expand_use_tree<'a>(
102 prefix: Option<Path>, 105 prefix: Option<Path>,
103 tree: &ast::UseTree, 106 tree: &'a ast::UseTree,
104 cb: &mut impl FnMut(Path, Option<TextRange>), 107 cb: &mut impl FnMut(Path, Option<&'a ast::PathSegment>),
105) { 108) {
106 if let Some(use_tree_list) = tree.use_tree_list() { 109 if let Some(use_tree_list) = tree.use_tree_list() {
107 let prefix = match tree.path() { 110 let prefix = match tree.path() {
@@ -125,20 +128,18 @@ fn expand_use_tree(
125 if let Some(segment) = ast_path.segment() { 128 if let Some(segment) = ast_path.segment() {
126 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { 129 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
127 if let Some(prefix) = prefix { 130 if let Some(prefix) = prefix {
128 cb(prefix, Some(segment.syntax().range())); 131 cb(prefix, Some(segment));
129 return; 132 return;
130 } 133 }
131 } 134 }
132 } 135 }
133 } 136 }
134 if let Some(path) = convert_path(prefix, ast_path) { 137 if let Some(path) = convert_path(prefix, ast_path) {
135 let range = if tree.has_star() { 138 if tree.has_star() {
136 None 139 cb(path, None)
137 } else { 140 } else if let Some(segment) = ast_path.segment() {
138 let range = ast_path.segment().unwrap().syntax().range(); 141 cb(path, Some(segment))
139 Some(range)
140 }; 142 };
141 cb(path, range)
142 } 143 }
143 // TODO: report errors somewhere 144 // TODO: report errors somewhere
144 // We get here if we do 145 // We get here if we do
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index 985a02410..074153862 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -46,7 +46,7 @@ pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<
46 let module_tree = db.module_tree(source_root); 46 let module_tree = db.module_tree(source_root);
47 let input = module_tree 47 let input = module_tree
48 .modules() 48 .modules()
49 .map(|id| (id, db.input_module_items(source_root, id))) 49 .map(|id| (id, db.lower_module_module(source_root, id)))
50 .collect::<FxHashMap<_, _>>(); 50 .collect::<FxHashMap<_, _>>();
51 51
52 let resolver = Resolver::new(db, &input, source_root, module_tree); 52 let resolver = Resolver::new(db, &input, source_root, module_tree);
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs
index 699680748..4276e47e8 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide_api/src/completion/complete_scope.rs
@@ -1,5 +1,5 @@
1use rustc_hash::FxHashSet; 1use rustc_hash::FxHashSet;
2use ra_syntax::TextUnit; 2use ra_syntax::{AstNode, TextUnit};
3 3
4use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; 4use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
5 5
@@ -17,18 +17,15 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
17 } 17 }
18 18
19 let module_scope = module.scope(ctx.db); 19 let module_scope = module.scope(ctx.db);
20 let (file_id, _) = module.definition_source(ctx.db);
21 module_scope 20 module_scope
22 .entries() 21 .entries()
23 .filter(|(_name, res)| { 22 .filter(|(_name, res)| {
24 // Don't expose this item 23 // For cases like `use self::foo<|>` don't suggest foo itself.
25 // FIXME: this penetrates through all kinds of abstractions,
26 // we need to figura out the way to do it less ugly.
27 match res.import { 24 match res.import {
28 None => true, 25 None => true,
29 Some(import) => { 26 Some(import) => {
30 let range = import.range(ctx.db, file_id); 27 let source = module.import_source(ctx.db, import);
31 !range.is_subrange(&ctx.leaf.range()) 28 !source.syntax().range().is_subrange(&ctx.leaf.range())
32 } 29 }
33 } 30 }
34 }) 31 })
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index 36778b955..a1d3333b2 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -114,6 +114,9 @@ salsa::database_storage! {
114 fn file_items() for hir::db::FileItemsQuery; 114 fn file_items() for hir::db::FileItemsQuery;
115 fn file_item() for hir::db::FileItemQuery; 115 fn file_item() for hir::db::FileItemQuery;
116 fn input_module_items() for hir::db::InputModuleItemsQuery; 116 fn input_module_items() for hir::db::InputModuleItemsQuery;
117 fn lower_module() for hir::db::LowerModuleQuery;
118 fn lower_module_module() for hir::db::LowerModuleModuleQuery;
119 fn lower_module_source_map() for hir::db::LowerModuleSourceMapQuery;
117 fn item_map() for hir::db::ItemMapQuery; 120 fn item_map() for hir::db::ItemMapQuery;
118 fn submodules() for hir::db::SubmodulesQuery; 121 fn submodules() for hir::db::SubmodulesQuery;
119 fn infer() for hir::db::InferQuery; 122 fn infer() for hir::db::InferQuery;