aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs18
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/has_source.rs16
-rw-r--r--crates/ra_hir/src/lib.rs4
-rw-r--r--crates/ra_hir_def/src/db.rs11
-rw-r--r--crates/ra_hir_def/src/item_scope.rs35
-rw-r--r--crates/ra_hir_def/src/lib.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs46
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs68
-rw-r--r--crates/ra_hir_def/src/trace.rs8
-rw-r--r--crates/ra_ide/src/change.rs2
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs17
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs4
13 files changed, 166 insertions, 71 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index e6768ea0b..fca3a2950 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -12,8 +12,8 @@ use hir_def::{
12 resolver::HasResolver, 12 resolver::HasResolver,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, 14 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId,
15 LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, 15 LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId,
16 TypeParamId, UnionId, 16 TraitId, TypeAliasId, TypeParamId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -180,11 +180,13 @@ impl Module {
180 } 180 }
181 181
182 /// Returns a `ModuleScope`: a set of items, visible in this module. 182 /// Returns a `ModuleScope`: a set of items, visible in this module.
183 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { 183 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
184 db.crate_def_map(self.id.krate)[self.id.local_id] 184 db.crate_def_map(self.id.krate)[self.id.local_id]
185 .scope 185 .scope
186 .entries() 186 .entries()
187 .map(|(name, res)| (name.clone(), res.def.into())) 187 .map(|(name, res)| {
188 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
189 })
188 .collect() 190 .collect()
189 } 191 }
190 192
@@ -227,10 +229,10 @@ impl Module {
227 } 229 }
228} 230}
229 231
230// pub struct Import { 232pub struct Import {
231// pub(crate) parent: Module, 233 pub(crate) parent: Module,
232// pub(crate) id: LocalImportId, 234 pub(crate) id: LocalImportId,
233// } 235}
234 236
235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 237#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
236pub struct StructField { 238pub struct StructField {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index f5ffd64fa..bfae3660b 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -4,8 +4,8 @@ pub use hir_def::db::{
4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, 4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, 5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery, 7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery,
8 TraitDataQuery, TypeAliasDataQuery, 8 StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
9}; 9};
10pub use hir_expand::db::{ 10pub use hir_expand::db::{
11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs
index 5541266e2..72afecf26 100644
--- a/crates/ra_hir/src/has_source.rs
+++ b/crates/ra_hir/src/has_source.rs
@@ -9,8 +9,8 @@ use hir_def::{
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module, 12 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
13 Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, 13 Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union,
14}; 14};
15 15
16pub use hir_expand::InFile; 16pub use hir_expand::InFile;
@@ -117,6 +117,18 @@ impl HasSource for ImplBlock {
117 self.id.lookup(db).source(db) 117 self.id.lookup(db).source(db)
118 } 118 }
119} 119}
120impl HasSource for Import {
121 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
122
123 /// Returns the syntax of the last path segment corresponding to this import
124 fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> {
125 let src = self.parent.definition_source(db);
126 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
127 let root = db.parse_or_expand(src.file_id).unwrap();
128 let ptr = source_map.get(self.id);
129 src.with_value(ptr.map_left(|it| it.to_node(&root)).map_right(|it| it.to_node(&root)))
130 }
131}
120 132
121impl HasSource for TypeParam { 133impl HasSource for TypeParam {
122 type Ast = Either<ast::TraitDef, ast::TypeParam>; 134 type Ast = Either<ast::TraitDef, ast::TypeParam>;
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 0008a8858..7f9aef770 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -40,8 +40,8 @@ mod from_source;
40pub use crate::{ 40pub use crate::{
41 code_model::{ 41 code_model::{
42 Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, 42 Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum,
43 EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef, 43 EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Import, Local,
44 Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, 44 MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
45 TypeParam, Union, VariantDef, 45 TypeParam, Union, VariantDef,
46 }, 46 },
47 from_source::FromSource, 47 from_source::FromSource,
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index c55fd4111..98bff6cb7 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -13,7 +13,10 @@ use crate::{
13 docs::Documentation, 13 docs::Documentation,
14 generics::GenericParams, 14 generics::GenericParams,
15 lang_item::{LangItemTarget, LangItems}, 15 lang_item::{LangItemTarget, LangItems},
16 nameres::{raw::RawItems, CrateDefMap}, 16 nameres::{
17 raw::{ImportSourceMap, RawItems},
18 CrateDefMap,
19 },
17 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
18 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
19 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -43,6 +46,12 @@ pub trait InternDatabase: SourceDatabase {
43 46
44#[salsa::query_group(DefDatabaseStorage)] 47#[salsa::query_group(DefDatabaseStorage)]
45pub trait DefDatabase: InternDatabase + AstDatabase { 48pub trait DefDatabase: InternDatabase + AstDatabase {
49 #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
50 fn raw_items_with_source_map(
51 &self,
52 file_id: HirFileId,
53 ) -> (Arc<RawItems>, Arc<ImportSourceMap>);
54
46 #[salsa::invoke(RawItems::raw_items_query)] 55 #[salsa::invoke(RawItems::raw_items_query)]
47 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 56 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
48 57
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index 5c14fefff..6b9be8325 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -5,7 +5,7 @@ use hir_expand::name::Name;
5use once_cell::sync::Lazy; 5use once_cell::sync::Lazy;
6use rustc_hash::FxHashMap; 6use rustc_hash::FxHashMap;
7 7
8use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; 8use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId};
9 9
10#[derive(Debug, Default, PartialEq, Eq)] 10#[derive(Debug, Default, PartialEq, Eq)]
11pub struct ItemScope { 11pub struct ItemScope {
@@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
30 BuiltinType::ALL 30 BuiltinType::ALL
31 .iter() 31 .iter()
32 .map(|(name, ty)| { 32 .map(|(name, ty)| {
33 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), declaration: false }) 33 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
34 }) 34 })
35 .collect() 35 .collect()
36}); 36});
@@ -53,9 +53,11 @@ impl ItemScope {
53 } 53 }
54 54
55 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { 55 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
56 self.entries().filter(|(_name, res)| res.declaration).flat_map(|(_name, res)| { 56 self.entries()
57 res.def.take_types().into_iter().chain(res.def.take_values().into_iter()) 57 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
58 }) 58 .flat_map(|per_ns| {
59 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
60 })
59 } 61 }
60 62
61 pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ { 63 pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
@@ -110,26 +112,38 @@ impl ItemScope {
110 self.legacy_macros.insert(name, mac); 112 self.legacy_macros.insert(name, mac);
111 } 113 }
112 114
113 pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, declaration: bool) -> bool { 115 pub(crate) fn push_res(
116 &mut self,
117 name: Name,
118 res: &Resolution,
119 import: Option<LocalImportId>,
120 ) -> bool {
114 let mut changed = false; 121 let mut changed = false;
115 let existing = self.items.entry(name.clone()).or_default(); 122 let existing = self.items.entry(name.clone()).or_default();
116 123
117 if existing.def.types.is_none() && res.def.types.is_some() { 124 if existing.def.types.is_none() && res.def.types.is_some() {
118 existing.def.types = res.def.types; 125 existing.def.types = res.def.types;
119 existing.declaration |= declaration; 126 existing.import = import.or(res.import);
120 changed = true; 127 changed = true;
121 } 128 }
122 if existing.def.values.is_none() && res.def.values.is_some() { 129 if existing.def.values.is_none() && res.def.values.is_some() {
123 existing.def.values = res.def.values; 130 existing.def.values = res.def.values;
124 existing.declaration |= declaration; 131 existing.import = import.or(res.import);
125 changed = true; 132 changed = true;
126 } 133 }
127 if existing.def.macros.is_none() && res.def.macros.is_some() { 134 if existing.def.macros.is_none() && res.def.macros.is_some() {
128 existing.def.macros = res.def.macros; 135 existing.def.macros = res.def.macros;
129 existing.declaration |= declaration; 136 existing.import = import.or(res.import);
130 changed = true; 137 changed = true;
131 } 138 }
132 139
140 if existing.def.is_none()
141 && res.def.is_none()
142 && existing.import.is_none()
143 && res.import.is_some()
144 {
145 existing.import = res.import;
146 }
133 changed 147 changed
134 } 148 }
135 149
@@ -146,5 +160,6 @@ impl ItemScope {
146pub struct Resolution { 160pub struct Resolution {
147 /// None for unresolved 161 /// None for unresolved
148 pub def: PerNs, 162 pub def: PerNs,
149 pub declaration: bool, 163 /// ident by which this is imported into local scope.
164 pub import: Option<LocalImportId>,
150} 165}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f6c7f38d1..acd4f4af1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -52,6 +52,10 @@ use crate::body::Expander;
52use crate::builtin_type::BuiltinType; 52use crate::builtin_type::BuiltinType;
53 53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55pub struct LocalImportId(RawId);
56impl_arena_id!(LocalImportId);
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55pub struct ModuleId { 59pub struct ModuleId {
56 pub krate: CrateId, 60 pub krate: CrateId,
57 pub local_id: LocalModuleId, 61 pub local_id: LocalModuleId,
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 9419461a8..45199fa11 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -26,7 +26,8 @@ use crate::{
26 path::{ModPath, PathKind}, 26 path::{ModPath, PathKind},
27 per_ns::PerNs, 27 per_ns::PerNs,
28 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, 28 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
29 LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 29 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc,
30 TypeAliasLoc, UnionLoc,
30}; 31};
31 32
32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 33pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -92,7 +93,7 @@ impl PartialResolvedImport {
92#[derive(Clone, Debug, Eq, PartialEq)] 93#[derive(Clone, Debug, Eq, PartialEq)]
93struct ImportDirective { 94struct ImportDirective {
94 module_id: LocalModuleId, 95 module_id: LocalModuleId,
95 import_id: raw::LocalImportId, 96 import_id: LocalImportId,
96 import: raw::ImportData, 97 import: raw::ImportData,
97 status: PartialResolvedImport, 98 status: PartialResolvedImport,
98} 99}
@@ -109,7 +110,7 @@ struct MacroDirective {
109struct DefCollector<'a, DB> { 110struct DefCollector<'a, DB> {
110 db: &'a DB, 111 db: &'a DB,
111 def_map: CrateDefMap, 112 def_map: CrateDefMap,
112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::LocalImportId)>>, 113 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
113 unresolved_imports: Vec<ImportDirective>, 114 unresolved_imports: Vec<ImportDirective>,
114 resolved_imports: Vec<ImportDirective>, 115 resolved_imports: Vec<ImportDirective>,
115 unexpanded_macros: Vec<MacroDirective>, 116 unexpanded_macros: Vec<MacroDirective>,
@@ -217,7 +218,8 @@ where
217 if export { 218 if export {
218 self.update( 219 self.update(
219 self.def_map.root, 220 self.def_map.root,
220 &[(name, Resolution { def: PerNs::macros(macro_), declaration: false })], 221 None,
222 &[(name, Resolution { def: PerNs::macros(macro_), import: None })],
221 ); 223 );
222 } 224 }
223 } 225 }
@@ -372,7 +374,7 @@ where
372 // Module scoped macros is included 374 // Module scoped macros is included
373 let items = scope.collect_resolutions(); 375 let items = scope.collect_resolutions();
374 376
375 self.update(module_id, &items); 377 self.update(module_id, Some(import_id), &items);
376 } else { 378 } else {
377 // glob import from same crate => we do an initial 379 // glob import from same crate => we do an initial
378 // import, and then need to propagate any further 380 // import, and then need to propagate any further
@@ -382,7 +384,7 @@ where
382 // Module scoped macros is included 384 // Module scoped macros is included
383 let items = scope.collect_resolutions(); 385 let items = scope.collect_resolutions();
384 386
385 self.update(module_id, &items); 387 self.update(module_id, Some(import_id), &items);
386 // record the glob import in case we add further items 388 // record the glob import in case we add further items
387 let glob = self.glob_imports.entry(m.local_id).or_default(); 389 let glob = self.glob_imports.entry(m.local_id).or_default();
388 if !glob.iter().any(|it| *it == (module_id, import_id)) { 390 if !glob.iter().any(|it| *it == (module_id, import_id)) {
@@ -402,12 +404,12 @@ where
402 let variant = EnumVariantId { parent: e, local_id }; 404 let variant = EnumVariantId { parent: e, local_id };
403 let res = Resolution { 405 let res = Resolution {
404 def: PerNs::both(variant.into(), variant.into()), 406 def: PerNs::both(variant.into(), variant.into()),
405 declaration: false, 407 import: Some(import_id),
406 }; 408 };
407 (name, res) 409 (name, res)
408 }) 410 })
409 .collect::<Vec<_>>(); 411 .collect::<Vec<_>>();
410 self.update(module_id, &resolutions); 412 self.update(module_id, Some(import_id), &resolutions);
411 } 413 }
412 Some(d) => { 414 Some(d) => {
413 log::debug!("glob import {:?} from non-module/enum {:?}", import, d); 415 log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -429,21 +431,27 @@ where
429 } 431 }
430 } 432 }
431 433
432 let resolution = Resolution { def, declaration: false }; 434 let resolution = Resolution { def, import: Some(import_id) };
433 self.update(module_id, &[(name, resolution)]); 435 self.update(module_id, Some(import_id), &[(name, resolution)]);
434 } 436 }
435 None => tested_by!(bogus_paths), 437 None => tested_by!(bogus_paths),
436 } 438 }
437 } 439 }
438 } 440 }
439 441
440 fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { 442 fn update(
441 self.update_recursive(module_id, resolutions, 0) 443 &mut self,
444 module_id: LocalModuleId,
445 import: Option<LocalImportId>,
446 resolutions: &[(Name, Resolution)],
447 ) {
448 self.update_recursive(module_id, import, resolutions, 0)
442 } 449 }
443 450
444 fn update_recursive( 451 fn update_recursive(
445 &mut self, 452 &mut self,
446 module_id: LocalModuleId, 453 module_id: LocalModuleId,
454 import: Option<LocalImportId>,
447 resolutions: &[(Name, Resolution)], 455 resolutions: &[(Name, Resolution)],
448 depth: usize, 456 depth: usize,
449 ) { 457 ) {
@@ -454,7 +462,7 @@ where
454 let scope = &mut self.def_map.modules[module_id].scope; 462 let scope = &mut self.def_map.modules[module_id].scope;
455 let mut changed = false; 463 let mut changed = false;
456 for (name, res) in resolutions { 464 for (name, res) in resolutions {
457 changed |= scope.push_res(name.clone(), res, depth == 0 && res.declaration); 465 changed |= scope.push_res(name.clone(), res, import);
458 } 466 }
459 467
460 if !changed { 468 if !changed {
@@ -467,9 +475,9 @@ where
467 .flat_map(|v| v.iter()) 475 .flat_map(|v| v.iter())
468 .cloned() 476 .cloned()
469 .collect::<Vec<_>>(); 477 .collect::<Vec<_>>();
470 for (glob_importing_module, _glob_import) in glob_imports { 478 for (glob_importing_module, glob_import) in glob_imports {
471 // We pass the glob import so that the tracked import in those modules is that glob import 479 // We pass the glob import so that the tracked import in those modules is that glob import
472 self.update_recursive(glob_importing_module, resolutions, depth + 1); 480 self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1);
473 } 481 }
474 } 482 }
475 483
@@ -711,9 +719,9 @@ where
711 def: PerNs::types( 719 def: PerNs::types(
712 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), 720 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(),
713 ), 721 ),
714 declaration: true, 722 import: None,
715 }; 723 };
716 self.def_collector.update(self.module_id, &[(name, resolution)]); 724 self.def_collector.update(self.module_id, None, &[(name, resolution)]);
717 res 725 res
718 } 726 }
719 727
@@ -783,8 +791,8 @@ where
783 PerNs::types(def.into()) 791 PerNs::types(def.into())
784 } 792 }
785 }; 793 };
786 let resolution = Resolution { def, declaration: true }; 794 let resolution = Resolution { def, import: None };
787 self.def_collector.update(self.module_id, &[(name, resolution)]) 795 self.def_collector.update(self.module_id, None, &[(name, resolution)])
788 } 796 }
789 797
790 fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { 798 fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index b10e458a2..ecb4d7c03 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -7,24 +7,24 @@
7 7
8use std::{ops::Index, sync::Arc}; 8use std::{ops::Index, sync::Arc};
9 9
10use either::Either;
10use hir_expand::{ 11use hir_expand::{
11 ast_id_map::AstIdMap, 12 ast_id_map::AstIdMap,
12 db::AstDatabase, 13 db::AstDatabase,
13 hygiene::Hygiene, 14 hygiene::Hygiene,
14 name::{AsName, Name}, 15 name::{AsName, Name},
15}; 16};
16use ra_arena::{impl_arena_id, Arena, RawId}; 17use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
17use ra_syntax::{ 18use ra_syntax::{
18 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner},
19 AstNode, 20 AstNode, AstPtr,
20}; 21};
21use test_utils::tested_by; 22use test_utils::tested_by;
22 23
23use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; 24use crate::{
24 25 attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 26 LocalImportId,
26pub(super) struct LocalImportId(RawId); 27};
27impl_arena_id!(LocalImportId);
28 28
29/// `RawItems` is a set of top-level items in a file (except for impls). 29/// `RawItems` is a set of top-level items in a file (except for impls).
30/// 30///
@@ -41,14 +41,35 @@ pub struct RawItems {
41 items: Vec<RawItem>, 41 items: Vec<RawItem>,
42} 42}
43 43
44#[derive(Debug, Default, PartialEq, Eq)]
45pub struct ImportSourceMap {
46 map: ArenaMap<LocalImportId, ImportSourcePtr>,
47}
48
49type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
50
51impl ImportSourceMap {
52 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
53 self.map[import].clone()
54 }
55}
56
44impl RawItems { 57impl RawItems {
45 pub(crate) fn raw_items_query( 58 pub(crate) fn raw_items_query(
46 db: &(impl DefDatabase + AstDatabase), 59 db: &(impl DefDatabase + AstDatabase),
47 file_id: HirFileId, 60 file_id: HirFileId,
48 ) -> Arc<RawItems> { 61 ) -> Arc<RawItems> {
62 db.raw_items_with_source_map(file_id).0
63 }
64
65 pub(crate) fn raw_items_with_source_map_query(
66 db: &(impl DefDatabase + AstDatabase),
67 file_id: HirFileId,
68 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
49 let mut collector = RawItemsCollector { 69 let mut collector = RawItemsCollector {
50 raw_items: RawItems::default(), 70 raw_items: RawItems::default(),
51 source_ast_id_map: db.ast_id_map(file_id), 71 source_ast_id_map: db.ast_id_map(file_id),
72 imports: Trace::new(),
52 file_id, 73 file_id,
53 hygiene: Hygiene::new(db, file_id), 74 hygiene: Hygiene::new(db, file_id),
54 }; 75 };
@@ -59,8 +80,11 @@ impl RawItems {
59 collector.process_module(None, item_list); 80 collector.process_module(None, item_list);
60 } 81 }
61 } 82 }
62 let raw_items = collector.raw_items; 83 let mut raw_items = collector.raw_items;
63 Arc::new(raw_items) 84 let (arena, map) = collector.imports.into_arena_and_map();
85 raw_items.imports = arena;
86 let source_map = ImportSourceMap { map };
87 (Arc::new(raw_items), Arc::new(source_map))
64 } 88 }
65 89
66 pub(super) fn items(&self) -> &[RawItem] { 90 pub(super) fn items(&self) -> &[RawItem] {
@@ -199,6 +223,7 @@ pub(super) struct ImplData {
199 223
200struct RawItemsCollector { 224struct RawItemsCollector {
201 raw_items: RawItems, 225 raw_items: RawItems,
226 imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
202 source_ast_id_map: Arc<AstIdMap>, 227 source_ast_id_map: Arc<AstIdMap>,
203 file_id: HirFileId, 228 file_id: HirFileId,
204 hygiene: Hygiene, 229 hygiene: Hygiene,
@@ -305,7 +330,7 @@ impl RawItemsCollector {
305 ModPath::expand_use_item( 330 ModPath::expand_use_item(
306 InFile { value: use_item, file_id: self.file_id }, 331 InFile { value: use_item, file_id: self.file_id },
307 &self.hygiene, 332 &self.hygiene,
308 |path, _use_tree, is_glob, alias| { 333 |path, use_tree, is_glob, alias| {
309 let import_data = ImportData { 334 let import_data = ImportData {
310 path, 335 path,
311 alias, 336 alias,
@@ -314,11 +339,11 @@ impl RawItemsCollector {
314 is_extern_crate: false, 339 is_extern_crate: false,
315 is_macro_use: false, 340 is_macro_use: false,
316 }; 341 };
317 buf.push(import_data); 342 buf.push((import_data, Either::Left(AstPtr::new(use_tree))));
318 }, 343 },
319 ); 344 );
320 for import_data in buf { 345 for (import_data, ptr) in buf {
321 self.push_import(current_module, attrs.clone(), import_data); 346 self.push_import(current_module, attrs.clone(), import_data, ptr);
322 } 347 }
323 } 348 }
324 349
@@ -341,7 +366,12 @@ impl RawItemsCollector {
341 is_extern_crate: true, 366 is_extern_crate: true,
342 is_macro_use, 367 is_macro_use,
343 }; 368 };
344 self.push_import(current_module, attrs, import_data); 369 self.push_import(
370 current_module,
371 attrs,
372 import_data,
373 Either::Right(AstPtr::new(&extern_crate)),
374 );
345 } 375 }
346 } 376 }
347 377
@@ -372,8 +402,14 @@ impl RawItemsCollector {
372 self.push_item(current_module, attrs, RawItemKind::Impl(imp)) 402 self.push_item(current_module, attrs, RawItemKind::Impl(imp))
373 } 403 }
374 404
375 fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) { 405 fn push_import(
376 let import = self.raw_items.imports.alloc(data); 406 &mut self,
407 current_module: Option<Module>,
408 attrs: Attrs,
409 data: ImportData,
410 source: ImportSourcePtr,
411 ) {
412 let import = self.imports.alloc(|| source, || data);
377 self.push_item(current_module, attrs, RawItemKind::Import(import)) 413 self.push_item(current_module, attrs, RawItemKind::Import(import))
378 } 414 }
379 415
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs
index 9769e88df..2bcd707bc 100644
--- a/crates/ra_hir_def/src/trace.rs
+++ b/crates/ra_hir_def/src/trace.rs
@@ -18,6 +18,10 @@ pub(crate) struct Trace<ID: ArenaId, T, V> {
18} 18}
19 19
20impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { 20impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
21 pub(crate) fn new() -> Trace<ID, T, V> {
22 Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 }
23 }
24
21 pub(crate) fn new_for_arena() -> Trace<ID, T, V> { 25 pub(crate) fn new_for_arena() -> Trace<ID, T, V> {
22 Trace { arena: Some(Arena::default()), map: None, len: 0 } 26 Trace { arena: Some(Arena::default()), map: None, len: 0 }
23 } 27 }
@@ -48,4 +52,8 @@ impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
48 pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> { 52 pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> {
49 self.map.take().unwrap() 53 self.map.take().unwrap()
50 } 54 }
55
56 pub(crate) fn into_arena_and_map(mut self) -> (Arena<ID, T>, ArenaMap<ID, V>) {
57 (self.arena.take().unwrap(), self.map.take().unwrap())
58 }
51} 59}
diff --git a/crates/ra_ide/src/change.rs b/crates/ra_ide/src/change.rs
index 387a9cafb..4a76d1dd8 100644
--- a/crates/ra_ide/src/change.rs
+++ b/crates/ra_ide/src/change.rs
@@ -270,6 +270,7 @@ impl RootDatabase {
270 270
271 self.query(hir::db::AstIdMapQuery).sweep(sweep); 271 self.query(hir::db::AstIdMapQuery).sweep(sweep);
272 272
273 self.query(hir::db::RawItemsWithSourceMapQuery).sweep(sweep);
273 self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep); 274 self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep);
274 275
275 self.query(hir::db::ExprScopesQuery).sweep(sweep); 276 self.query(hir::db::ExprScopesQuery).sweep(sweep);
@@ -308,6 +309,7 @@ impl RootDatabase {
308 hir::db::StructDataQuery 309 hir::db::StructDataQuery
309 hir::db::EnumDataQuery 310 hir::db::EnumDataQuery
310 hir::db::TraitDataQuery 311 hir::db::TraitDataQuery
312 hir::db::RawItemsWithSourceMapQuery
311 hir::db::RawItemsQuery 313 hir::db::RawItemsQuery
312 hir::db::CrateDefMapQuery 314 hir::db::CrateDefMapQuery
313 hir::db::GenericParamsQuery 315 hir::db::GenericParamsQuery
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index 8ce86ad7d..28f94e0a7 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Adt, PathResolution, ScopeDef}; 3use either::Either;
4use hir::{Adt, HasSource, PathResolution};
4use ra_syntax::AstNode; 5use ra_syntax::AstNode;
5use test_utils::tested_by; 6use test_utils::tested_by;
6 7
@@ -18,15 +19,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
18 match def { 19 match def {
19 hir::ModuleDef::Module(module) => { 20 hir::ModuleDef::Module(module) => {
20 let module_scope = module.scope(ctx.db); 21 let module_scope = module.scope(ctx.db);
21 for (name, def) in module_scope { 22 for (name, def, import) in module_scope {
22 if ctx.use_item_syntax.is_some() { 23 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def {
23 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def { 24 if ctx.use_item_syntax.is_some() {
24 tested_by!(dont_complete_primitive_in_use); 25 tested_by!(dont_complete_primitive_in_use);
25 continue; 26 continue;
26 } 27 }
27 if let ScopeDef::Unknown = def { 28 }
28 if let Some(name_ref) = ctx.name_ref.as_ref() { 29 if Some(module) == ctx.module {
29 if &name_ref.syntax().text() == name.to_string().as_str() { 30 if let Some(import) = import {
31 if let Either::Left(use_tree) = import.source(ctx.db).value {
32 if use_tree.syntax().text_range().contains_inclusive(ctx.offset) {
30 // for `use self::foo<|>`, don't suggest `foo` as a completion 33 // for `use self::foo<|>`, don't suggest `foo` as a completion
31 tested_by!(dont_complete_current_use); 34 tested_by!(dont_complete_current_use);
32 continue; 35 continue;
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 8f56ce706..4894ea2f6 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -18,7 +18,6 @@ pub(crate) struct CompletionContext<'a> {
18 pub(super) analyzer: hir::SourceAnalyzer, 18 pub(super) analyzer: hir::SourceAnalyzer,
19 pub(super) offset: TextUnit, 19 pub(super) offset: TextUnit,
20 pub(super) token: SyntaxToken, 20 pub(super) token: SyntaxToken,
21 pub(super) name_ref: Option<ast::NameRef>,
22 pub(super) module: Option<hir::Module>, 21 pub(super) module: Option<hir::Module>,
23 pub(super) function_syntax: Option<ast::FnDef>, 22 pub(super) function_syntax: Option<ast::FnDef>,
24 pub(super) use_item_syntax: Option<ast::UseItem>, 23 pub(super) use_item_syntax: Option<ast::UseItem>,
@@ -69,7 +68,6 @@ impl<'a> CompletionContext<'a> {
69 analyzer, 68 analyzer,
70 token, 69 token,
71 offset: position.offset, 70 offset: position.offset,
72 name_ref: None,
73 module, 71 module,
74 function_syntax: None, 72 function_syntax: None,
75 use_item_syntax: None, 73 use_item_syntax: None,
@@ -144,8 +142,6 @@ impl<'a> CompletionContext<'a> {
144 } 142 }
145 143
146 fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) { 144 fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) {
147 self.name_ref =
148 find_node_at_offset(original_file.syntax(), name_ref.syntax().text_range().start());
149 let name_range = name_ref.syntax().text_range(); 145 let name_range = name_ref.syntax().text_range();
150 if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() { 146 if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() {
151 self.record_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); 147 self.record_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset);