aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock13
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs93
-rw-r--r--crates/ra_hir/src/code_model/src.rs30
-rw-r--r--crates/ra_hir/src/db.rs40
-rw-r--r--crates/ra_hir/src/from_source.rs4
-rw-r--r--crates/ra_hir/src/ids.rs167
-rw-r--r--crates/ra_hir/src/impl_block.rs4
-rw-r--r--crates/ra_hir/src/lang_item.rs16
-rw-r--r--crates/ra_hir/src/nameres.rs36
-rw-r--r--crates/ra_hir/src/nameres/collector.rs25
-rw-r--r--crates/ra_hir/src/resolve.rs17
-rw-r--r--crates/ra_hir/src/source_binder.rs2
-rw-r--r--crates/ra_hir/src/traits.rs2
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs12
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs38
-rw-r--r--crates/ra_hir_def/Cargo.toml14
-rw-r--r--crates/ra_hir_def/src/db.rs22
-rw-r--r--crates/ra_hir_def/src/lib.rs216
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs2
-rw-r--r--crates/ra_ide_api/src/impls.rs4
-rw-r--r--crates/ra_ide_api/src/parent_module.rs5
-rw-r--r--crates/ra_ide_api/src/references/search_scope.rs2
23 files changed, 402 insertions, 363 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c7ec98226..66ff1285a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1003,6 +1003,7 @@ dependencies = [
1003 "ra_arena 0.1.0", 1003 "ra_arena 0.1.0",
1004 "ra_cfg 0.1.0", 1004 "ra_cfg 0.1.0",
1005 "ra_db 0.1.0", 1005 "ra_db 0.1.0",
1006 "ra_hir_def 0.1.0",
1006 "ra_hir_expand 0.1.0", 1007 "ra_hir_expand 0.1.0",
1007 "ra_mbe 0.1.0", 1008 "ra_mbe 0.1.0",
1008 "ra_prof 0.1.0", 1009 "ra_prof 0.1.0",
@@ -1014,6 +1015,18 @@ dependencies = [
1014] 1015]
1015 1016
1016[[package]] 1017[[package]]
1018name = "ra_hir_def"
1019version = "0.1.0"
1020dependencies = [
1021 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1022 "ra_arena 0.1.0",
1023 "ra_db 0.1.0",
1024 "ra_hir_expand 0.1.0",
1025 "ra_prof 0.1.0",
1026 "ra_syntax 0.1.0",
1027]
1028
1029[[package]]
1017name = "ra_hir_expand" 1030name = "ra_hir_expand"
1018version = "0.1.0" 1031version = "0.1.0"
1019dependencies = [ 1032dependencies = [
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index 143dae6bd..5df371bc0 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -20,6 +20,7 @@ ra_db = { path = "../ra_db" }
20mbe = { path = "../ra_mbe", package = "ra_mbe" } 20mbe = { path = "../ra_mbe", package = "ra_mbe" }
21tt = { path = "../ra_tt", package = "ra_tt" } 21tt = { path = "../ra_tt", package = "ra_tt" }
22hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 22hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
23hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
23test_utils = { path = "../test_utils" } 24test_utils = { path = "../test_utils" }
24ra_prof = { path = "../ra_prof" } 25ra_prof = { path = "../ra_prof" }
25 26
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 8eb3c577d..1a790b2f3 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -5,6 +5,7 @@ pub(crate) mod docs;
5 5
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use hir_def::{CrateModuleId, ModuleId};
8use ra_db::{CrateId, Edition, FileId}; 9use ra_db::{CrateId, Edition, FileId};
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 10use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
10 11
@@ -23,7 +24,7 @@ use crate::{
23 BOOL, CHAR, F32, F64, I128, I16, I32, I64, I8, ISIZE, SELF_TYPE, STR, U128, U16, U32, U64, 24 BOOL, CHAR, F32, F64, I128, I16, I32, I64, I8, ISIZE, SELF_TYPE, STR, U128, U16, U32, U64,
24 U8, USIZE, 25 U8, USIZE,
25 }, 26 },
26 nameres::{CrateModuleId, ImportId, ModuleScope, Namespace}, 27 nameres::{ImportId, ModuleScope, Namespace},
27 resolve::{Resolver, Scope, TypeNs}, 28 resolve::{Resolver, Scope, TypeNs},
28 traits::TraitData, 29 traits::TraitData,
29 ty::{ 30 ty::{
@@ -67,8 +68,7 @@ impl Crate {
67 68
68 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { 69 pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> {
69 let module_id = db.crate_def_map(self).root(); 70 let module_id = db.crate_def_map(self).root();
70 let module = Module { krate: self, module_id }; 71 Some(Module::new(self, module_id))
71 Some(module)
72 } 72 }
73 73
74 pub fn edition(self, db: &impl DefDatabase) -> Edition { 74 pub fn edition(self, db: &impl DefDatabase) -> Edition {
@@ -83,8 +83,7 @@ impl Crate {
83 83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub struct Module { 85pub struct Module {
86 pub(crate) krate: Crate, 86 pub(crate) id: ModuleId,
87 pub(crate) module_id: CrateModuleId,
88} 87}
89 88
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 89#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -175,12 +174,16 @@ impl ModuleSource {
175} 174}
176 175
177impl Module { 176impl Module {
177 pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module {
178 Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } }
179 }
180
178 /// Name of this module. 181 /// Name of this module.
179 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 182 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
180 let def_map = db.crate_def_map(self.krate); 183 let def_map = db.crate_def_map(self.krate());
181 let parent = def_map[self.module_id].parent?; 184 let parent = def_map[self.id.module_id].parent?;
182 def_map[parent].children.iter().find_map(|(name, module_id)| { 185 def_map[parent].children.iter().find_map(|(name, module_id)| {
183 if *module_id == self.module_id { 186 if *module_id == self.id.module_id {
184 Some(name.clone()) 187 Some(name.clone())
185 } else { 188 } else {
186 None 189 None
@@ -200,29 +203,29 @@ impl Module {
200 } 203 }
201 204
202 /// Returns the crate this module is part of. 205 /// Returns the crate this module is part of.
203 pub fn krate(self, _db: &impl DefDatabase) -> Option<Crate> { 206 pub fn krate(self) -> Crate {
204 Some(self.krate) 207 Crate { crate_id: self.id.krate }
205 } 208 }
206 209
207 /// Topmost parent of this module. Every module has a `crate_root`, but some 210 /// Topmost parent of this module. Every module has a `crate_root`, but some
208 /// might be missing `krate`. This can happen if a module's file is not included 211 /// might be missing `krate`. This can happen if a module's file is not included
209 /// in the module tree of any target in `Cargo.toml`. 212 /// in the module tree of any target in `Cargo.toml`.
210 pub fn crate_root(self, db: &impl DefDatabase) -> Module { 213 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
211 let def_map = db.crate_def_map(self.krate); 214 let def_map = db.crate_def_map(self.krate());
212 self.with_module_id(def_map.root()) 215 self.with_module_id(def_map.root())
213 } 216 }
214 217
215 /// Finds a child module with the specified name. 218 /// Finds a child module with the specified name.
216 pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> { 219 pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
217 let def_map = db.crate_def_map(self.krate); 220 let def_map = db.crate_def_map(self.krate());
218 let child_id = def_map[self.module_id].children.get(name)?; 221 let child_id = def_map[self.id.module_id].children.get(name)?;
219 Some(self.with_module_id(*child_id)) 222 Some(self.with_module_id(*child_id))
220 } 223 }
221 224
222 /// Iterates over all child modules. 225 /// Iterates over all child modules.
223 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { 226 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
224 let def_map = db.crate_def_map(self.krate); 227 let def_map = db.crate_def_map(self.krate());
225 let children = def_map[self.module_id] 228 let children = def_map[self.id.module_id]
226 .children 229 .children
227 .iter() 230 .iter()
228 .map(|(_, module_id)| self.with_module_id(*module_id)) 231 .map(|(_, module_id)| self.with_module_id(*module_id))
@@ -232,8 +235,8 @@ impl Module {
232 235
233 /// Finds a parent module. 236 /// Finds a parent module.
234 pub fn parent(self, db: &impl DefDatabase) -> Option<Module> { 237 pub fn parent(self, db: &impl DefDatabase) -> Option<Module> {
235 let def_map = db.crate_def_map(self.krate); 238 let def_map = db.crate_def_map(self.krate());
236 let parent_id = def_map[self.module_id].parent?; 239 let parent_id = def_map[self.id.module_id].parent?;
237 Some(self.with_module_id(parent_id)) 240 Some(self.with_module_id(parent_id))
238 } 241 }
239 242
@@ -249,11 +252,11 @@ impl Module {
249 252
250 /// Returns a `ModuleScope`: a set of items, visible in this module. 253 /// Returns a `ModuleScope`: a set of items, visible in this module.
251 pub fn scope(self, db: &impl HirDatabase) -> ModuleScope { 254 pub fn scope(self, db: &impl HirDatabase) -> ModuleScope {
252 db.crate_def_map(self.krate)[self.module_id].scope.clone() 255 db.crate_def_map(self.krate())[self.id.module_id].scope.clone()
253 } 256 }
254 257
255 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 258 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
256 db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); 259 db.crate_def_map(self.krate()).add_diagnostics(db, self.id.module_id, sink);
257 for decl in self.declarations(db) { 260 for decl in self.declarations(db) {
258 match decl { 261 match decl {
259 crate::ModuleDef::Function(f) => f.diagnostics(db, sink), 262 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
@@ -277,13 +280,13 @@ impl Module {
277 } 280 }
278 281
279 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { 282 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
280 let def_map = db.crate_def_map(self.krate); 283 let def_map = db.crate_def_map(self.krate());
281 Resolver::default().push_module_scope(def_map, self.module_id) 284 Resolver::default().push_module_scope(def_map, self.id.module_id)
282 } 285 }
283 286
284 pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { 287 pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> {
285 let def_map = db.crate_def_map(self.krate); 288 let def_map = db.crate_def_map(self.krate());
286 def_map[self.module_id] 289 def_map[self.id.module_id]
287 .scope 290 .scope
288 .entries() 291 .entries()
289 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) 292 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
@@ -303,7 +306,7 @@ impl Module {
303 } 306 }
304 307
305 fn with_module_id(self, module_id: CrateModuleId) -> Module { 308 fn with_module_id(self, module_id: CrateModuleId) -> Module {
306 Module { module_id, krate: self.krate } 309 Module::new(self.krate(), module_id)
307 } 310 }
308} 311}
309 312
@@ -340,11 +343,11 @@ pub struct Struct {
340 343
341impl Struct { 344impl Struct {
342 pub fn module(self, db: &impl DefDatabase) -> Module { 345 pub fn module(self, db: &impl DefDatabase) -> Module {
343 self.id.module(db) 346 Module { id: self.id.module(db) }
344 } 347 }
345 348
346 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 349 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
347 self.module(db).krate(db) 350 Some(self.module(db).krate())
348 } 351 }
349 352
350 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 353 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
@@ -402,7 +405,7 @@ impl Union {
402 } 405 }
403 406
404 pub fn module(self, db: &impl HirDatabase) -> Module { 407 pub fn module(self, db: &impl HirDatabase) -> Module {
405 self.id.module(db) 408 Module { id: self.id.module(db) }
406 } 409 }
407 410
408 pub fn ty(self, db: &impl HirDatabase) -> Ty { 411 pub fn ty(self, db: &impl HirDatabase) -> Ty {
@@ -428,11 +431,11 @@ pub struct Enum {
428 431
429impl Enum { 432impl Enum {
430 pub fn module(self, db: &impl DefDatabase) -> Module { 433 pub fn module(self, db: &impl DefDatabase) -> Module {
431 self.id.module(db) 434 Module { id: self.id.module(db) }
432 } 435 }
433 436
434 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 437 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
435 self.module(db).krate(db) 438 Some(self.module(db).krate())
436 } 439 }
437 440
438 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 441 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
@@ -523,12 +526,14 @@ impl Adt {
523 } 526 }
524 527
525 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> { 528 pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
526 match self { 529 Some(
527 Adt::Struct(s) => s.module(db), 530 match self {
528 Adt::Union(s) => s.module(db), 531 Adt::Struct(s) => s.module(db),
529 Adt::Enum(e) => e.module(db), 532 Adt::Union(s) => s.module(db),
530 } 533 Adt::Enum(e) => e.module(db),
531 .krate(db) 534 }
535 .krate(),
536 )
532 } 537 }
533 538
534 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { 539 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
@@ -692,11 +697,11 @@ impl FnData {
692 697
693impl Function { 698impl Function {
694 pub fn module(self, db: &impl DefDatabase) -> Module { 699 pub fn module(self, db: &impl DefDatabase) -> Module {
695 self.id.module(db) 700 Module { id: self.id.module(db) }
696 } 701 }
697 702
698 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 703 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
699 self.module(db).krate(db) 704 Some(self.module(db).krate())
700 } 705 }
701 706
702 pub fn name(self, db: &impl HirDatabase) -> Name { 707 pub fn name(self, db: &impl HirDatabase) -> Name {
@@ -770,11 +775,11 @@ pub struct Const {
770 775
771impl Const { 776impl Const {
772 pub fn module(self, db: &impl DefDatabase) -> Module { 777 pub fn module(self, db: &impl DefDatabase) -> Module {
773 self.id.module(db) 778 Module { id: self.id.module(db) }
774 } 779 }
775 780
776 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 781 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
777 self.module(db).krate(db) 782 Some(self.module(db).krate())
778 } 783 }
779 784
780 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { 785 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
@@ -867,11 +872,11 @@ pub struct Static {
867 872
868impl Static { 873impl Static {
869 pub fn module(self, db: &impl DefDatabase) -> Module { 874 pub fn module(self, db: &impl DefDatabase) -> Module {
870 self.id.module(db) 875 Module { id: self.id.module(db) }
871 } 876 }
872 877
873 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 878 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
874 self.module(db).krate(db) 879 Some(self.module(db).krate())
875 } 880 }
876 881
877 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { 882 pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> {
@@ -896,7 +901,7 @@ pub struct Trait {
896 901
897impl Trait { 902impl Trait {
898 pub fn module(self, db: &impl DefDatabase) -> Module { 903 pub fn module(self, db: &impl DefDatabase) -> Module {
899 self.id.module(db) 904 Module { id: self.id.module(db) }
900 } 905 }
901 906
902 pub fn name(self, db: &impl DefDatabase) -> Option<Name> { 907 pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
@@ -998,11 +1003,11 @@ pub struct TypeAlias {
998 1003
999impl TypeAlias { 1004impl TypeAlias {
1000 pub fn module(self, db: &impl DefDatabase) -> Module { 1005 pub fn module(self, db: &impl DefDatabase) -> Module {
1001 self.id.module(db) 1006 Module { id: self.id.module(db) }
1002 } 1007 }
1003 1008
1004 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 1009 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
1005 self.module(db).krate(db) 1010 Some(self.module(db).krate())
1006 } 1011 }
1007 1012
1008 /// The containing impl block, if this is a method. 1013 /// The containing impl block, if this is a method.
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index fdae26906..5c7f61eef 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -1,9 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use ra_syntax::{ 3use ra_syntax::ast::{self, AstNode};
4 ast::{self, AstNode},
5 SyntaxNode,
6};
7 4
8use crate::{ 5use crate::{
9 db::{AstDatabase, DefDatabase, HirDatabase}, 6 db::{AstDatabase, DefDatabase, HirDatabase},
@@ -12,34 +9,21 @@ use crate::{
12 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, 9 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
13}; 10};
14 11
15#[derive(Debug, PartialEq, Eq, Clone, Copy)] 12pub use hir_def::Source;
16pub struct Source<T> {
17 pub file_id: HirFileId,
18 pub ast: T,
19}
20 13
21pub trait HasSource { 14pub trait HasSource {
22 type Ast; 15 type Ast;
23 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; 16 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>;
24} 17}
25 18
26impl<T> Source<T> {
27 pub(crate) fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> {
28 Source { file_id: self.file_id, ast: f(self.ast) }
29 }
30 pub(crate) fn file_syntax(&self, db: &impl AstDatabase) -> SyntaxNode {
31 db.parse_or_expand(self.file_id).expect("source created from invalid file")
32 }
33}
34
35/// NB: Module is !HasSource, because it has two source nodes at the same time: 19/// NB: Module is !HasSource, because it has two source nodes at the same time:
36/// definition and declaration. 20/// definition and declaration.
37impl Module { 21impl Module {
38 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 22 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
39 pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { 23 pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> {
40 let def_map = db.crate_def_map(self.krate); 24 let def_map = db.crate_def_map(self.krate());
41 let decl_id = def_map[self.module_id].declaration; 25 let decl_id = def_map[self.id.module_id].declaration;
42 let file_id = def_map[self.module_id].definition; 26 let file_id = def_map[self.id.module_id].definition;
43 let ast = ModuleSource::new(db, file_id, decl_id); 27 let ast = ModuleSource::new(db, file_id, decl_id);
44 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); 28 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
45 Source { file_id, ast } 29 Source { file_id, ast }
@@ -51,8 +35,8 @@ impl Module {
51 self, 35 self,
52 db: &(impl DefDatabase + AstDatabase), 36 db: &(impl DefDatabase + AstDatabase),
53 ) -> Option<Source<ast::Module>> { 37 ) -> Option<Source<ast::Module>> {
54 let def_map = db.crate_def_map(self.krate); 38 let def_map = db.crate_def_map(self.krate());
55 let decl = def_map[self.module_id].declaration?; 39 let decl = def_map[self.id.module_id].declaration?;
56 let ast = decl.to_node(db); 40 let ast = decl.to_node(db);
57 Some(Source { file_id: decl.file_id(), ast }) 41 Some(Source { file_id: decl.file_id(), ast })
58 } 42 }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 6d34c671d..8f6cb2da7 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -2,8 +2,8 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use ra_db::{salsa, SourceDatabase}; 5use ra_db::salsa;
6use ra_syntax::{ast, SmolStr}; 6use ra_syntax::SmolStr;
7 7
8use crate::{ 8use crate::{
9 adt::{EnumData, StructData}, 9 adt::{EnumData, StructData},
@@ -23,40 +23,12 @@ use crate::{
23 Static, Struct, StructField, Trait, TypeAlias, 23 Static, Struct, StructField, Trait, TypeAlias,
24}; 24};
25 25
26pub use hir_def::db::{InternDatabase, InternDatabaseStorage};
26pub use hir_expand::db::{ 27pub use hir_expand::db::{
27 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 28 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
28 ParseMacroQuery, 29 ParseMacroQuery,
29}; 30};
30 31
31/// We store all interned things in the single QueryGroup.
32///
33/// This is done mainly to allow both "volatile" `AstDatabase` and "stable"
34/// `DefDatabase` to access macros, without adding hard dependencies between the
35/// two.
36#[salsa::query_group(InternDatabaseStorage)]
37pub trait InternDatabase: SourceDatabase {
38 #[salsa::interned]
39 fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId;
40 #[salsa::interned]
41 fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId;
42 #[salsa::interned]
43 fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId;
44 #[salsa::interned]
45 fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId;
46 #[salsa::interned]
47 fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId;
48 #[salsa::interned]
49 fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId;
50 #[salsa::interned]
51 fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId;
52
53 // Interned IDs for Chalk integration
54 #[salsa::interned]
55 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
56 #[salsa::interned]
57 fn intern_impl(&self, impl_: Impl) -> ids::GlobalImplId;
58}
59
60// This database uses `AstDatabase` internally, 32// This database uses `AstDatabase` internally,
61#[salsa::query_group(DefDatabaseStorage)] 33#[salsa::query_group(DefDatabaseStorage)]
62#[salsa::requires(AstDatabase)] 34#[salsa::requires(AstDatabase)]
@@ -176,6 +148,12 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
176 #[salsa::invoke(crate::ty::traits::trait_solver_query)] 148 #[salsa::invoke(crate::ty::traits::trait_solver_query)]
177 fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver; 149 fn trait_solver(&self, krate: Crate) -> crate::ty::traits::TraitSolver;
178 150
151 // Interned IDs for Chalk integration
152 #[salsa::interned]
153 fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
154 #[salsa::interned]
155 fn intern_impl(&self, impl_: Impl) -> ids::GlobalImplId;
156
179 #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)] 157 #[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)]
180 fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>; 158 fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>;
181 159
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 7954c04b2..93713bb14 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -195,7 +195,7 @@ impl Module {
195 .find_map(|krate| { 195 .find_map(|krate| {
196 let def_map = db.crate_def_map(krate); 196 let def_map = db.crate_def_map(krate);
197 let module_id = def_map.find_module_by_source(src.file_id, decl_id)?; 197 let module_id = def_map.find_module_by_source(src.file_id, decl_id)?;
198 Some(Module { krate, module_id }) 198 Some(Module::new(krate, module_id))
199 }) 199 })
200 } 200 }
201} 201}
@@ -208,6 +208,6 @@ where
208 let module_src = 208 let module_src =
209 crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax()); 209 crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax());
210 let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?; 210 let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?;
211 let ctx = LocationCtx::new(db, module, src.file_id); 211 let ctx = LocationCtx::new(db, module.id, src.file_id);
212 Some(DEF::from_ast(ctx, &src.ast)) 212 Some(DEF::from_ast(ctx, &src.ast))
213} 213}
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index dea288eb7..fe083c0c6 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -5,16 +5,12 @@
5//! This module defines a bunch of ids we are using. The most important ones are 5//! This module defines a bunch of ids we are using. The most important ones are
6//! probably `HirFileId` and `DefId`. 6//! probably `HirFileId` and `DefId`.
7 7
8use std::hash::{Hash, Hasher};
9
10use ra_db::salsa; 8use ra_db::salsa;
11use ra_syntax::{ast, AstNode};
12 9
13use crate::{ 10pub use hir_def::{
14 db::{AstDatabase, InternDatabase}, 11 AstItemDef, ConstId, EnumId, FunctionId, ItemLoc, LocationCtx, StaticId, StructId, TraitId,
15 AstId, FileAstId, Module, Source, 12 TypeAliasId,
16}; 13};
17
18pub use hir_expand::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, MacroFileKind}; 14pub use hir_expand::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, MacroFileKind};
19 15
20macro_rules! impl_intern_key { 16macro_rules! impl_intern_key {
@@ -30,163 +26,6 @@ macro_rules! impl_intern_key {
30 }; 26 };
31} 27}
32 28
33#[derive(Debug)]
34pub struct ItemLoc<N: AstNode> {
35 pub(crate) module: Module,
36 ast_id: AstId<N>,
37}
38
39impl<N: AstNode> PartialEq for ItemLoc<N> {
40 fn eq(&self, other: &Self) -> bool {
41 self.module == other.module && self.ast_id == other.ast_id
42 }
43}
44impl<N: AstNode> Eq for ItemLoc<N> {}
45impl<N: AstNode> Hash for ItemLoc<N> {
46 fn hash<H: Hasher>(&self, hasher: &mut H) {
47 self.module.hash(hasher);
48 self.ast_id.hash(hasher);
49 }
50}
51
52impl<N: AstNode> Clone for ItemLoc<N> {
53 fn clone(&self) -> ItemLoc<N> {
54 ItemLoc { module: self.module, ast_id: self.ast_id }
55 }
56}
57
58#[derive(Clone, Copy)]
59pub(crate) struct LocationCtx<DB> {
60 db: DB,
61 module: Module,
62 file_id: HirFileId,
63}
64
65impl<'a, DB> LocationCtx<&'a DB> {
66 pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> {
67 LocationCtx { db, module, file_id }
68 }
69}
70
71impl<'a, DB: AstDatabase + InternDatabase> LocationCtx<&'a DB> {
72 pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF
73 where
74 N: AstNode,
75 DEF: AstItemDef<N>,
76 {
77 DEF::from_ast(self, ast)
78 }
79}
80
81pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
82 fn intern(db: &impl InternDatabase, loc: ItemLoc<N>) -> Self;
83 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<N>;
84
85 fn from_ast(ctx: LocationCtx<&(impl AstDatabase + InternDatabase)>, ast: &N) -> Self {
86 let items = ctx.db.ast_id_map(ctx.file_id);
87 let item_id = items.ast_id(ast);
88 Self::from_ast_id(ctx, item_id)
89 }
90 fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId<N>) -> Self {
91 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) };
92 Self::intern(ctx.db, loc)
93 }
94 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> {
95 let loc = self.lookup_intern(db);
96 let ast = loc.ast_id.to_node(db);
97 Source { file_id: loc.ast_id.file_id(), ast }
98 }
99 fn module(self, db: &impl InternDatabase) -> Module {
100 let loc = self.lookup_intern(db);
101 loc.module
102 }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
106pub struct FunctionId(salsa::InternId);
107impl_intern_key!(FunctionId);
108
109impl AstItemDef<ast::FnDef> for FunctionId {
110 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self {
111 db.intern_function(loc)
112 }
113 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> {
114 db.lookup_intern_function(self)
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
119pub struct StructId(salsa::InternId);
120impl_intern_key!(StructId);
121impl AstItemDef<ast::StructDef> for StructId {
122 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
123 db.intern_struct(loc)
124 }
125 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
126 db.lookup_intern_struct(self)
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
131pub struct EnumId(salsa::InternId);
132impl_intern_key!(EnumId);
133impl AstItemDef<ast::EnumDef> for EnumId {
134 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::EnumDef>) -> Self {
135 db.intern_enum(loc)
136 }
137 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::EnumDef> {
138 db.lookup_intern_enum(self)
139 }
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
143pub struct ConstId(salsa::InternId);
144impl_intern_key!(ConstId);
145impl AstItemDef<ast::ConstDef> for ConstId {
146 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self {
147 db.intern_const(loc)
148 }
149 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> {
150 db.lookup_intern_const(self)
151 }
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155pub struct StaticId(salsa::InternId);
156impl_intern_key!(StaticId);
157impl AstItemDef<ast::StaticDef> for StaticId {
158 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StaticDef>) -> Self {
159 db.intern_static(loc)
160 }
161 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StaticDef> {
162 db.lookup_intern_static(self)
163 }
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
167pub struct TraitId(salsa::InternId);
168impl_intern_key!(TraitId);
169impl AstItemDef<ast::TraitDef> for TraitId {
170 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TraitDef>) -> Self {
171 db.intern_trait(loc)
172 }
173 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TraitDef> {
174 db.lookup_intern_trait(self)
175 }
176}
177
178#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
179pub struct TypeAliasId(salsa::InternId);
180impl_intern_key!(TypeAliasId);
181impl AstItemDef<ast::TypeAliasDef> for TypeAliasId {
182 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self {
183 db.intern_type_alias(loc)
184 }
185 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> {
186 db.lookup_intern_type_alias(self)
187 }
188}
189
190/// This exists just for Chalk, because Chalk just has a single `StructId` where 29/// This exists just for Chalk, because Chalk just has a single `StructId` where
191/// we have different kinds of ADTs, primitive types and special type 30/// we have different kinds of ADTs, primitive types and special type
192/// constructors like tuples and function pointers. 31/// constructors like tuples and function pointers.
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 1a5223680..06f21fc33 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -129,7 +129,7 @@ impl ImplData {
129 ) -> Self { 129 ) -> Self {
130 let target_trait = node.target_trait().map(TypeRef::from_ast); 130 let target_trait = node.target_trait().map(TypeRef::from_ast);
131 let target_type = TypeRef::from_ast_opt(node.target_type()); 131 let target_type = TypeRef::from_ast_opt(node.target_type());
132 let ctx = LocationCtx::new(db, module, file_id); 132 let ctx = LocationCtx::new(db, module.id, file_id);
133 let negative = node.is_negative(); 133 let negative = node.is_negative();
134 let items = if let Some(item_list) = node.item_list() { 134 let items = if let Some(item_list) = node.item_list() {
135 item_list 135 item_list
@@ -182,7 +182,7 @@ impl ModuleImplBlocks {
182 ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { 182 ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) {
183 let mut source_map = ImplSourceMap::default(); 183 let mut source_map = ImplSourceMap::default();
184 let crate_graph = db.crate_graph(); 184 let crate_graph = db.crate_graph();
185 let cfg_options = crate_graph.cfg_options(module.krate.crate_id()); 185 let cfg_options = crate_graph.cfg_options(module.id.krate);
186 186
187 let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map); 187 let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map);
188 (Arc::new(result), Arc::new(source_map)) 188 (Arc::new(result), Arc::new(source_map))
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs
index 6c4e8ffbd..e1780ed38 100644
--- a/crates/ra_hir/src/lang_item.rs
+++ b/crates/ra_hir/src/lang_item.rs
@@ -22,14 +22,14 @@ pub enum LangItemTarget {
22 22
23impl LangItemTarget { 23impl LangItemTarget {
24 pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { 24 pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
25 match self { 25 Some(match self {
26 LangItemTarget::Enum(e) => e.module(db).krate(db), 26 LangItemTarget::Enum(e) => e.module(db).krate(),
27 LangItemTarget::Function(f) => f.module(db).krate(db), 27 LangItemTarget::Function(f) => f.module(db).krate(),
28 LangItemTarget::ImplBlock(i) => i.module().krate(db), 28 LangItemTarget::ImplBlock(i) => i.module().krate(),
29 LangItemTarget::Static(s) => s.module(db).krate(db), 29 LangItemTarget::Static(s) => s.module(db).krate(),
30 LangItemTarget::Struct(s) => s.module(db).krate(db), 30 LangItemTarget::Struct(s) => s.module(db).krate(),
31 LangItemTarget::Trait(t) => t.module(db).krate(db), 31 LangItemTarget::Trait(t) => t.module(db).krate(),
32 } 32 })
33 } 33 }
34} 34}
35 35
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 67adcfa28..b325979f5 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -56,8 +56,9 @@ mod tests;
56 56
57use std::sync::Arc; 57use std::sync::Arc;
58 58
59use hir_def::CrateModuleId;
59use once_cell::sync::Lazy; 60use once_cell::sync::Lazy;
60use ra_arena::{impl_arena_id, Arena, RawId}; 61use ra_arena::Arena;
61use ra_db::{Edition, FileId}; 62use ra_db::{Edition, FileId};
62use ra_prof::profile; 63use ra_prof::profile;
63use ra_syntax::ast; 64use ra_syntax::ast;
@@ -115,13 +116,8 @@ impl std::ops::Index<CrateModuleId> for CrateDefMap {
115 } 116 }
116} 117}
117 118
118/// An ID of a module, **local** to a specific crate
119#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
120pub(crate) struct CrateModuleId(RawId);
121impl_arena_id!(CrateModuleId);
122
123#[derive(Default, Debug, PartialEq, Eq)] 119#[derive(Default, Debug, PartialEq, Eq)]
124pub(crate) struct ModuleData { 120pub struct ModuleData {
125 pub(crate) parent: Option<CrateModuleId>, 121 pub(crate) parent: Option<CrateModuleId>,
126 pub(crate) children: FxHashMap<Name, CrateModuleId>, 122 pub(crate) children: FxHashMap<Name, CrateModuleId>,
127 pub(crate) scope: ModuleScope, 123 pub(crate) scope: ModuleScope,
@@ -335,7 +331,7 @@ impl CrateDefMap {
335 PathKind::DollarCrate(krate) => { 331 PathKind::DollarCrate(krate) => {
336 if krate == self.krate { 332 if krate == self.krate {
337 tested_by!(macro_dollar_crate_self); 333 tested_by!(macro_dollar_crate_self);
338 PerNs::types(Module { krate: self.krate, module_id: self.root }.into()) 334 PerNs::types(Module::new(self.krate, self.root).into())
339 } else { 335 } else {
340 match krate.root_module(db) { 336 match krate.root_module(db) {
341 Some(module) => { 337 Some(module) => {
@@ -346,12 +342,8 @@ impl CrateDefMap {
346 } 342 }
347 } 343 }
348 } 344 }
349 PathKind::Crate => { 345 PathKind::Crate => PerNs::types(Module::new(self.krate, self.root).into()),
350 PerNs::types(Module { krate: self.krate, module_id: self.root }.into()) 346 PathKind::Self_ => PerNs::types(Module::new(self.krate, original_module).into()),
351 }
352 PathKind::Self_ => {
353 PerNs::types(Module { krate: self.krate, module_id: original_module }.into())
354 }
355 // plain import or absolute path in 2015: crate-relative with 347 // plain import or absolute path in 2015: crate-relative with
356 // fallback to extern prelude (with the simplification in 348 // fallback to extern prelude (with the simplification in
357 // rust-lang/rust#57745) 349 // rust-lang/rust#57745)
@@ -377,7 +369,7 @@ impl CrateDefMap {
377 } 369 }
378 PathKind::Super => { 370 PathKind::Super => {
379 if let Some(p) = self.modules[original_module].parent { 371 if let Some(p) = self.modules[original_module].parent {
380 PerNs::types(Module { krate: self.krate, module_id: p }.into()) 372 PerNs::types(Module::new(self.krate, p).into())
381 } else { 373 } else {
382 log::debug!("super path in root module"); 374 log::debug!("super path in root module");
383 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 375 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
@@ -419,12 +411,12 @@ impl CrateDefMap {
419 411
420 curr_per_ns = match curr { 412 curr_per_ns = match curr {
421 ModuleDef::Module(module) => { 413 ModuleDef::Module(module) => {
422 if module.krate != self.krate { 414 if module.krate() != self.krate {
423 let path = 415 let path =
424 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 416 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
425 log::debug!("resolving {:?} in other crate", path); 417 log::debug!("resolving {:?} in other crate", path);
426 let defp_map = db.crate_def_map(module.krate); 418 let defp_map = db.crate_def_map(module.krate());
427 let (def, s) = defp_map.resolve_path(db, module.module_id, &path); 419 let (def, s) = defp_map.resolve_path(db, module.id.module_id, &path);
428 return ResolvePathResult::with( 420 return ResolvePathResult::with(
429 def, 421 def,
430 ReachedFixedPoint::Yes, 422 ReachedFixedPoint::Yes,
@@ -433,7 +425,7 @@ impl CrateDefMap {
433 } 425 }
434 426
435 // Since it is a qualified path here, it should not contains legacy macros 427 // Since it is a qualified path here, it should not contains legacy macros
436 match self[module.module_id].scope.get(&segment.name) { 428 match self[module.id.module_id].scope.get(&segment.name) {
437 Some(res) => res.def, 429 Some(res) => res.def,
438 _ => { 430 _ => {
439 log::debug!("path segment {:?} not found", segment.name); 431 log::debug!("path segment {:?} not found", segment.name);
@@ -511,14 +503,14 @@ impl CrateDefMap {
511 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { 503 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs {
512 if let Some(prelude) = self.prelude { 504 if let Some(prelude) = self.prelude {
513 let keep; 505 let keep;
514 let def_map = if prelude.krate == self.krate { 506 let def_map = if prelude.krate() == self.krate {
515 self 507 self
516 } else { 508 } else {
517 // Extend lifetime 509 // Extend lifetime
518 keep = db.crate_def_map(prelude.krate); 510 keep = db.crate_def_map(prelude.krate());
519 &keep 511 &keep
520 }; 512 };
521 def_map[prelude.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) 513 def_map[prelude.id.module_id].scope.get(name).map_or_else(PerNs::none, |res| res.def)
522 } else { 514 } else {
523 PerNs::none() 515 PerNs::none()
524 } 516 }
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index dc591e8d3..a94a0554c 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -212,7 +212,7 @@ where
212 212
213 if let Some(ModuleDef::Module(m)) = res.take_types() { 213 if let Some(ModuleDef::Module(m)) = res.take_types() {
214 tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); 214 tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use);
215 self.import_all_macros_exported(current_module_id, m.krate); 215 self.import_all_macros_exported(current_module_id, m.krate());
216 } 216 }
217 } 217 }
218 218
@@ -289,11 +289,11 @@ where
289 if import.is_prelude { 289 if import.is_prelude {
290 tested_by!(std_prelude); 290 tested_by!(std_prelude);
291 self.def_map.prelude = Some(m); 291 self.def_map.prelude = Some(m);
292 } else if m.krate != self.def_map.krate { 292 } else if m.krate() != self.def_map.krate {
293 tested_by!(glob_across_crates); 293 tested_by!(glob_across_crates);
294 // glob import from other crate => we can just import everything once 294 // glob import from other crate => we can just import everything once
295 let item_map = self.db.crate_def_map(m.krate); 295 let item_map = self.db.crate_def_map(m.krate());
296 let scope = &item_map[m.module_id].scope; 296 let scope = &item_map[m.id.module_id].scope;
297 297
298 // Module scoped macros is included 298 // Module scoped macros is included
299 let items = scope 299 let items = scope
@@ -307,7 +307,7 @@ where
307 // glob import from same crate => we do an initial 307 // glob import from same crate => we do an initial
308 // import, and then need to propagate any further 308 // import, and then need to propagate any further
309 // additions 309 // additions
310 let scope = &self.def_map[m.module_id].scope; 310 let scope = &self.def_map[m.id.module_id].scope;
311 311
312 // Module scoped macros is included 312 // Module scoped macros is included
313 let items = scope 313 let items = scope
@@ -319,7 +319,7 @@ where
319 self.update(module_id, Some(import_id), &items); 319 self.update(module_id, Some(import_id), &items);
320 // record the glob import in case we add further items 320 // record the glob import in case we add further items
321 self.glob_imports 321 self.glob_imports
322 .entry(m.module_id) 322 .entry(m.id.module_id)
323 .or_default() 323 .or_default()
324 .push((module_id, import_id)); 324 .push((module_id, import_id));
325 } 325 }
@@ -523,9 +523,10 @@ where
523 523
524 // Prelude module is always considered to be `#[macro_use]`. 524 // Prelude module is always considered to be `#[macro_use]`.
525 if let Some(prelude_module) = self.def_collector.def_map.prelude { 525 if let Some(prelude_module) = self.def_collector.def_map.prelude {
526 if prelude_module.krate != self.def_collector.def_map.krate { 526 if prelude_module.krate() != self.def_collector.def_map.krate {
527 tested_by!(prelude_is_macro_use); 527 tested_by!(prelude_is_macro_use);
528 self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate); 528 self.def_collector
529 .import_all_macros_exported(self.module_id, prelude_module.krate());
529 } 530 }
530 } 531 }
531 532
@@ -631,9 +632,7 @@ where
631 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); 632 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone();
632 modules[self.module_id].children.insert(name.clone(), res); 633 modules[self.module_id].children.insert(name.clone(), res);
633 let resolution = Resolution { 634 let resolution = Resolution {
634 def: PerNs::types( 635 def: PerNs::types(Module::new(self.def_collector.def_map.krate, res).into()),
635 Module { krate: self.def_collector.def_map.krate, module_id: res }.into(),
636 ),
637 import: None, 636 import: None,
638 }; 637 };
639 self.def_collector.update(self.module_id, None, &[(name, resolution)]); 638 self.def_collector.update(self.module_id, None, &[(name, resolution)]);
@@ -641,8 +640,8 @@ where
641 } 640 }
642 641
643 fn define_def(&mut self, def: &raw::DefData) { 642 fn define_def(&mut self, def: &raw::DefData) {
644 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; 643 let module = Module::new(self.def_collector.def_map.krate, self.module_id);
645 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); 644 let ctx = LocationCtx::new(self.def_collector.db, module.id, self.file_id);
646 645
647 macro_rules! def { 646 macro_rules! def {
648 ($kind:ident, $ast_id:ident) => { 647 ($kind:ident, $ast_id:ident) => {
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 3c797c0c3..8b6269407 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -1,6 +1,7 @@
1//! Name resolution. 1//! Name resolution.
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_def::CrateModuleId;
4use rustc_hash::FxHashSet; 5use rustc_hash::FxHashSet;
5 6
6use crate::{ 7use crate::{
@@ -13,7 +14,7 @@ use crate::{
13 generics::GenericParams, 14 generics::GenericParams,
14 impl_block::ImplBlock, 15 impl_block::ImplBlock,
15 name::{Name, SELF_PARAM, SELF_TYPE}, 16 name::{Name, SELF_PARAM, SELF_TYPE},
16 nameres::{CrateDefMap, CrateModuleId, PerNs}, 17 nameres::{CrateDefMap, PerNs},
17 path::{Path, PathKind}, 18 path::{Path, PathKind},
18 Adt, BuiltinType, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, Static, Struct, 19 Adt, BuiltinType, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, Static, Struct,
19 Trait, TypeAlias, 20 Trait, TypeAlias,
@@ -330,8 +331,8 @@ impl Resolver {
330 for scope in &self.scopes { 331 for scope in &self.scopes {
331 if let Scope::ModuleScope(m) = scope { 332 if let Scope::ModuleScope(m) = scope {
332 if let Some(prelude) = m.crate_def_map.prelude() { 333 if let Some(prelude) = m.crate_def_map.prelude() {
333 let prelude_def_map = db.crate_def_map(prelude.krate); 334 let prelude_def_map = db.crate_def_map(prelude.krate());
334 traits.extend(prelude_def_map[prelude.module_id].scope.traits()); 335 traits.extend(prelude_def_map[prelude.id.module_id].scope.traits());
335 } 336 }
336 traits.extend(m.crate_def_map[m.module_id].scope.traits()); 337 traits.extend(m.crate_def_map[m.module_id].scope.traits());
337 } 338 }
@@ -444,10 +445,12 @@ impl Scope {
444 f(name.clone(), ScopeDef::ModuleDef(*def)); 445 f(name.clone(), ScopeDef::ModuleDef(*def));
445 }); 446 });
446 if let Some(prelude) = m.crate_def_map.prelude() { 447 if let Some(prelude) = m.crate_def_map.prelude() {
447 let prelude_def_map = db.crate_def_map(prelude.krate); 448 let prelude_def_map = db.crate_def_map(prelude.krate());
448 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { 449 prelude_def_map[prelude.id.module_id].scope.entries().for_each(
449 f(name.clone(), res.def.into()); 450 |(name, res)| {
450 }); 451 f(name.clone(), res.def.into());
452 },
453 );
451 } 454 }
452 } 455 }
453 Scope::GenericParams(gp) => { 456 Scope::GenericParams(gp) => {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index a907d6a9f..730c33226 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -64,7 +64,7 @@ fn def_with_body_from_child_node(
64) -> Option<DefWithBody> { 64) -> Option<DefWithBody> {
65 let src = crate::ModuleSource::from_child_node(db, file_id, node); 65 let src = crate::ModuleSource::from_child_node(db, file_id, node);
66 let module = Module::from_definition(db, crate::Source { file_id: file_id.into(), ast: src })?; 66 let module = Module::from_definition(db, crate::Source { file_id: file_id.into(), ast: src })?;
67 let ctx = LocationCtx::new(db, module, file_id.into()); 67 let ctx = LocationCtx::new(db, module.id, file_id.into());
68 68
69 node.ancestors().find_map(|node| { 69 node.ancestors().find_map(|node| {
70 if let Some(def) = ast::FnDef::cast(node.clone()) { 70 if let Some(def) = ast::FnDef::cast(node.clone()) {
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs
index e39511518..22f188049 100644
--- a/crates/ra_hir/src/traits.rs
+++ b/crates/ra_hir/src/traits.rs
@@ -27,7 +27,7 @@ impl TraitData {
27 let src = tr.source(db); 27 let src = tr.source(db);
28 let name = src.ast.name().map(|n| n.as_name()); 28 let name = src.ast.name().map(|n| n.as_name());
29 let module = tr.module(db); 29 let module = tr.module(db);
30 let ctx = LocationCtx::new(db, module, src.file_id); 30 let ctx = LocationCtx::new(db, module.id, src.file_id);
31 let auto = src.ast.is_auto(); 31 let auto = src.ast.is_auto();
32 let items = if let Some(item_list) = src.ast.item_list() { 32 let items = if let Some(item_list) = src.ast.item_list() {
33 item_list 33 item_list
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index ad2ab560d..50583a142 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -5,13 +5,13 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::CrateModuleId;
8use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
9 10
10use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 11use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef};
11use crate::{ 12use crate::{
12 db::HirDatabase, 13 db::HirDatabase,
13 impl_block::{ImplBlock, ImplId}, 14 impl_block::{ImplBlock, ImplId},
14 nameres::CrateModuleId,
15 resolve::Resolver, 15 resolve::Resolver,
16 ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy}, 16 ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy},
17 ty::{Ty, TypeCtor}, 17 ty::{Ty, TypeCtor},
@@ -50,7 +50,7 @@ impl CrateImplBlocks {
50 let fingerprint = TyFingerprint::for_impl(ty); 50 let fingerprint = TyFingerprint::for_impl(ty);
51 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( 51 fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map(
52 move |(module_id, impl_id)| { 52 move |(module_id, impl_id)| {
53 let module = Module { krate: self.krate, module_id: *module_id }; 53 let module = Module::new(self.krate, *module_id);
54 ImplBlock::from_id(module, *impl_id) 54 ImplBlock::from_id(module, *impl_id)
55 }, 55 },
56 ) 56 )
@@ -62,7 +62,7 @@ impl CrateImplBlocks {
62 ) -> impl Iterator<Item = ImplBlock> + 'a { 62 ) -> impl Iterator<Item = ImplBlock> + 'a {
63 self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map( 63 self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map(
64 move |(module_id, impl_id)| { 64 move |(module_id, impl_id)| {
65 let module = Module { krate: self.krate, module_id: *module_id }; 65 let module = Module::new(self.krate, *module_id);
66 ImplBlock::from_id(module, *impl_id) 66 ImplBlock::from_id(module, *impl_id)
67 }, 67 },
68 ) 68 )
@@ -71,7 +71,7 @@ impl CrateImplBlocks {
71 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { 71 pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a {
72 self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map( 72 self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map(
73 move |(module_id, impl_id)| { 73 move |(module_id, impl_id)| {
74 let module = Module { krate: self.krate, module_id: *module_id }; 74 let module = Module::new(self.krate, *module_id);
75 ImplBlock::from_id(module, *impl_id) 75 ImplBlock::from_id(module, *impl_id)
76 }, 76 },
77 ) 77 )
@@ -90,14 +90,14 @@ impl CrateImplBlocks {
90 self.impls_by_trait 90 self.impls_by_trait
91 .entry(tr.trait_) 91 .entry(tr.trait_)
92 .or_insert_with(Vec::new) 92 .or_insert_with(Vec::new)
93 .push((module.module_id, impl_id)); 93 .push((module.id.module_id, impl_id));
94 } 94 }
95 } else { 95 } else {
96 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { 96 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
97 self.impls 97 self.impls
98 .entry(target_ty_fp) 98 .entry(target_ty_fp)
99 .or_insert_with(Vec::new) 99 .or_insert_with(Vec::new)
100 .push((module.module_id, impl_id)); 100 .push((module.id.module_id, impl_id));
101 } 101 }
102 } 102 }
103 } 103 }
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index e18c28cf6..ab66515be 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -162,11 +162,11 @@ impl ToChalk for Trait {
162 type Chalk = chalk_ir::TraitId; 162 type Chalk = chalk_ir::TraitId;
163 163
164 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId { 164 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId {
165 self.id.into() 165 chalk_ir::TraitId(id_to_chalk(self.id))
166 } 166 }
167 167
168 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait { 168 fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait {
169 Trait { id: trait_id.into() } 169 Trait { id: id_from_chalk(trait_id.0) }
170 } 170 }
171} 171}
172 172
@@ -198,11 +198,11 @@ impl ToChalk for TypeAlias {
198 type Chalk = chalk_ir::TypeId; 198 type Chalk = chalk_ir::TypeId;
199 199
200 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId { 200 fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TypeId {
201 self.id.into() 201 chalk_ir::TypeId(id_to_chalk(self.id))
202 } 202 }
203 203
204 fn from_chalk(_db: &impl HirDatabase, impl_id: chalk_ir::TypeId) -> TypeAlias { 204 fn from_chalk(_db: &impl HirDatabase, type_alias_id: chalk_ir::TypeId) -> TypeAlias {
205 TypeAlias { id: impl_id.into() } 205 TypeAlias { id: id_from_chalk(type_alias_id.0) }
206 } 206 }
207} 207}
208 208
@@ -537,7 +537,7 @@ pub(crate) fn trait_datum_query(
537 let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db); 537 let trait_ref = trait_.trait_ref(db).subst(&bound_vars).to_chalk(db);
538 let flags = chalk_rust_ir::TraitFlags { 538 let flags = chalk_rust_ir::TraitFlags {
539 auto: trait_.is_auto(db), 539 auto: trait_.is_auto(db),
540 upstream: trait_.module(db).krate(db) != Some(krate), 540 upstream: trait_.module(db).krate() != krate,
541 non_enumerable: true, 541 non_enumerable: true,
542 // FIXME set these flags correctly 542 // FIXME set these flags correctly
543 marker: false, 543 marker: false,
@@ -625,7 +625,7 @@ fn impl_block_datum(
625 .target_trait_ref(db) 625 .target_trait_ref(db)
626 .expect("FIXME handle unresolved impl block trait ref") 626 .expect("FIXME handle unresolved impl block trait ref")
627 .subst(&bound_vars); 627 .subst(&bound_vars);
628 let impl_type = if impl_block.module().krate(db) == Some(krate) { 628 let impl_type = if impl_block.module().krate() == krate {
629 chalk_rust_ir::ImplType::Local 629 chalk_rust_ir::ImplType::Local
630 } else { 630 } else {
631 chalk_rust_ir::ImplType::External 631 chalk_rust_ir::ImplType::External
@@ -775,30 +775,6 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
775 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 775 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
776} 776}
777 777
778impl From<chalk_ir::TraitId> for crate::ids::TraitId {
779 fn from(trait_id: chalk_ir::TraitId) -> Self {
780 id_from_chalk(trait_id.0)
781 }
782}
783
784impl From<crate::ids::TraitId> for chalk_ir::TraitId {
785 fn from(trait_id: crate::ids::TraitId) -> Self {
786 chalk_ir::TraitId(id_to_chalk(trait_id))
787 }
788}
789
790impl From<chalk_ir::TypeId> for crate::ids::TypeAliasId {
791 fn from(type_id: chalk_ir::TypeId) -> Self {
792 id_from_chalk(type_id.0)
793 }
794}
795
796impl From<crate::ids::TypeAliasId> for chalk_ir::TypeId {
797 fn from(type_id: crate::ids::TypeAliasId) -> Self {
798 chalk_ir::TypeId(id_to_chalk(type_id))
799 }
800}
801
802impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { 778impl From<chalk_ir::StructId> for crate::ids::TypeCtorId {
803 fn from(struct_id: chalk_ir::StructId) -> Self { 779 fn from(struct_id: chalk_ir::StructId) -> Self {
804 id_from_chalk(struct_id.0) 780 id_from_chalk(struct_id.0)
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
new file mode 100644
index 000000000..75e93f254
--- /dev/null
+++ b/crates/ra_hir_def/Cargo.toml
@@ -0,0 +1,14 @@
1[package]
2edition = "2018"
3name = "ra_hir_def"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6
7[dependencies]
8log = "0.4.5"
9
10ra_arena = { path = "../ra_arena" }
11ra_db = { path = "../ra_db" }
12ra_syntax = { path = "../ra_syntax" }
13ra_prof = { path = "../ra_prof" }
14hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
new file mode 100644
index 000000000..f6f976c86
--- /dev/null
+++ b/crates/ra_hir_def/src/db.rs
@@ -0,0 +1,22 @@
1//! Defines database & queries for name resolution.
2
3use ra_db::{salsa, SourceDatabase};
4use ra_syntax::ast;
5
6#[salsa::query_group(InternDatabaseStorage)]
7pub trait InternDatabase: SourceDatabase {
8 #[salsa::interned]
9 fn intern_function(&self, loc: crate::ItemLoc<ast::FnDef>) -> crate::FunctionId;
10 #[salsa::interned]
11 fn intern_struct(&self, loc: crate::ItemLoc<ast::StructDef>) -> crate::StructId;
12 #[salsa::interned]
13 fn intern_enum(&self, loc: crate::ItemLoc<ast::EnumDef>) -> crate::EnumId;
14 #[salsa::interned]
15 fn intern_const(&self, loc: crate::ItemLoc<ast::ConstDef>) -> crate::ConstId;
16 #[salsa::interned]
17 fn intern_static(&self, loc: crate::ItemLoc<ast::StaticDef>) -> crate::StaticId;
18 #[salsa::interned]
19 fn intern_trait(&self, loc: crate::ItemLoc<ast::TraitDef>) -> crate::TraitId;
20 #[salsa::interned]
21 fn intern_type_alias(&self, loc: crate::ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId;
22}
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
new file mode 100644
index 000000000..4d6b9db03
--- /dev/null
+++ b/crates/ra_hir_def/src/lib.rs
@@ -0,0 +1,216 @@
1//! `hir_def` crate contains everything between macro expansion and type
2//! inference.
3//!
4//! It defines various items (structs, enums, traits) which comprises Rust code,
5//! as well as an algorithm for resolving paths to such entities.
6//!
7//! Note that `hir_def` is a work in progress, so not all of the above is
8//! actually true.
9
10pub mod db;
11
12use std::hash::{Hash, Hasher};
13
14use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId};
15use ra_arena::{impl_arena_id, RawId};
16use ra_db::{salsa, CrateId};
17use ra_syntax::{ast, AstNode, SyntaxNode};
18
19use crate::db::InternDatabase;
20
21#[derive(Debug, PartialEq, Eq, Clone, Copy)]
22pub struct Source<T> {
23 pub file_id: HirFileId,
24 pub ast: T,
25}
26
27impl<T> Source<T> {
28 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> {
29 Source { file_id: self.file_id, ast: f(self.ast) }
30 }
31 pub fn file_syntax(&self, db: &impl AstDatabase) -> SyntaxNode {
32 db.parse_or_expand(self.file_id).expect("source created from invalid file")
33 }
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37pub struct ModuleId {
38 pub krate: CrateId,
39 pub module_id: CrateModuleId,
40}
41
42/// An ID of a module, **local** to a specific crate
43// FIXME: rename to `LocalModuleId`.
44#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
45pub struct CrateModuleId(RawId);
46impl_arena_id!(CrateModuleId);
47
48macro_rules! impl_intern_key {
49 ($name:ident) => {
50 impl salsa::InternKey for $name {
51 fn from_intern_id(v: salsa::InternId) -> Self {
52 $name(v)
53 }
54 fn as_intern_id(&self) -> salsa::InternId {
55 self.0
56 }
57 }
58 };
59}
60
61#[derive(Debug)]
62pub struct ItemLoc<N: AstNode> {
63 pub(crate) module: ModuleId,
64 ast_id: AstId<N>,
65}
66
67impl<N: AstNode> PartialEq for ItemLoc<N> {
68 fn eq(&self, other: &Self) -> bool {
69 self.module == other.module && self.ast_id == other.ast_id
70 }
71}
72impl<N: AstNode> Eq for ItemLoc<N> {}
73impl<N: AstNode> Hash for ItemLoc<N> {
74 fn hash<H: Hasher>(&self, hasher: &mut H) {
75 self.module.hash(hasher);
76 self.ast_id.hash(hasher);
77 }
78}
79
80impl<N: AstNode> Clone for ItemLoc<N> {
81 fn clone(&self) -> ItemLoc<N> {
82 ItemLoc { module: self.module, ast_id: self.ast_id }
83 }
84}
85
86#[derive(Clone, Copy)]
87pub struct LocationCtx<DB> {
88 db: DB,
89 module: ModuleId,
90 file_id: HirFileId,
91}
92
93impl<'a, DB> LocationCtx<&'a DB> {
94 pub fn new(db: &'a DB, module: ModuleId, file_id: HirFileId) -> LocationCtx<&'a DB> {
95 LocationCtx { db, module, file_id }
96 }
97}
98
99impl<'a, DB: AstDatabase + InternDatabase> LocationCtx<&'a DB> {
100 pub fn to_def<N, DEF>(self, ast: &N) -> DEF
101 where
102 N: AstNode,
103 DEF: AstItemDef<N>,
104 {
105 DEF::from_ast(self, ast)
106 }
107}
108
109pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
110 fn intern(db: &impl InternDatabase, loc: ItemLoc<N>) -> Self;
111 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<N>;
112
113 fn from_ast(ctx: LocationCtx<&(impl AstDatabase + InternDatabase)>, ast: &N) -> Self {
114 let items = ctx.db.ast_id_map(ctx.file_id);
115 let item_id = items.ast_id(ast);
116 Self::from_ast_id(ctx, item_id)
117 }
118 fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId<N>) -> Self {
119 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) };
120 Self::intern(ctx.db, loc)
121 }
122 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> {
123 let loc = self.lookup_intern(db);
124 let ast = loc.ast_id.to_node(db);
125 Source { file_id: loc.ast_id.file_id(), ast }
126 }
127 fn module(self, db: &impl InternDatabase) -> ModuleId {
128 let loc = self.lookup_intern(db);
129 loc.module
130 }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
134pub struct FunctionId(salsa::InternId);
135impl_intern_key!(FunctionId);
136
137impl AstItemDef<ast::FnDef> for FunctionId {
138 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self {
139 db.intern_function(loc)
140 }
141 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> {
142 db.lookup_intern_function(self)
143 }
144}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
147pub struct StructId(salsa::InternId);
148impl_intern_key!(StructId);
149impl AstItemDef<ast::StructDef> for StructId {
150 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
151 db.intern_struct(loc)
152 }
153 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
154 db.lookup_intern_struct(self)
155 }
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
159pub struct EnumId(salsa::InternId);
160impl_intern_key!(EnumId);
161impl AstItemDef<ast::EnumDef> for EnumId {
162 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::EnumDef>) -> Self {
163 db.intern_enum(loc)
164 }
165 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::EnumDef> {
166 db.lookup_intern_enum(self)
167 }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
171pub struct ConstId(salsa::InternId);
172impl_intern_key!(ConstId);
173impl AstItemDef<ast::ConstDef> for ConstId {
174 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self {
175 db.intern_const(loc)
176 }
177 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> {
178 db.lookup_intern_const(self)
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
183pub struct StaticId(salsa::InternId);
184impl_intern_key!(StaticId);
185impl AstItemDef<ast::StaticDef> for StaticId {
186 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StaticDef>) -> Self {
187 db.intern_static(loc)
188 }
189 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StaticDef> {
190 db.lookup_intern_static(self)
191 }
192}
193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
195pub struct TraitId(salsa::InternId);
196impl_intern_key!(TraitId);
197impl AstItemDef<ast::TraitDef> for TraitId {
198 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TraitDef>) -> Self {
199 db.intern_trait(loc)
200 }
201 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TraitDef> {
202 db.lookup_intern_trait(self)
203 }
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
207pub struct TypeAliasId(salsa::InternId);
208impl_intern_key!(TypeAliasId);
209impl AstItemDef<ast::TypeAliasDef> for TypeAliasId {
210 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self {
211 db.intern_type_alias(loc)
212 }
213 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> {
214 db.lookup_intern_type_alias(self)
215 }
216}
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 23dece73c..956d8ce49 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -50,7 +50,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), 50 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
51 _ => unreachable!(), 51 _ => unreachable!(),
52 }; 52 };
53 let krate = ctx.module.and_then(|m| m.krate(ctx.db)); 53 let krate = ctx.module.map(|m| m.krate());
54 if let Some(krate) = krate { 54 if let Some(krate) = krate {
55 ty.iterate_impl_items(ctx.db, krate, |item| { 55 ty.iterate_impl_items(ctx.db, krate, |item| {
56 match item { 56 match item {
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs
index 7fc1b1efa..b899ed3a5 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide_api/src/impls.rs
@@ -51,7 +51,7 @@ fn impls_for_def(
51 } 51 }
52 }; 52 };
53 53
54 let krate = module.krate(db)?; 54 let krate = module.krate();
55 let impls = db.impls_in_crate(krate); 55 let impls = db.impls_in_crate(krate);
56 56
57 Some( 57 Some(
@@ -72,7 +72,7 @@ fn impls_for_trait(
72 let src = hir::Source { file_id: position.file_id.into(), ast: node.clone() }; 72 let src = hir::Source { file_id: position.file_id.into(), ast: node.clone() };
73 let tr = hir::Trait::from_source(db, src)?; 73 let tr = hir::Trait::from_source(db, src)?;
74 74
75 let krate = module.krate(db)?; 75 let krate = module.krate();
76 let impls = db.impls_in_crate(krate); 76 let impls = db.impls_in_crate(krate);
77 77
78 Some( 78 Some(
diff --git a/crates/ra_ide_api/src/parent_module.rs b/crates/ra_ide_api/src/parent_module.rs
index 566509849..4c57566e2 100644
--- a/crates/ra_ide_api/src/parent_module.rs
+++ b/crates/ra_ide_api/src/parent_module.rs
@@ -27,10 +27,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
27 Some(it) => it, 27 Some(it) => it,
28 None => return Vec::new(), 28 None => return Vec::new(),
29 }; 29 };
30 let krate = match module.krate(db) { 30 let krate = module.krate();
31 Some(it) => it,
32 None => return Vec::new(),
33 };
34 vec![krate.crate_id()] 31 vec![krate.crate_id()]
35} 32}
36 33
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs
index b6eb248b7..dbd1af597 100644
--- a/crates/ra_ide_api/src/references/search_scope.rs
+++ b/crates/ra_ide_api/src/references/search_scope.rs
@@ -120,7 +120,7 @@ impl NameDefinition {
120 return SearchScope::new(res); 120 return SearchScope::new(res);
121 } 121 }
122 if vis.as_str() == "pub" { 122 if vis.as_str() == "pub" {
123 let krate = self.container.krate(db).unwrap(); 123 let krate = self.container.krate();
124 let crate_graph = db.crate_graph(); 124 let crate_graph = db.crate_graph();
125 for crate_id in crate_graph.iter() { 125 for crate_id in crate_graph.iter() {
126 let mut crate_deps = crate_graph.dependencies(crate_id); 126 let mut crate_deps = crate_graph.dependencies(crate_id);