aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-23 20:14:13 +0000
committerAleksey Kladov <[email protected]>2019-01-24 10:29:19 +0000
commit3ab1519cb27b927074ed7fbbb18a856e6e7fabb8 (patch)
tree692c7a256604e188d38890966290bd1637d7dd60 /crates/ra_hir
parentcfb085ded8d61d7b744d0a83ecbb3da254f6ab9f (diff)
Change ids strategy
this is a part of larghish hir refactoring which aims to * replace per-source-root module trees with per crate trees * switch from a monotyped DedId to type-specific ids
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/adt.rs2
-rw-r--r--crates/ra_hir/src/code_model_api.rs32
-rw-r--r--crates/ra_hir/src/code_model_impl/krate.rs24
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs180
-rw-r--r--crates/ra_hir/src/db.rs36
-rw-r--r--crates/ra_hir/src/ids.rs22
-rw-r--r--crates/ra_hir/src/impl_block.rs25
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/mock.rs13
-rw-r--r--crates/ra_hir/src/module_tree.rs36
-rw-r--r--crates/ra_hir/src/nameres.rs56
-rw-r--r--crates/ra_hir/src/nameres/lower.rs74
-rw-r--r--crates/ra_hir/src/nameres/tests.rs35
-rw-r--r--crates/ra_hir/src/query_definitions.rs20
-rw-r--r--crates/ra_hir/src/source_binder.rs28
-rw-r--r--crates/ra_hir/src/ty.rs21
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs26
17 files changed, 277 insertions, 355 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index ab1c428db..4cca09351 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -64,9 +64,9 @@ fn get_def_id(
64 ..same_file_loc.source_item_id 64 ..same_file_loc.source_item_id
65 }; 65 };
66 let loc = DefLoc { 66 let loc = DefLoc {
67 module: same_file_loc.module,
67 kind: expected_kind, 68 kind: expected_kind,
68 source_item_id, 69 source_item_id,
69 ..*same_file_loc
70 }; 70 };
71 loc.id(db) 71 loc.id(db)
72} 72}
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 3ff07bd60..f59a60c07 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -14,13 +14,14 @@ use crate::{
14 adt::VariantData, 14 adt::VariantData,
15 generics::GenericParams, 15 generics::GenericParams,
16 code_model_impl::def_id_to_ast, 16 code_model_impl::def_id_to_ast,
17 docs::{Documentation, Docs, docs_from_ast} 17 docs::{Documentation, Docs, docs_from_ast},
18 module_tree::ModuleId,
18}; 19};
19 20
20/// hir::Crate describes a single crate. It's the main interface with which 21/// hir::Crate describes a single crate. It's the main interface with which
21/// a crate's dependencies interact. Mostly, it should be just a proxy for the 22/// a crate's dependencies interact. Mostly, it should be just a proxy for the
22/// root module. 23/// root module.
23#[derive(Debug, Clone, PartialEq, Eq, Hash)] 24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub struct Crate { 25pub struct Crate {
25 pub(crate) crate_id: CrateId, 26 pub(crate) crate_id: CrateId,
26} 27}
@@ -45,7 +46,6 @@ impl Crate {
45 46
46#[derive(Debug)] 47#[derive(Debug)]
47pub enum Def { 48pub enum Def {
48 Module(Module),
49 Struct(Struct), 49 Struct(Struct),
50 Enum(Enum), 50 Enum(Enum),
51 EnumVariant(EnumVariant), 51 EnumVariant(EnumVariant),
@@ -57,9 +57,29 @@ pub enum Def {
57 Item, 57 Item,
58} 58}
59 59
60#[derive(Debug, Clone, PartialEq, Eq, Hash)] 60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61pub struct Module { 61pub struct Module {
62 pub(crate) def_id: DefId, 62 pub(crate) krate: CrateId,
63 pub(crate) module_id: ModuleId,
64}
65
66/// The defs which can be visible in the module.
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum ModuleDef {
69 Module(Module),
70 Def(DefId),
71}
72
73impl Into<ModuleDef> for Module {
74 fn into(self) -> ModuleDef {
75 ModuleDef::Module(self)
76 }
77}
78
79impl Into<ModuleDef> for DefId {
80 fn into(self) -> ModuleDef {
81 ModuleDef::Def(self)
82 }
63} 83}
64 84
65pub enum ModuleSource { 85pub enum ModuleSource {
@@ -149,7 +169,7 @@ impl Module {
149 self.scope_impl(db) 169 self.scope_impl(db)
150 } 170 }
151 171
152 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { 172 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
153 self.resolve_path_impl(db, path) 173 self.resolve_path_impl(db, path)
154 } 174 }
155 175
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs
index 8c6e34873..cdd30b402 100644
--- a/crates/ra_hir/src/code_model_impl/krate.rs
+++ b/crates/ra_hir/src/code_model_impl/krate.rs
@@ -1,7 +1,7 @@
1use ra_db::CrateId; 1use ra_db::CrateId;
2 2
3use crate::{ 3use crate::{
4 HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, 4 Crate, CrateDependency, AsName, Module,
5 db::HirDatabase, 5 db::HirDatabase,
6}; 6};
7 7
@@ -21,27 +21,13 @@ impl Crate {
21 .collect() 21 .collect()
22 } 22 }
23 pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { 23 pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> {
24 let crate_graph = db.crate_graph(); 24 let module_tree = db.module_tree(self.crate_id);
25 let file_id = crate_graph.crate_root(self.crate_id); 25 let module_id = module_tree.modules().next()?;
26 let source_root_id = db.file_source_root(file_id);
27 let file_id = HirFileId::from(file_id);
28 let module_tree = db.module_tree(source_root_id);
29 // FIXME: teach module tree about crate roots instead of guessing
30 let source = SourceItemId {
31 file_id,
32 item_id: None,
33 };
34 let module_id = module_tree.find_module_by_source(source)?;
35 26
36 let def_loc = DefLoc { 27 let module = Module {
37 kind: DefKind::Module, 28 krate: self.crate_id,
38 source_root_id,
39 module_id, 29 module_id,
40 source_item_id: module_id.source(&module_tree),
41 }; 30 };
42 let def_id = def_loc.id(db);
43
44 let module = Module::new(def_id);
45 Some(module) 31 Some(module)
46 } 32 }
47} 33}
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index d94079f11..5d00e905b 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -1,52 +1,33 @@
1use ra_db::{SourceRootId, FileId}; 1use ra_db::FileId;
2use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; 2use ra_syntax::{ast, SyntaxNode, TreeArc};
3 3
4use crate::{ 4use crate::{
5 Module, ModuleSource, Problem, 5 Module, ModuleSource, Problem, ModuleDef,
6 Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, 6 Crate, Name, Path, PathKind, PerNs, Def,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 nameres::{ModuleScope, lower::ImportId}, 8 nameres::{ModuleScope, lower::ImportId},
9 db::HirDatabase, 9 db::HirDatabase,
10}; 10};
11 11
12impl Module { 12impl Module {
13 pub(crate) fn new(def_id: DefId) -> Self { 13 fn with_module_id(&self, module_id: ModuleId) -> Module {
14 crate::code_model_api::Module { def_id } 14 Module {
15 }
16
17 pub(crate) fn from_module_id(
18 db: &impl HirDatabase,
19 source_root_id: SourceRootId,
20 module_id: ModuleId,
21 ) -> Self {
22 let module_tree = db.module_tree(source_root_id);
23 let def_loc = DefLoc {
24 kind: DefKind::Module,
25 source_root_id,
26 module_id, 15 module_id,
27 source_item_id: module_id.source(&module_tree), 16 krate: self.krate,
28 }; 17 }
29 let def_id = def_loc.id(db);
30 Module::new(def_id)
31 } 18 }
32 19
33 pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { 20 pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
34 let loc = self.def_id.loc(db); 21 let module_tree = db.module_tree(self.krate);
35 let module_tree = db.module_tree(loc.source_root_id); 22 let link = self.module_id.parent_link(&module_tree)?;
36 let link = loc.module_id.parent_link(&module_tree)?;
37 Some(link.name(&module_tree).clone()) 23 Some(link.name(&module_tree).clone())
38 } 24 }
39 25
40 pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { 26 pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) {
41 let loc = self.def_id.loc(db); 27 let module_tree = db.module_tree(self.krate);
42 let file_id = loc.source_item_id.file_id.as_original_file(); 28 let source = self.module_id.source(&module_tree);
43 let syntax_node = db.file_item(loc.source_item_id); 29 let module_source = ModuleSource::from_source_item_id(db, source);
44 let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) { 30 let file_id = source.file_id.as_original_file();
45 ModuleSource::SourceFile(source_file.to_owned())
46 } else {
47 let module = ast::Module::cast(&syntax_node).unwrap();
48 ModuleSource::Module(module.to_owned())
49 };
50 (file_id, module_source) 31 (file_id, module_source)
51 } 32 }
52 33
@@ -54,9 +35,8 @@ impl Module {
54 &self, 35 &self,
55 db: &impl HirDatabase, 36 db: &impl HirDatabase,
56 ) -> Option<(FileId, TreeArc<ast::Module>)> { 37 ) -> Option<(FileId, TreeArc<ast::Module>)> {
57 let loc = self.def_id.loc(db); 38 let module_tree = db.module_tree(self.krate);
58 let module_tree = db.module_tree(loc.source_root_id); 39 let link = self.module_id.parent_link(&module_tree)?;
59 let link = loc.module_id.parent_link(&module_tree)?;
60 let file_id = link 40 let file_id = link
61 .owner(&module_tree) 41 .owner(&module_tree)
62 .source(&module_tree) 42 .source(&module_tree)
@@ -71,85 +51,67 @@ impl Module {
71 db: &impl HirDatabase, 51 db: &impl HirDatabase,
72 import: ImportId, 52 import: ImportId,
73 ) -> TreeArc<ast::PathSegment> { 53 ) -> TreeArc<ast::PathSegment> {
74 let loc = self.def_id.loc(db); 54 let source_map = db.lower_module_source_map(self.clone());
75 let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id);
76 let (_, source) = self.definition_source(db); 55 let (_, source) = self.definition_source(db);
77 source_map.get(&source, import) 56 source_map.get(&source, import)
78 } 57 }
79 58
80 pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> { 59 pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> {
81 let root = self.crate_root(db); 60 Some(Crate::new(self.krate))
82 let loc = root.def_id.loc(db);
83 let file_id = loc.source_item_id.file_id.as_original_file();
84
85 let crate_graph = db.crate_graph();
86 let crate_id = crate_graph.crate_id_for_crate_root(file_id)?;
87 Some(Crate::new(crate_id))
88 } 61 }
89 62
90 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { 63 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module {
91 let loc = self.def_id.loc(db); 64 let module_tree = db.module_tree(self.krate);
92 let module_tree = db.module_tree(loc.source_root_id); 65 let module_id = self.module_id.crate_root(&module_tree);
93 let module_id = loc.module_id.crate_root(&module_tree); 66 self.with_module_id(module_id)
94 Module::from_module_id(db, loc.source_root_id, module_id)
95 } 67 }
96 68
97 /// Finds a child module with the specified name. 69 /// Finds a child module with the specified name.
98 pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { 70 pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
99 let loc = self.def_id.loc(db); 71 let module_tree = db.module_tree(self.krate);
100 let module_tree = db.module_tree(loc.source_root_id); 72 let child_id = self.module_id.child(&module_tree, name)?;
101 let child_id = loc.module_id.child(&module_tree, name)?; 73 Some(self.with_module_id(child_id))
102 Some(Module::from_module_id(db, loc.source_root_id, child_id))
103 } 74 }
104 75
105 /// Iterates over all child modules. 76 /// Iterates over all child modules.
106 pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { 77 pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> {
107 // FIXME this should be implementable without collecting into a vec, but 78 let module_tree = db.module_tree(self.krate);
108 // it's kind of hard since the iterator needs to keep a reference to the 79 let children = self
109 // module tree.
110 let loc = self.def_id.loc(db);
111 let module_tree = db.module_tree(loc.source_root_id);
112 let children = loc
113 .module_id 80 .module_id
114 .children(&module_tree) 81 .children(&module_tree)
115 .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) 82 .map(|(_, module_id)| self.with_module_id(module_id))
116 .collect::<Vec<_>>(); 83 .collect::<Vec<_>>();
117 children.into_iter() 84 children.into_iter()
118 } 85 }
119 86
120 pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { 87 pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> {
121 let loc = self.def_id.loc(db); 88 let module_tree = db.module_tree(self.krate);
122 let module_tree = db.module_tree(loc.source_root_id); 89 let parent_id = self.module_id.parent(&module_tree)?;
123 let parent_id = loc.module_id.parent(&module_tree)?; 90 Some(self.with_module_id(parent_id))
124 Some(Module::from_module_id(db, loc.source_root_id, parent_id))
125 } 91 }
126 92
127 /// Returns a `ModuleScope`: a set of items, visible in this module. 93 /// Returns a `ModuleScope`: a set of items, visible in this module.
128 pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { 94 pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope {
129 let loc = self.def_id.loc(db); 95 let item_map = db.item_map(self.krate);
130 let item_map = db.item_map(loc.source_root_id); 96 item_map.per_module[&self.module_id].clone()
131 item_map.per_module[&loc.module_id].clone()
132 } 97 }
133 98
134 pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { 99 pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
135 let mut curr_per_ns = PerNs::types( 100 let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind {
136 match path.kind { 101 PathKind::Crate => self.crate_root(db).into(),
137 PathKind::Crate => self.crate_root(db), 102 PathKind::Self_ | PathKind::Plain => self.clone().into(),
138 PathKind::Self_ | PathKind::Plain => self.clone(), 103 PathKind::Super => {
139 PathKind::Super => { 104 if let Some(p) = self.parent(db) {
140 if let Some(p) = self.parent(db) { 105 p.into()
141 p 106 } else {
142 } else {
143 return PerNs::none();
144 }
145 }
146 PathKind::Abs => {
147 // TODO: absolute use is not supported
148 return PerNs::none(); 107 return PerNs::none();
149 } 108 }
150 } 109 }
151 .def_id, 110 PathKind::Abs => {
152 ); 111 // TODO: absolute use is not supported
112 return PerNs::none();
113 }
114 });
153 115
154 for segment in path.segments.iter() { 116 for segment in path.segments.iter() {
155 let curr = match curr_per_ns.as_ref().take_types() { 117 let curr = match curr_per_ns.as_ref().take_types() {
@@ -164,32 +126,39 @@ impl Module {
164 } 126 }
165 }; 127 };
166 // resolve segment in curr 128 // resolve segment in curr
167 curr_per_ns = match curr.resolve(db) { 129
168 Def::Module(m) => { 130 curr_per_ns = match curr {
131 ModuleDef::Module(m) => {
169 let scope = m.scope(db); 132 let scope = m.scope(db);
170 match scope.get(&segment.name) { 133 match scope.get(&segment.name) {
171 Some(r) => r.def_id, 134 Some(r) => r.def_id.clone(),
172 None => PerNs::none(), 135 None => PerNs::none(),
173 } 136 }
174 } 137 }
175 Def::Enum(e) => { 138 ModuleDef::Def(def) => {
176 // enum variant 139 match def.resolve(db) {
177 let matching_variant = e 140 Def::Enum(e) => {
178 .variants(db) 141 // enum variant
179 .into_iter() 142 let matching_variant = e
180 .find(|(n, _variant)| n == &segment.name); 143 .variants(db)
181 144 .into_iter()
182 match matching_variant { 145 .find(|(n, _variant)| n == &segment.name);
183 Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()), 146
184 None => PerNs::none(), 147 match matching_variant {
148 Some((_n, variant)) => {
149 PerNs::both(variant.def_id().into(), e.def_id().into())
150 }
151 None => PerNs::none(),
152 }
153 }
154 _ => {
155 // could be an inherent method call in UFCS form
156 // (`Struct::method`), or some other kind of associated
157 // item... Which we currently don't handle (TODO)
158 PerNs::none()
159 }
185 } 160 }
186 } 161 }
187 _ => {
188 // could be an inherent method call in UFCS form
189 // (`Struct::method`), or some other kind of associated
190 // item... Which we currently don't handle (TODO)
191 PerNs::none()
192 }
193 }; 162 };
194 } 163 }
195 curr_per_ns 164 curr_per_ns
@@ -199,8 +168,7 @@ impl Module {
199 &self, 168 &self,
200 db: &impl HirDatabase, 169 db: &impl HirDatabase,
201 ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { 170 ) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
202 let loc = self.def_id.loc(db); 171 let module_tree = db.module_tree(self.krate);
203 let module_tree = db.module_tree(loc.source_root_id); 172 self.module_id.problems(&module_tree, db)
204 loc.module_id.problems(&module_tree, db)
205 } 173 }
206} 174}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index cc03da1e2..0898daa3c 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -1,15 +1,15 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; 3use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
4use ra_db::{SourceRootId, SyntaxDatabase, salsa}; 4use ra_db::{SyntaxDatabase, CrateId, salsa};
5 5
6use crate::{ 6use crate::{
7 HirInterner, DefId, MacroCallId, Name, HirFileId, 7 DefId, MacroCallId, Name, HirFileId,
8 SourceFileItems, SourceItemId, Crate, 8 SourceFileItems, SourceItemId, Crate, Module, HirInterner,
9 query_definitions, 9 query_definitions,
10 FnSignature, FnScopes, 10 FnSignature, FnScopes,
11 macros::MacroExpansion, 11 macros::MacroExpansion,
12 module_tree::{ModuleId, ModuleTree}, 12 module_tree::ModuleTree,
13 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, 13 nameres::{ItemMap, lower::{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},
@@ -56,38 +56,22 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
56 fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>; 56 fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>;
57 57
58 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)] 58 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
59 fn lower_module( 59 fn lower_module(&self, module: Module) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
60 &self,
61 source_root_id: SourceRootId,
62 module_id: ModuleId,
63 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
64 60
65 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)] 61 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)]
66 fn lower_module_module( 62 fn lower_module_module(&self, module: Module) -> Arc<LoweredModule>;
67 &self,
68 source_root_id: SourceRootId,
69 module_id: ModuleId,
70 ) -> Arc<LoweredModule>;
71 63
72 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)] 64 #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
73 fn lower_module_source_map( 65 fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>;
74 &self,
75 source_root_id: SourceRootId,
76 module_id: ModuleId,
77 ) -> Arc<ImportSourceMap>;
78 66
79 #[salsa::invoke(query_definitions::item_map)] 67 #[salsa::invoke(query_definitions::item_map)]
80 fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>; 68 fn item_map(&self, crate_id: CrateId) -> Arc<ItemMap>;
81 69
82 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)] 70 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)]
83 fn module_tree(&self, source_root_id: SourceRootId) -> Arc<ModuleTree>; 71 fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>;
84 72
85 #[salsa::invoke(crate::impl_block::impls_in_module)] 73 #[salsa::invoke(crate::impl_block::impls_in_module)]
86 fn impls_in_module( 74 fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
87 &self,
88 source_root_id: SourceRootId,
89 module_id: ModuleId,
90 ) -> Arc<ModuleImplBlocks>;
91 75
92 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 76 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
93 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 77 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 43f0e81f9..99f04e4ef 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -1,11 +1,10 @@
1use ra_db::{SourceRootId, LocationIntener, FileId}; 1use ra_db::{LocationIntener, FileId};
2use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; 2use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast};
3use ra_arena::{Arena, RawId, impl_arena_id}; 3use ra_arena::{Arena, RawId, impl_arena_id};
4 4
5use crate::{ 5use crate::{
6 HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, 6 HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate,
7 Module, Trait, Type, Static, Const, 7 Module, Trait, Type, Static, Const,
8 module_tree::ModuleId,
9}; 8};
10 9
11#[derive(Debug, Default)] 10#[derive(Debug, Default)]
@@ -110,10 +109,9 @@ impl From<MacroCallId> for HirFileId {
110pub struct MacroCallId(RawId); 109pub struct MacroCallId(RawId);
111impl_arena_id!(MacroCallId); 110impl_arena_id!(MacroCallId);
112 111
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
114pub struct MacroCallLoc { 113pub struct MacroCallLoc {
115 pub(crate) source_root_id: SourceRootId, 114 pub(crate) module: Module,
116 pub(crate) module_id: ModuleId,
117 pub(crate) source_item_id: SourceItemId, 115 pub(crate) source_item_id: SourceItemId,
118} 116}
119 117
@@ -139,14 +137,12 @@ impl_arena_id!(DefId);
139#[derive(Clone, Debug, PartialEq, Eq, Hash)] 137#[derive(Clone, Debug, PartialEq, Eq, Hash)]
140pub struct DefLoc { 138pub struct DefLoc {
141 pub(crate) kind: DefKind, 139 pub(crate) kind: DefKind,
142 pub(crate) source_root_id: SourceRootId, 140 pub(crate) module: Module,
143 pub(crate) module_id: ModuleId,
144 pub(crate) source_item_id: SourceItemId, 141 pub(crate) source_item_id: SourceItemId,
145} 142}
146 143
147#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 144#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
148pub(crate) enum DefKind { 145pub(crate) enum DefKind {
149 Module,
150 Function, 146 Function,
151 Struct, 147 Struct,
152 Enum, 148 Enum,
@@ -177,10 +173,6 @@ impl DefId {
177 pub fn resolve(self, db: &impl HirDatabase) -> Def { 173 pub fn resolve(self, db: &impl HirDatabase) -> Def {
178 let loc = self.loc(db); 174 let loc = self.loc(db);
179 match loc.kind { 175 match loc.kind {
180 DefKind::Module => {
181 let module = Module::from_module_id(db, loc.source_root_id, loc.module_id);
182 Def::Module(module)
183 }
184 DefKind::Function => { 176 DefKind::Function => {
185 let function = Function::new(self); 177 let function = Function::new(self);
186 Def::Function(function) 178 Def::Function(function)
@@ -221,8 +213,7 @@ impl DefId {
221 213
222 /// For a module, returns that module; for any other def, returns the containing module. 214 /// For a module, returns that module; for any other def, returns the containing module.
223 pub fn module(self, db: &impl HirDatabase) -> Module { 215 pub fn module(self, db: &impl HirDatabase) -> Module {
224 let loc = self.loc(db); 216 self.loc(db).module
225 Module::from_module_id(db, loc.source_root_id, loc.module_id)
226 } 217 }
227 218
228 /// Returns the containing crate. 219 /// Returns the containing crate.
@@ -232,8 +223,7 @@ impl DefId {
232 223
233 /// Returns the containing impl block, if this is an impl item. 224 /// Returns the containing impl block, if this is an impl item.
234 pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { 225 pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> {
235 let loc = self.loc(db); 226 let module_impls = db.impls_in_module(self.loc(db).module);
236 let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id);
237 ImplBlock::containing(module_impls, self) 227 ImplBlock::containing(module_impls, self)
238 } 228 }
239} 229}
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 551d0d149..ba8b84da2 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -3,14 +3,12 @@ use rustc_hash::FxHashMap;
3 3
4use ra_arena::{Arena, RawId, impl_arena_id}; 4use ra_arena::{Arena, RawId, impl_arena_id};
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast::{self, AstNode};
6use ra_db::{SourceRootId};
7 6
8use crate::{ 7use crate::{
9 DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, 8 DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
10 Function, HirInterner, 9 Function, HirFileId, HirInterner,
11 db::HirDatabase, 10 db::HirDatabase,
12 type_ref::TypeRef, 11 type_ref::TypeRef,
13 module_tree::ModuleId,
14}; 12};
15 13
16use crate::code_model_api::{Module, ModuleSource}; 14use crate::code_model_api::{Module, ModuleSource};
@@ -67,13 +65,13 @@ pub struct ImplData {
67impl ImplData { 65impl ImplData {
68 pub(crate) fn from_ast( 66 pub(crate) fn from_ast(
69 db: &impl AsRef<HirInterner>, 67 db: &impl AsRef<HirInterner>,
68 file_id: HirFileId,
70 file_items: &SourceFileItems, 69 file_items: &SourceFileItems,
71 module: &Module, 70 module: Module,
72 node: &ast::ImplBlock, 71 node: &ast::ImplBlock,
73 ) -> Self { 72 ) -> Self {
74 let target_trait = node.target_trait().map(TypeRef::from_ast); 73 let target_trait = node.target_trait().map(TypeRef::from_ast);
75 let target_type = TypeRef::from_ast_opt(node.target_type()); 74 let target_type = TypeRef::from_ast_opt(node.target_type());
76 let module_loc = module.def_id.loc(db);
77 let items = if let Some(item_list) = node.item_list() { 75 let items = if let Some(item_list) = node.item_list() {
78 item_list 76 item_list
79 .impl_items() 77 .impl_items()
@@ -85,13 +83,13 @@ impl ImplData {
85 }; 83 };
86 let item_id = file_items.id_of_unchecked(item_node.syntax()); 84 let item_id = file_items.id_of_unchecked(item_node.syntax());
87 let source_item_id = SourceItemId { 85 let source_item_id = SourceItemId {
88 file_id: module_loc.source_item_id.file_id, 86 file_id,
89 item_id: Some(item_id), 87 item_id: Some(item_id),
90 }; 88 };
91 let def_loc = DefLoc { 89 let def_loc = DefLoc {
90 module,
92 kind, 91 kind,
93 source_item_id, 92 source_item_id,
94 ..module_loc
95 }; 93 };
96 let def_id = def_loc.id(db); 94 let def_id = def_loc.id(db);
97 match item_node.kind() { 95 match item_node.kind() {
@@ -168,6 +166,7 @@ impl ModuleImplBlocks {
168 166
169 fn collect(&mut self, db: &impl HirDatabase, module: Module) { 167 fn collect(&mut self, db: &impl HirDatabase, module: Module) {
170 let (file_id, module_source) = module.definition_source(db); 168 let (file_id, module_source) = module.definition_source(db);
169 let file_id: HirFileId = file_id.into();
171 let node = match &module_source { 170 let node = match &module_source {
172 ModuleSource::SourceFile(node) => node.syntax(), 171 ModuleSource::SourceFile(node) => node.syntax(),
173 ModuleSource::Module(node) => node 172 ModuleSource::Module(node) => node
@@ -176,10 +175,11 @@ impl ModuleImplBlocks {
176 .syntax(), 175 .syntax(),
177 }; 176 };
178 177
179 let source_file_items = db.file_items(file_id.into()); 178 let source_file_items = db.file_items(file_id);
180 179
181 for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { 180 for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) {
182 let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); 181 let impl_block =
182 ImplData::from_ast(db, file_id, &source_file_items, module, impl_block_ast);
183 let id = self.impls.alloc(impl_block); 183 let id = self.impls.alloc(impl_block);
184 for impl_item in &self.impls[id].items { 184 for impl_item in &self.impls[id].items {
185 self.impls_by_def.insert(impl_item.def_id(), id); 185 self.impls_by_def.insert(impl_item.def_id(), id);
@@ -188,13 +188,8 @@ impl ModuleImplBlocks {
188 } 188 }
189} 189}
190 190
191pub(crate) fn impls_in_module( 191pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
192 db: &impl HirDatabase,
193 source_root_id: SourceRootId,
194 module_id: ModuleId,
195) -> Arc<ModuleImplBlocks> {
196 let mut result = ModuleImplBlocks::new(); 192 let mut result = ModuleImplBlocks::new();
197 let module = Module::from_module_id(db, source_root_id, module_id);
198 result.collect(db, module); 193 result.collect(db, module);
199 Arc::new(result) 194 Arc::new(result)
200} 195}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 87b5a8b8a..a6246a5e9 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -52,7 +52,7 @@ pub use self::{
52pub use self::code_model_api::{ 52pub use self::code_model_api::{
53 Crate, CrateDependency, 53 Crate, CrateDependency,
54 Def, 54 Def,
55 Module, ModuleSource, Problem, 55 Module, ModuleDef, ModuleSource, Problem,
56 Struct, Enum, EnumVariant, 56 Struct, Enum, EnumVariant,
57 Function, FnSignature, ScopeEntryWithSyntax, 57 Function, FnSignature, ScopeEntryWithSyntax,
58 StructField, 58 StructField,
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 4145c8048..361366f6a 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -35,10 +35,6 @@ impl MockDatabase {
35 let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text); 35 let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text);
36 db.query_mut(ra_db::SourceRootQuery) 36 db.query_mut(ra_db::SourceRootQuery)
37 .set(WORKSPACE, Arc::new(source_root.clone())); 37 .set(WORKSPACE, Arc::new(source_root.clone()));
38
39 let mut crate_graph = CrateGraph::default();
40 crate_graph.add_crate_root(file_id);
41 db.set_crate_graph(crate_graph);
42 (db, source_root, file_id) 38 (db, source_root, file_id)
43 } 39 }
44 40
@@ -97,6 +93,8 @@ impl MockDatabase {
97 text: &str, 93 text: &str,
98 ) -> FileId { 94 ) -> FileId {
99 assert!(path.starts_with('/')); 95 assert!(path.starts_with('/'));
96 let is_crate_root = path == "/lib.rs" || path == "/main.rs";
97
100 let path = RelativePathBuf::from_path(&path[1..]).unwrap(); 98 let path = RelativePathBuf::from_path(&path[1..]).unwrap();
101 let file_id = FileId(self.file_counter); 99 let file_id = FileId(self.file_counter);
102 self.file_counter += 1; 100 self.file_counter += 1;
@@ -107,6 +105,12 @@ impl MockDatabase {
107 self.query_mut(ra_db::FileSourceRootQuery) 105 self.query_mut(ra_db::FileSourceRootQuery)
108 .set(file_id, source_root_id); 106 .set(file_id, source_root_id);
109 source_root.files.insert(path, file_id); 107 source_root.files.insert(path, file_id);
108
109 if is_crate_root {
110 let mut crate_graph = CrateGraph::default();
111 crate_graph.add_crate_root(file_id);
112 self.set_crate_graph(crate_graph);
113 }
110 file_id 114 file_id
111 } 115 }
112 116
@@ -202,6 +206,7 @@ salsa::database_storage! {
202 fn file_relative_path() for ra_db::FileRelativePathQuery; 206 fn file_relative_path() for ra_db::FileRelativePathQuery;
203 fn file_source_root() for ra_db::FileSourceRootQuery; 207 fn file_source_root() for ra_db::FileSourceRootQuery;
204 fn source_root() for ra_db::SourceRootQuery; 208 fn source_root() for ra_db::SourceRootQuery;
209 fn source_root_crates() for ra_db::SourceRootCratesQuery;
205 fn local_roots() for ra_db::LocalRootsQuery; 210 fn local_roots() for ra_db::LocalRootsQuery;
206 fn library_roots() for ra_db::LibraryRootsQuery; 211 fn library_roots() for ra_db::LibraryRootsQuery;
207 fn crate_graph() for ra_db::CrateGraphQuery; 212 fn crate_graph() for ra_db::CrateGraphQuery;
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs
index b201bf69b..c00834c4c 100644
--- a/crates/ra_hir/src/module_tree.rs
+++ b/crates/ra_hir/src/module_tree.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::{FxHashMap, FxHashSet};
4use arrayvec::ArrayVec; 4use arrayvec::ArrayVec;
5use relative_path::RelativePathBuf; 5use relative_path::RelativePathBuf;
6use ra_db::{FileId, SourceRootId, SourceRoot}; 6use ra_db::{FileId, SourceRoot, CrateId};
7use ra_syntax::{ 7use ra_syntax::{
8 SyntaxNode, TreeArc, 8 SyntaxNode, TreeArc,
9 algo::generate, 9 algo::generate,
@@ -126,13 +126,10 @@ struct LinkData {
126} 126}
127 127
128impl ModuleTree { 128impl ModuleTree {
129 pub(crate) fn module_tree_query( 129 pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> {
130 db: &impl HirDatabase,
131 source_root: SourceRootId,
132 ) -> Arc<ModuleTree> {
133 db.check_canceled(); 130 db.check_canceled();
134 let mut res = ModuleTree::default(); 131 let mut res = ModuleTree::default();
135 res.init(db, source_root); 132 res.init_crate(db, crate_id);
136 Arc::new(res) 133 Arc::new(res)
137 } 134 }
138 135
@@ -145,24 +142,21 @@ impl ModuleTree {
145 Some(res) 142 Some(res)
146 } 143 }
147 144
148 fn init(&mut self, db: &impl HirDatabase, source_root: SourceRootId) { 145 fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) {
146 let crate_graph = db.crate_graph();
147 let file_id = crate_graph.crate_root(crate_id);
148 let source_root_id = db.file_source_root(file_id);
149
149 let mut roots = FxHashMap::default(); 150 let mut roots = FxHashMap::default();
150 let mut visited = FxHashSet::default(); 151 let mut visited = FxHashSet::default();
151 152
152 let source_root = db.source_root(source_root); 153 let source_root = db.source_root(source_root_id);
153 for &file_id in source_root.files.values() { 154 let source = SourceItemId {
154 let source = SourceItemId { 155 file_id: file_id.into(),
155 file_id: file_id.into(), 156 item_id: None,
156 item_id: None, 157 };
157 }; 158 let module_id = self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
158 if visited.contains(&source) { 159 roots.insert(file_id, module_id);
159 continue; // TODO: use explicit crate_roots here
160 }
161 assert!(!roots.contains_key(&file_id));
162 let module_id =
163 self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
164 roots.insert(file_id, module_id);
165 }
166 } 160 }
167 161
168 fn init_subtree( 162 fn init_subtree(
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 1d163edf7..a3bc98958 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -16,19 +16,19 @@
16//! structure itself is modified. 16//! structure itself is modified.
17pub(crate) mod lower; 17pub(crate) mod lower;
18 18
19use crate::nameres::lower::*;
20
21use std::sync::Arc; 19use std::sync::Arc;
22 20
21use ra_db::CrateId;
23use rustc_hash::{FxHashMap, FxHashSet}; 22use rustc_hash::{FxHashMap, FxHashSet};
24use ra_db::SourceRootId;
25 23
26use crate::{ 24use crate::{
27 DefId, DefLoc, DefKind, 25 Module, ModuleDef,
28 Path, PathKind, 26 Path, PathKind,
29 HirDatabase, Crate, 27 HirDatabase, Crate,
30 Name, 28 Name,
31 module_tree::{ModuleId, ModuleTree}, 29 module_tree::{ModuleId, ModuleTree},
30//FIXME: deglobify
31 nameres::lower::*,
32}; 32};
33 33
34/// `ItemMap` is the result of name resolution. It contains, for each 34/// `ItemMap` is the result of name resolution. It contains, for each
@@ -58,7 +58,7 @@ impl ModuleScope {
58#[derive(Debug, Clone, PartialEq, Eq)] 58#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct Resolution { 59pub struct Resolution {
60 /// None for unresolved 60 /// None for unresolved
61 pub def_id: PerNs<DefId>, 61 pub def_id: PerNs<ModuleDef>,
62 /// ident by which this is imported into local scope. 62 /// ident by which this is imported into local scope.
63 pub import: Option<ImportId>, 63 pub import: Option<ImportId>,
64} 64}
@@ -152,7 +152,7 @@ impl<T> PerNs<T> {
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<LoweredModule>>, 154 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
155 source_root: SourceRootId, 155 krate: CrateId,
156 module_tree: Arc<ModuleTree>, 156 module_tree: Arc<ModuleTree>,
157 processed_imports: FxHashSet<(ModuleId, ImportId)>, 157 processed_imports: FxHashSet<(ModuleId, ImportId)>,
158 result: ItemMap, 158 result: ItemMap,
@@ -165,13 +165,13 @@ where
165 pub(crate) fn new( 165 pub(crate) fn new(
166 db: &'a DB, 166 db: &'a DB,
167 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, 167 input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
168 source_root: SourceRootId, 168 krate: CrateId,
169 module_tree: Arc<ModuleTree>,
170 ) -> Resolver<'a, DB> { 169 ) -> Resolver<'a, DB> {
170 let module_tree = db.module_tree(krate);
171 Resolver { 171 Resolver {
172 db, 172 db,
173 input, 173 input,
174 source_root, 174 krate,
175 module_tree, 175 module_tree,
176 processed_imports: FxHashSet::default(), 176 processed_imports: FxHashSet::default(),
177 result: ItemMap::default(), 177 result: ItemMap::default(),
@@ -210,7 +210,7 @@ where
210 let krate = Crate::new(crate_id); 210 let krate = Crate::new(crate_id);
211 for dep in krate.dependencies(self.db) { 211 for dep in krate.dependencies(self.db) {
212 if let Some(module) = dep.krate.root_module(self.db) { 212 if let Some(module) = dep.krate.root_module(self.db) {
213 let def_id = module.def_id; 213 let def_id = module.into();
214 self.add_module_item( 214 self.add_module_item(
215 &mut module_items, 215 &mut module_items,
216 dep.name.clone(), 216 dep.name.clone(),
@@ -244,20 +244,22 @@ where
244 244
245 // Populate modules 245 // Populate modules
246 for (name, module_id) in module_id.children(&self.module_tree) { 246 for (name, module_id) in module_id.children(&self.module_tree) {
247 let def_loc = DefLoc { 247 let module = Module {
248 kind: DefKind::Module,
249 source_root_id: self.source_root,
250 module_id, 248 module_id,
251 source_item_id: module_id.source(&self.module_tree), 249 krate: self.krate,
252 }; 250 };
253 let def_id = def_loc.id(self.db); 251 self.add_module_item(&mut module_items, name, PerNs::types(module.into()));
254 self.add_module_item(&mut module_items, name, PerNs::types(def_id));
255 } 252 }
256 253
257 self.result.per_module.insert(module_id, module_items); 254 self.result.per_module.insert(module_id, module_items);
258 } 255 }
259 256
260 fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) { 257 fn add_module_item(
258 &self,
259 module_items: &mut ModuleScope,
260 name: Name,
261 def_id: PerNs<ModuleDef>,
262 ) {
261 let resolution = Resolution { 263 let resolution = Resolution {
262 def_id, 264 def_id,
263 import: None, 265 import: None,
@@ -329,17 +331,11 @@ where
329 ); 331 );
330 return false; 332 return false;
331 }; 333 };
332 curr = match type_def_id.loc(self.db) { 334 curr = match type_def_id {
333 DefLoc { 335 ModuleDef::Module(module) => {
334 kind: DefKind::Module, 336 if module.krate == self.krate {
335 module_id: target_module_id, 337 module.module_id
336 source_root_id,
337 ..
338 } => {
339 if source_root_id == self.source_root {
340 target_module_id
341 } else { 338 } else {
342 let module = crate::code_model_api::Module::new(type_def_id);
343 let path = Path { 339 let path = Path {
344 segments: import.path.segments[i + 1..].iter().cloned().collect(), 340 segments: import.path.segments[i + 1..].iter().cloned().collect(),
345 kind: PathKind::Crate, 341 kind: PathKind::Crate,
@@ -359,7 +355,7 @@ where
359 "resolved import {:?} ({:?}) cross-source root to {:?}", 355 "resolved import {:?} ({:?}) cross-source root to {:?}",
360 last_segment.name, 356 last_segment.name,
361 import, 357 import,
362 def_id.map(|did| did.loc(self.db)) 358 def_id,
363 ); 359 );
364 return true; 360 return true;
365 } else { 361 } else {
@@ -372,7 +368,7 @@ where
372 log::debug!( 368 log::debug!(
373 "path segment {:?} resolved to non-module {:?}, but is not last", 369 "path segment {:?} resolved to non-module {:?}, but is not last",
374 segment.name, 370 segment.name,
375 type_def_id.loc(self.db) 371 type_def_id,
376 ); 372 );
377 return true; // this resolved to a non-module, so the path won't ever resolve 373 return true; // this resolved to a non-module, so the path won't ever resolve
378 } 374 }
@@ -382,7 +378,7 @@ where
382 "resolved import {:?} ({:?}) within source root to {:?}", 378 "resolved import {:?} ({:?}) within source root to {:?}",
383 segment.name, 379 segment.name,
384 import, 380 import,
385 def_id.map(|did| did.loc(self.db)) 381 def_id,
386 ); 382 );
387 self.update(module_id, |items| { 383 self.update(module_id, |items| {
388 let res = Resolution { 384 let res = Resolution {
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index 4eea6ff1d..6f003bd66 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -4,14 +4,13 @@ use ra_syntax::{
4 SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, 4 SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr,
5 ast::{self, ModuleItemOwner, NameOwner}, 5 ast::{self, ModuleItemOwner, NameOwner},
6}; 6};
7use ra_db::SourceRootId;
8use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 7use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
9use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
10 9
11use crate::{ 10use crate::{
12 SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, 11 SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems,
13 HirFileId, MacroCallLoc, AsName, PerNs, DefId, DefKind, DefLoc, 12 HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc,
14 module_tree::ModuleId 13 ModuleDef, Module,
15}; 14};
16 15
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -32,7 +31,7 @@ pub(super) struct ImportData {
32/// can avoid redoing name resolution. 31/// can avoid redoing name resolution.
33#[derive(Debug, Default, PartialEq, Eq)] 32#[derive(Debug, Default, PartialEq, Eq)]
34pub struct LoweredModule { 33pub struct LoweredModule {
35 pub(crate) declarations: FxHashMap<Name, PerNs<DefId>>, 34 pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
36 pub(super) imports: Arena<ImportId, ImportData>, 35 pub(super) imports: Arena<ImportId, ImportData>,
37} 36}
38 37
@@ -59,37 +58,31 @@ impl ImportSourceMap {
59impl LoweredModule { 58impl LoweredModule {
60 pub(crate) fn lower_module_module_query( 59 pub(crate) fn lower_module_module_query(
61 db: &impl HirDatabase, 60 db: &impl HirDatabase,
62 source_root_id: SourceRootId, 61 module: Module,
63 module_id: ModuleId,
64 ) -> Arc<LoweredModule> { 62 ) -> Arc<LoweredModule> {
65 db.lower_module(source_root_id, module_id).0 63 db.lower_module(module).0
66 } 64 }
67 65
68 pub(crate) fn lower_module_source_map_query( 66 pub(crate) fn lower_module_source_map_query(
69 db: &impl HirDatabase, 67 db: &impl HirDatabase,
70 source_root_id: SourceRootId, 68 module: Module,
71 module_id: ModuleId,
72 ) -> Arc<ImportSourceMap> { 69 ) -> Arc<ImportSourceMap> {
73 db.lower_module(source_root_id, module_id).1 70 db.lower_module(module).1
74 } 71 }
75 72
76 pub(crate) fn lower_module_query( 73 pub(crate) fn lower_module_query(
77 db: &impl HirDatabase, 74 db: &impl HirDatabase,
78 source_root_id: SourceRootId, 75 module: Module,
79 module_id: ModuleId,
80 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) { 76 ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
81 let module_tree = db.module_tree(source_root_id); 77 let (file_id, source) = module.definition_source(db);
82 let source = module_id.source(&module_tree); 78 let file_id: HirFileId = file_id.into();
83 let file_id = source.file_id;
84 let source = ModuleSource::from_source_item_id(db, source);
85 let mut source_map = ImportSourceMap::default(); 79 let mut source_map = ImportSourceMap::default();
86 let mut res = LoweredModule::default(); 80 let mut res = LoweredModule::default();
87 match source { 81 match source {
88 ModuleSource::SourceFile(it) => res.fill( 82 ModuleSource::SourceFile(it) => res.fill(
89 &mut source_map, 83 &mut source_map,
90 db, 84 db,
91 source_root_id, 85 module,
92 module_id,
93 file_id, 86 file_id,
94 &mut it.items_with_macros(), 87 &mut it.items_with_macros(),
95 ), 88 ),
@@ -98,8 +91,7 @@ impl LoweredModule {
98 res.fill( 91 res.fill(
99 &mut source_map, 92 &mut source_map,
100 db, 93 db,
101 source_root_id, 94 module,
102 module_id,
103 file_id, 95 file_id,
104 &mut item_list.items_with_macros(), 96 &mut item_list.items_with_macros(),
105 ) 97 )
@@ -113,8 +105,7 @@ impl LoweredModule {
113 &mut self, 105 &mut self,
114 source_map: &mut ImportSourceMap, 106 source_map: &mut ImportSourceMap,
115 db: &impl HirDatabase, 107 db: &impl HirDatabase,
116 source_root_id: SourceRootId, 108 module: Module,
117 module_id: ModuleId,
118 file_id: HirFileId, 109 file_id: HirFileId,
119 items: &mut Iterator<Item = ast::ItemOrMacro>, 110 items: &mut Iterator<Item = ast::ItemOrMacro>,
120 ) { 111 ) {
@@ -123,21 +114,12 @@ impl LoweredModule {
123 for item in items { 114 for item in items {
124 match item { 115 match item {
125 ast::ItemOrMacro::Item(it) => { 116 ast::ItemOrMacro::Item(it) => {
126 self.add_def_id( 117 self.add_def_id(source_map, db, module, file_id, &file_items, it);
127 source_map,
128 db,
129 source_root_id,
130 module_id,
131 file_id,
132 &file_items,
133 it,
134 );
135 } 118 }
136 ast::ItemOrMacro::Macro(macro_call) => { 119 ast::ItemOrMacro::Macro(macro_call) => {
137 let item_id = file_items.id_of_unchecked(macro_call.syntax()); 120 let item_id = file_items.id_of_unchecked(macro_call.syntax());
138 let loc = MacroCallLoc { 121 let loc = MacroCallLoc {
139 source_root_id, 122 module,
140 module_id,
141 source_item_id: SourceItemId { 123 source_item_id: SourceItemId {
142 file_id, 124 file_id,
143 item_id: Some(item_id), 125 item_id: Some(item_id),
@@ -148,15 +130,7 @@ impl LoweredModule {
148 let file_items = db.file_items(file_id); 130 let file_items = db.file_items(file_id);
149 //FIXME: expand recursively 131 //FIXME: expand recursively
150 for item in db.hir_source_file(file_id).items() { 132 for item in db.hir_source_file(file_id).items() {
151 self.add_def_id( 133 self.add_def_id(source_map, db, module, file_id, &file_items, item);
152 source_map,
153 db,
154 source_root_id,
155 module_id,
156 file_id,
157 &file_items,
158 item,
159 );
160 } 134 }
161 } 135 }
162 } 136 }
@@ -167,8 +141,7 @@ impl LoweredModule {
167 &mut self, 141 &mut self,
168 source_map: &mut ImportSourceMap, 142 source_map: &mut ImportSourceMap,
169 db: &impl HirDatabase, 143 db: &impl HirDatabase,
170 source_root_id: SourceRootId, 144 module: Module,
171 module_id: ModuleId,
172 file_id: HirFileId, 145 file_id: HirFileId,
173 file_items: &SourceFileItems, 146 file_items: &SourceFileItems,
174 item: &ast::ModuleItem, 147 item: &ast::ModuleItem,
@@ -199,7 +172,7 @@ impl LoweredModule {
199 } 172 }
200 }; 173 };
201 if let Some(name) = name { 174 if let Some(name) = name {
202 let def_id = assign_def_id(db, source_root_id, module_id, file_id, file_items, item); 175 let def_id = assign_def_id(db, module, file_id, file_items, item);
203 self.declarations.insert(name.as_name(), def_id); 176 self.declarations.insert(name.as_name(), def_id);
204 } 177 }
205 } 178 }
@@ -219,12 +192,11 @@ impl LoweredModule {
219 192
220fn assign_def_id( 193fn assign_def_id(
221 db: &impl HirDatabase, 194 db: &impl HirDatabase,
222 source_root_id: SourceRootId, 195 module: Module,
223 module_id: ModuleId,
224 file_id: HirFileId, 196 file_id: HirFileId,
225 file_items: &SourceFileItems, 197 file_items: &SourceFileItems,
226 item: &ast::ModuleItem, 198 item: &ast::ModuleItem,
227) -> PerNs<DefId> { 199) -> PerNs<ModuleDef> {
228 // depending on the item kind, the location can define something in 200 // depending on the item kind, the location can define something in
229 // the values namespace, the types namespace, or both 201 // the values namespace, the types namespace, or both
230 let kind = DefKind::for_syntax_kind(item.syntax().kind()); 202 let kind = DefKind::for_syntax_kind(item.syntax().kind());
@@ -232,14 +204,13 @@ fn assign_def_id(
232 let item_id = file_items.id_of_unchecked(item.syntax()); 204 let item_id = file_items.id_of_unchecked(item.syntax());
233 let def_loc = DefLoc { 205 let def_loc = DefLoc {
234 kind: k, 206 kind: k,
235 source_root_id, 207 module,
236 module_id,
237 source_item_id: SourceItemId { 208 source_item_id: SourceItemId {
238 file_id, 209 file_id,
239 item_id: Some(item_id), 210 item_id: Some(item_id),
240 }, 211 },
241 }; 212 };
242 def_loc.id(db) 213 def_loc.id(db).into()
243 }); 214 });
244 def_id 215 def_id
245} 216}
@@ -248,7 +219,6 @@ impl DefKind {
248 fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { 219 fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
249 match kind { 220 match kind {
250 SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), 221 SyntaxKind::FN_DEF => PerNs::values(DefKind::Function),
251 SyntaxKind::MODULE => PerNs::types(DefKind::Module),
252 SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), 222 SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor),
253 SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), 223 SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum),
254 SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), 224 SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait),
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index e92007453..9322bf08c 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -1,6 +1,6 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::{FilesDatabase, CrateGraph, SourceRootId, salsa::Database}; 3use ra_db::{CrateGraph, SourceRootId, salsa::Database};
4use relative_path::RelativePath; 4use relative_path::RelativePath;
5use test_utils::{assert_eq_text, covers}; 5use test_utils::{assert_eq_text, covers};
6 6
@@ -13,10 +13,10 @@ use crate::{
13 13
14fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { 14fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
15 let (db, pos) = MockDatabase::with_position(fixture); 15 let (db, pos) = MockDatabase::with_position(fixture);
16 let source_root = db.file_source_root(pos.file_id);
17 let module = crate::source_binder::module_from_position(&db, pos).unwrap(); 16 let module = crate::source_binder::module_from_position(&db, pos).unwrap();
18 let module_id = module.def_id.loc(&db).module_id; 17 let krate = module.krate(&db).unwrap();
19 (db.item_map(source_root), module_id) 18 let module_id = module.module_id;
19 (db.item_map(krate.crate_id), module_id)
20} 20}
21 21
22fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { 22fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) {
@@ -238,14 +238,13 @@ fn item_map_across_crates() {
238 238
239 db.set_crate_graph(crate_graph); 239 db.set_crate_graph(crate_graph);
240 240
241 let source_root = db.file_source_root(main_id);
242 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 241 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
243 let module_id = module.def_id.loc(&db).module_id; 242 let krate = module.krate(&db).unwrap();
244 let item_map = db.item_map(source_root); 243 let item_map = db.item_map(krate.crate_id);
245 244
246 check_module_item_map( 245 check_module_item_map(
247 &item_map, 246 &item_map,
248 module_id, 247 module.module_id,
249 " 248 "
250 Baz: t v 249 Baz: t v
251 test_crate: t 250 test_crate: t
@@ -292,12 +291,12 @@ fn import_across_source_roots() {
292 db.set_crate_graph(crate_graph); 291 db.set_crate_graph(crate_graph);
293 292
294 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 293 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
295 let module_id = module.def_id.loc(&db).module_id; 294 let krate = module.krate(&db).unwrap();
296 let item_map = db.item_map(source_root); 295 let item_map = db.item_map(krate.crate_id);
297 296
298 check_module_item_map( 297 check_module_item_map(
299 &item_map, 298 &item_map,
300 module_id, 299 module.module_id,
301 " 300 "
302 C: t v 301 C: t v
303 test_crate: t 302 test_crate: t
@@ -333,14 +332,13 @@ fn reexport_across_crates() {
333 332
334 db.set_crate_graph(crate_graph); 333 db.set_crate_graph(crate_graph);
335 334
336 let source_root = db.file_source_root(main_id);
337 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); 335 let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
338 let module_id = module.def_id.loc(&db).module_id; 336 let krate = module.krate(&db).unwrap();
339 let item_map = db.item_map(source_root); 337 let item_map = db.item_map(krate.crate_id);
340 338
341 check_module_item_map( 339 check_module_item_map(
342 &item_map, 340 &item_map,
343 module_id, 341 module.module_id,
344 " 342 "
345 Baz: t v 343 Baz: t v
346 test_crate: t 344 test_crate: t
@@ -350,10 +348,11 @@ fn reexport_across_crates() {
350 348
351fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { 349fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
352 let (mut db, pos) = MockDatabase::with_position(initial); 350 let (mut db, pos) = MockDatabase::with_position(initial);
353 let source_root = db.file_source_root(pos.file_id); 351 let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
352 let krate = module.krate(&db).unwrap();
354 { 353 {
355 let events = db.log_executed(|| { 354 let events = db.log_executed(|| {
356 db.item_map(source_root); 355 db.item_map(krate.crate_id);
357 }); 356 });
358 assert!(format!("{:?}", events).contains("item_map")) 357 assert!(format!("{:?}", events).contains("item_map"))
359 } 358 }
@@ -362,7 +361,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
362 361
363 { 362 {
364 let events = db.log_executed(|| { 363 let events = db.log_executed(|| {
365 db.item_map(source_root); 364 db.item_map(krate.crate_id);
366 }); 365 });
367 assert!( 366 assert!(
368 !format!("{:?}", events).contains("item_map"), 367 !format!("{:?}", events).contains("item_map"),
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index 074153862..a8ed887b3 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -7,11 +7,11 @@ use rustc_hash::FxHashMap;
7use ra_syntax::{ 7use ra_syntax::{
8 AstNode, SyntaxNode, TreeArc, 8 AstNode, SyntaxNode, TreeArc,
9}; 9};
10use ra_db::SourceRootId; 10use ra_db::{CrateId};
11 11
12use crate::{ 12use crate::{
13 SourceFileItems, SourceItemId, DefId, HirFileId, 13 SourceFileItems, SourceItemId, DefId, HirFileId,
14 FnScopes, 14 FnScopes, Module,
15 db::HirDatabase, 15 db::HirDatabase,
16 nameres::{ItemMap, Resolver}, 16 nameres::{ItemMap, Resolver},
17}; 17};
@@ -41,15 +41,23 @@ pub(super) fn file_item(
41 } 41 }
42} 42}
43 43
44pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> { 44pub(super) fn item_map(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ItemMap> {
45 let start = Instant::now(); 45 let start = Instant::now();
46 let module_tree = db.module_tree(source_root); 46 let module_tree = db.module_tree(crate_id);
47 let input = module_tree 47 let input = module_tree
48 .modules() 48 .modules()
49 .map(|id| (id, db.lower_module_module(source_root, id))) 49 .map(|module_id| {
50 (
51 module_id,
52 db.lower_module_module(Module {
53 krate: crate_id,
54 module_id,
55 }),
56 )
57 })
50 .collect::<FxHashMap<_, _>>(); 58 .collect::<FxHashMap<_, _>>();
51 59
52 let resolver = Resolver::new(db, &input, source_root, module_tree); 60 let resolver = Resolver::new(db, &input, crate_id);
53 let res = resolver.resolve(); 61 let res = resolver.resolve();
54 let elapsed = start.elapsed(); 62 let elapsed = start.elapsed();
55 log::info!("item_map: {:?}", elapsed); 63 log::info!("item_map: {:?}", elapsed);
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index bde0be37b..c3bd31d6b 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,7 +13,7 @@ use ra_syntax::{
13}; 13};
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Function, SourceItemId, 16 HirDatabase, Function, SourceItemId, ModuleDef,
17 DefKind, DefLoc, AsName, Module, 17 DefKind, DefLoc, AsName, Module,
18}; 18};
19 19
@@ -84,9 +84,13 @@ pub fn module_from_child_node(
84 84
85fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> { 85fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> {
86 let source_root_id = db.file_source_root(source.file_id.as_original_file()); 86 let source_root_id = db.file_source_root(source.file_id.as_original_file());
87 let module_tree = db.module_tree(source_root_id); 87 db.source_root_crates(source_root_id)
88 let module_id = module_tree.find_module_by_source(source)?; 88 .iter()
89 Some(Module::from_module_id(db, source_root_id, module_id)) 89 .find_map(|&krate| {
90 let module_tree = db.module_tree(krate);
91 let module_id = module_tree.find_module_by_source(source)?;
92 Some(Module { krate, module_id })
93 })
90} 94}
91 95
92pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { 96pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> {
@@ -110,8 +114,8 @@ pub fn function_from_module(
110 module: &Module, 114 module: &Module,
111 fn_def: &ast::FnDef, 115 fn_def: &ast::FnDef,
112) -> Function { 116) -> Function {
113 let loc = module.def_id.loc(db); 117 let (file_id, _) = module.definition_source(db);
114 let file_id = loc.source_item_id.file_id; 118 let file_id = file_id.into();
115 let file_items = db.file_items(file_id); 119 let file_items = db.file_items(file_id);
116 let item_id = file_items.id_of(file_id, fn_def.syntax()); 120 let item_id = file_items.id_of(file_id, fn_def.syntax());
117 let source_item_id = SourceItemId { 121 let source_item_id = SourceItemId {
@@ -119,9 +123,8 @@ pub fn function_from_module(
119 item_id: Some(item_id), 123 item_id: Some(item_id),
120 }; 124 };
121 let def_loc = DefLoc { 125 let def_loc = DefLoc {
126 module: module.clone(),
122 kind: DefKind::Function, 127 kind: DefKind::Function,
123 source_root_id: loc.source_root_id,
124 module_id: loc.module_id,
125 source_item_id, 128 source_item_id,
126 }; 129 };
127 Function::new(def_loc.id(db)) 130 Function::new(def_loc.id(db))
@@ -141,14 +144,17 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
141 Some(it) => it, 144 Some(it) => it,
142 None => return Vec::new(), 145 None => return Vec::new(),
143 }; 146 };
144 let loc = module.def_id.loc(db); 147 let items = db.lower_module_module(module);
145 let items = db.lower_module_module(loc.source_root_id, loc.module_id);
146 let mut res = Vec::new(); 148 let mut res = Vec::new();
147 149
148 for macro_call_id in items 150 for macro_call_id in items
149 .declarations 151 .declarations
150 .iter() 152 .iter()
151 .filter_map(|(_, it)| it.take_types()) 153 .filter_map(|(_, it)| it.clone().take_types())
154 .filter_map(|it| match it {
155 ModuleDef::Def(it) => Some(it),
156 _ => None,
157 })
152 .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id()) 158 .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id())
153 { 159 {
154 if let Some(exp) = db.expand_macro_invocation(macro_call_id) { 160 if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index e690ae158..4c96579ee 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -32,7 +32,7 @@ use rustc_hash::FxHashMap;
32 32
33use crate::{ 33use crate::{
34 Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, 34 Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
35 FnSignature, FnScopes, 35 FnSignature, FnScopes, ModuleDef,
36 db::HirDatabase, 36 db::HirDatabase,
37 type_ref::{TypeRef, Mutability}, 37 type_ref::{TypeRef, Mutability},
38 name::KnownName, 38 name::KnownName,
@@ -382,8 +382,8 @@ impl Ty {
382 382
383 // Resolve in module (in type namespace) 383 // Resolve in module (in type namespace)
384 let resolved = match module.resolve_path(db, path).take_types() { 384 let resolved = match module.resolve_path(db, path).take_types() {
385 Some(r) => r, 385 Some(ModuleDef::Def(r)) => r,
386 None => return Ty::Unknown, 386 None | Some(ModuleDef::Module(_)) => return Ty::Unknown,
387 }; 387 };
388 let ty = db.type_for_def(resolved); 388 let ty = db.type_for_def(resolved);
389 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); 389 let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved);
@@ -663,10 +663,6 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
663pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { 663pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty {
664 let def = def_id.resolve(db); 664 let def = def_id.resolve(db);
665 match def { 665 match def {
666 Def::Module(..) => {
667 log::debug!("trying to get type for module {:?}", def_id);
668 Ty::Unknown
669 }
670 Def::Function(f) => type_for_fn(db, f), 666 Def::Function(f) => type_for_fn(db, f),
671 Def::Struct(s) => type_for_struct(db, s), 667 Def::Struct(s) => type_for_struct(db, s),
672 Def::Enum(e) => type_for_enum(db, e), 668 Def::Enum(e) => type_for_enum(db, e),
@@ -1063,7 +1059,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1063 }; 1059 };
1064 1060
1065 // resolve in module 1061 // resolve in module
1066 let resolved = self.module.resolve_path(self.db, &path).take_values()?; 1062 let resolved = match self.module.resolve_path(self.db, &path).take_values()? {
1063 ModuleDef::Def(it) => it,
1064 ModuleDef::Module(_) => return None,
1065 };
1067 let ty = self.db.type_for_def(resolved); 1066 let ty = self.db.type_for_def(resolved);
1068 let ty = self.insert_type_vars(ty); 1067 let ty = self.insert_type_vars(ty);
1069 Some(ty) 1068 Some(ty)
@@ -1075,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1075 None => return (Ty::Unknown, None), 1074 None => return (Ty::Unknown, None),
1076 }; 1075 };
1077 let def_id = match self.module.resolve_path(self.db, &path).take_types() { 1076 let def_id = match self.module.resolve_path(self.db, &path).take_types() {
1078 Some(def_id) => def_id, 1077 Some(ModuleDef::Def(def_id)) => def_id,
1079 _ => return (Ty::Unknown, None), 1078 _ => return (Ty::Unknown, None),
1080 }; 1079 };
1081 // TODO remove the duplication between here and `Ty::from_path`? 1080 // TODO remove the duplication between here and `Ty::from_path`?
@@ -1216,6 +1215,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1216 .module 1215 .module
1217 .resolve_path(self.db, &path) 1216 .resolve_path(self.db, &path)
1218 .take_values() 1217 .take_values()
1218 .and_then(|module_def| match module_def {
1219 ModuleDef::Def(it) => Some(it),
1220 ModuleDef::Module(_) => None,
1221 })
1219 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), 1222 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
1220 Pat::Bind { 1223 Pat::Bind {
1221 mode, 1224 mode,
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9f65c5fe1..a5567a78f 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -6,8 +6,6 @@ use std::sync::Arc;
6 6
7use rustc_hash::FxHashMap; 7use rustc_hash::FxHashMap;
8 8
9use ra_db::SourceRootId;
10
11use crate::{ 9use crate::{
12 HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, 10 HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function,
13 impl_block::{ImplId, ImplBlock, ImplItem}, 11 impl_block::{ImplId, ImplBlock, ImplItem},
@@ -37,7 +35,7 @@ impl TyFingerprint {
37#[derive(Debug, PartialEq, Eq)] 35#[derive(Debug, PartialEq, Eq)]
38pub struct CrateImplBlocks { 36pub struct CrateImplBlocks {
39 /// To make sense of the ModuleIds, we need the source root. 37 /// To make sense of the ModuleIds, we need the source root.
40 source_root_id: SourceRootId, 38 krate: Crate,
41 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>, 39 impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>,
42} 40}
43 41
@@ -53,14 +51,17 @@ impl CrateImplBlocks {
53 .into_iter() 51 .into_iter()
54 .flat_map(|i| i.iter()) 52 .flat_map(|i| i.iter())
55 .map(move |(module_id, impl_id)| { 53 .map(move |(module_id, impl_id)| {
56 let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); 54 let module = Module {
55 krate: self.krate.crate_id,
56 module_id: *module_id,
57 };
58 let module_impl_blocks = db.impls_in_module(module);
57 ImplBlock::from_id(module_impl_blocks, *impl_id) 59 ImplBlock::from_id(module_impl_blocks, *impl_id)
58 }) 60 })
59 } 61 }
60 62
61 fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { 63 fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
62 let module_id = module.def_id.loc(db).module_id; 64 let module_impl_blocks = db.impls_in_module(module.clone());
63 let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id);
64 65
65 for (impl_id, impl_data) in module_impl_blocks.impls.iter() { 66 for (impl_id, impl_data) in module_impl_blocks.impls.iter() {
66 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); 67 let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
@@ -81,13 +82,13 @@ impl CrateImplBlocks {
81 self.impls 82 self.impls
82 .entry(target_ty_fp) 83 .entry(target_ty_fp)
83 .or_insert_with(Vec::new) 84 .or_insert_with(Vec::new)
84 .push((module_id, impl_id)); 85 .push((module.module_id, impl_id));
85 } 86 }
86 } 87 }
87 } 88 }
88 89
89 for child in module.children(db) { 90 for child in module.children(db) {
90 self.collect_recursive(db, child); 91 self.collect_recursive(db, &child);
91 } 92 }
92 } 93 }
93 94
@@ -95,15 +96,12 @@ impl CrateImplBlocks {
95 db: &impl HirDatabase, 96 db: &impl HirDatabase,
96 krate: Crate, 97 krate: Crate,
97 ) -> Arc<CrateImplBlocks> { 98 ) -> Arc<CrateImplBlocks> {
98 let crate_graph = db.crate_graph();
99 let file_id = crate_graph.crate_root(krate.crate_id);
100 let source_root_id = db.file_source_root(file_id);
101 let mut crate_impl_blocks = CrateImplBlocks { 99 let mut crate_impl_blocks = CrateImplBlocks {
102 source_root_id, 100 krate: krate.clone(),
103 impls: FxHashMap::default(), 101 impls: FxHashMap::default(),
104 }; 102 };
105 if let Some(module) = krate.root_module(db) { 103 if let Some(module) = krate.root_module(db) {
106 crate_impl_blocks.collect_recursive(db, module); 104 crate_impl_blocks.collect_recursive(db, &module);
107 } 105 }
108 Arc::new(crate_impl_blocks) 106 Arc::new(crate_impl_blocks)
109 } 107 }