aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/lib.rs')
-rw-r--r--crates/ra_hir_def/src/lib.rs346
1 files changed, 96 insertions, 250 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index bc5530896..f6c7f38d1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -15,6 +15,10 @@ pub mod type_ref;
15pub mod builtin_type; 15pub mod builtin_type;
16pub mod diagnostics; 16pub mod diagnostics;
17pub mod per_ns; 17pub mod per_ns;
18pub mod item_scope;
19
20pub mod dyn_map;
21pub mod keys;
18 22
19pub mod adt; 23pub mod adt;
20pub mod data; 24pub mod data;
@@ -29,23 +33,23 @@ pub mod resolver;
29mod trace; 33mod trace;
30pub mod nameres; 34pub mod nameres;
31 35
36pub mod src;
37pub mod child_by_source;
38
32#[cfg(test)] 39#[cfg(test)]
33mod test_db; 40mod test_db;
34#[cfg(test)] 41#[cfg(test)]
35mod marks; 42mod marks;
36 43
37use std::hash::{Hash, Hasher}; 44use std::hash::Hash;
38 45
39use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; 46use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
40use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; 47use ra_arena::{impl_arena_id, RawId};
41use ra_db::{impl_intern_key, salsa, CrateId}; 48use ra_db::{impl_intern_key, salsa, CrateId};
42use ra_syntax::{ast, AstNode}; 49use ra_syntax::{ast, AstNode};
43 50
44use crate::{builtin_type::BuiltinType, db::InternDatabase}; 51use crate::body::Expander;
45 52use crate::builtin_type::BuiltinType;
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47pub struct LocalImportId(RawId);
48impl_arena_id!(LocalImportId);
49 53
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51pub struct ModuleId { 55pub struct ModuleId {
@@ -59,122 +63,57 @@ pub struct ModuleId {
59pub struct LocalModuleId(RawId); 63pub struct LocalModuleId(RawId);
60impl_arena_id!(LocalModuleId); 64impl_arena_id!(LocalModuleId);
61 65
62#[derive(Debug)] 66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
63pub struct ItemLoc<N: AstNode> { 67pub struct ItemLoc<N: AstNode> {
64 pub(crate) module: ModuleId, 68 pub container: ContainerId,
65 ast_id: AstId<N>, 69 pub ast_id: AstId<N>,
66}
67
68impl<N: AstNode> PartialEq for ItemLoc<N> {
69 fn eq(&self, other: &Self) -> bool {
70 self.module == other.module && self.ast_id == other.ast_id
71 }
72}
73impl<N: AstNode> Eq for ItemLoc<N> {}
74impl<N: AstNode> Hash for ItemLoc<N> {
75 fn hash<H: Hasher>(&self, hasher: &mut H) {
76 self.module.hash(hasher);
77 self.ast_id.hash(hasher);
78 }
79}
80
81impl<N: AstNode> Clone for ItemLoc<N> {
82 fn clone(&self) -> ItemLoc<N> {
83 ItemLoc { module: self.module, ast_id: self.ast_id }
84 }
85} 70}
86 71
87#[derive(Clone, Copy)] 72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
88pub struct LocationCtx<DB> { 73pub struct AssocItemLoc<N: AstNode> {
89 db: DB, 74 pub container: AssocContainerId,
90 module: ModuleId, 75 pub ast_id: AstId<N>,
91 file_id: HirFileId,
92} 76}
93 77
94impl<'a, DB> LocationCtx<&'a DB> { 78macro_rules! impl_intern {
95 pub fn new(db: &'a DB, module: ModuleId, file_id: HirFileId) -> LocationCtx<&'a DB> { 79 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
96 LocationCtx { db, module, file_id } 80 impl_intern_key!($id);
97 }
98}
99 81
100pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { 82 impl Intern for $loc {
101 fn intern(db: &impl InternDatabase, loc: ItemLoc<N>) -> Self; 83 type ID = $id;
102 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<N>; 84 fn intern(self, db: &impl db::DefDatabase) -> $id {
85 db.$intern(self)
86 }
87 }
103 88
104 fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId<N>) -> Self { 89 impl Lookup for $id {
105 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) }; 90 type Data = $loc;
106 Self::intern(ctx.db, loc) 91 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
107 } 92 db.$lookup(*self)
108 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { 93 }
109 let loc = self.lookup_intern(db); 94 }
110 let value = loc.ast_id.to_node(db); 95 };
111 Source { file_id: loc.ast_id.file_id(), value }
112 }
113 fn module(self, db: &impl InternDatabase) -> ModuleId {
114 let loc = self.lookup_intern(db);
115 loc.module
116 }
117} 96}
118 97
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
120pub struct FunctionId(salsa::InternId); 99pub struct FunctionId(salsa::InternId);
121impl_intern_key!(FunctionId); 100type FunctionLoc = AssocItemLoc<ast::FnDef>;
122 101impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
124pub struct FunctionLoc {
125 pub container: ContainerId,
126 pub ast_id: AstId<ast::FnDef>,
127}
128
129impl Intern for FunctionLoc {
130 type ID = FunctionId;
131 fn intern(self, db: &impl db::DefDatabase) -> FunctionId {
132 db.intern_function(self)
133 }
134}
135
136impl Lookup for FunctionId {
137 type Data = FunctionLoc;
138 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc {
139 db.lookup_intern_function(*self)
140 }
141}
142 102
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
144pub struct StructId(salsa::InternId); 104pub struct StructId(salsa::InternId);
145impl_intern_key!(StructId); 105type StructLoc = ItemLoc<ast::StructDef>;
146impl AstItemDef<ast::StructDef> for StructId { 106impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
147 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
148 db.intern_struct(loc)
149 }
150 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::StructDef> {
151 db.lookup_intern_struct(self)
152 }
153}
154 107
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct UnionId(salsa::InternId); 109pub struct UnionId(salsa::InternId);
157impl_intern_key!(UnionId); 110pub type UnionLoc = ItemLoc<ast::UnionDef>;
158impl AstItemDef<ast::UnionDef> for UnionId { 111impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
159 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::UnionDef>) -> Self {
160 db.intern_union(loc)
161 }
162 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::UnionDef> {
163 db.lookup_intern_union(self)
164 }
165}
166 112
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
168pub struct EnumId(salsa::InternId); 114pub struct EnumId(salsa::InternId);
169impl_intern_key!(EnumId); 115pub type EnumLoc = ItemLoc<ast::EnumDef>;
170impl AstItemDef<ast::EnumDef> for EnumId { 116impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
171 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::EnumDef>) -> Self {
172 db.intern_enum(loc)
173 }
174 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::EnumDef> {
175 db.lookup_intern_enum(self)
176 }
177}
178 117
179// FIXME: rename to `VariantId`, only enums can ave variants 118// FIXME: rename to `VariantId`, only enums can ave variants
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -199,98 +138,38 @@ impl_arena_id!(LocalStructFieldId);
199 138
200#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
201pub struct ConstId(salsa::InternId); 140pub struct ConstId(salsa::InternId);
202impl_intern_key!(ConstId); 141type ConstLoc = AssocItemLoc<ast::ConstDef>;
203#[derive(Debug, Clone, PartialEq, Eq, Hash)] 142impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
204pub struct ConstLoc {
205 pub container: ContainerId,
206 pub ast_id: AstId<ast::ConstDef>,
207}
208
209impl Intern for ConstLoc {
210 type ID = ConstId;
211 fn intern(self, db: &impl db::DefDatabase) -> ConstId {
212 db.intern_const(self)
213 }
214}
215
216impl Lookup for ConstId {
217 type Data = ConstLoc;
218 fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
219 db.lookup_intern_const(*self)
220 }
221}
222 143
223#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
224pub struct StaticId(salsa::InternId); 145pub struct StaticId(salsa::InternId);
225impl_intern_key!(StaticId); 146pub type StaticLoc = ItemLoc<ast::StaticDef>;
226 147impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228pub struct StaticLoc {
229 pub container: ModuleId,
230 pub ast_id: AstId<ast::StaticDef>,
231}
232
233impl Intern for StaticLoc {
234 type ID = StaticId;
235 fn intern(self, db: &impl db::DefDatabase) -> StaticId {
236 db.intern_static(self)
237 }
238}
239
240impl Lookup for StaticId {
241 type Data = StaticLoc;
242 fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc {
243 db.lookup_intern_static(*self)
244 }
245}
246 148
247#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
248pub struct TraitId(salsa::InternId); 150pub struct TraitId(salsa::InternId);
249impl_intern_key!(TraitId); 151pub type TraitLoc = ItemLoc<ast::TraitDef>;
250impl AstItemDef<ast::TraitDef> for TraitId { 152impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
251 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TraitDef>) -> Self {
252 db.intern_trait(loc)
253 }
254 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TraitDef> {
255 db.lookup_intern_trait(self)
256 }
257}
258 153
259#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
260pub struct TypeAliasId(salsa::InternId); 155pub struct TypeAliasId(salsa::InternId);
261impl_intern_key!(TypeAliasId); 156type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
262 157impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
263#[derive(Debug, Clone, PartialEq, Eq, Hash)]
264pub struct TypeAliasLoc {
265 pub container: ContainerId,
266 pub ast_id: AstId<ast::TypeAliasDef>,
267}
268 158
269impl Intern for TypeAliasLoc { 159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
270 type ID = TypeAliasId; 160pub struct ImplId(salsa::InternId);
271 fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId { 161type ImplLoc = ItemLoc<ast::ImplBlock>;
272 db.intern_type_alias(self) 162impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
273 }
274}
275 163
276impl Lookup for TypeAliasId { 164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
277 type Data = TypeAliasLoc; 165pub struct TypeParamId {
278 fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc { 166 pub parent: GenericDefId,
279 db.lookup_intern_type_alias(*self) 167 pub local_id: LocalTypeParamId,
280 }
281} 168}
282 169
283#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
284pub struct ImplId(salsa::InternId); 171pub struct LocalTypeParamId(RawId);
285impl_intern_key!(ImplId); 172impl_arena_id!(LocalTypeParamId);
286impl AstItemDef<ast::ImplBlock> for ImplId {
287 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ImplBlock>) -> Self {
288 db.intern_impl(loc)
289 }
290 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ImplBlock> {
291 db.lookup_intern_impl(self)
292 }
293}
294 173
295macro_rules! impl_froms { 174macro_rules! impl_froms {
296 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 175 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
@@ -314,9 +193,16 @@ macro_rules! impl_froms {
314#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
315pub enum ContainerId { 194pub enum ContainerId {
316 ModuleId(ModuleId), 195 ModuleId(ModuleId),
196 DefWithBodyId(DefWithBodyId),
197}
198
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
200pub enum AssocContainerId {
201 ContainerId(ContainerId),
317 ImplId(ImplId), 202 ImplId(ImplId),
318 TraitId(TraitId), 203 TraitId(TraitId),
319} 204}
205impl_froms!(AssocContainerId: ContainerId);
320 206
321/// A Data Type 207/// A Data Type
322#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 208#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -459,43 +345,39 @@ pub trait HasModule {
459 fn module(&self, db: &impl db::DefDatabase) -> ModuleId; 345 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
460} 346}
461 347
462impl HasModule for FunctionLoc { 348impl HasModule for ContainerId {
463 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 349 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
464 match self.container { 350 match *self {
465 ContainerId::ModuleId(it) => it, 351 ContainerId::ModuleId(it) => it,
466 ContainerId::ImplId(it) => it.module(db), 352 ContainerId::DefWithBodyId(it) => it.module(db),
467 ContainerId::TraitId(it) => it.module(db),
468 } 353 }
469 } 354 }
470} 355}
471 356
472impl HasModule for TypeAliasLoc { 357impl HasModule for AssocContainerId {
473 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 358 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
474 match self.container { 359 match *self {
475 ContainerId::ModuleId(it) => it, 360 AssocContainerId::ContainerId(it) => it.module(db),
476 ContainerId::ImplId(it) => it.module(db), 361 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db),
477 ContainerId::TraitId(it) => it.module(db), 362 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
478 } 363 }
479 } 364 }
480} 365}
481 366
482impl HasModule for ConstLoc { 367impl<N: AstNode> HasModule for AssocItemLoc<N> {
483 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 368 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
484 match self.container { 369 self.container.module(db)
485 ContainerId::ModuleId(it) => it,
486 ContainerId::ImplId(it) => it.module(db),
487 ContainerId::TraitId(it) => it.module(db),
488 }
489 } 370 }
490} 371}
491 372
492impl HasModule for AdtId { 373impl HasModule for AdtId {
493 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 374 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
494 match self { 375 match self {
495 AdtId::StructId(it) => it.module(db), 376 AdtId::StructId(it) => it.lookup(db).container,
496 AdtId::UnionId(it) => it.module(db), 377 AdtId::UnionId(it) => it.lookup(db).container,
497 AdtId::EnumId(it) => it.module(db), 378 AdtId::EnumId(it) => it.lookup(db).container,
498 } 379 }
380 .module(db)
499 } 381 }
500} 382}
501 383
@@ -509,58 +391,22 @@ impl HasModule for DefWithBodyId {
509 } 391 }
510} 392}
511 393
512impl HasModule for StaticLoc { 394impl HasModule for GenericDefId {
513 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 395 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
514 self.container 396 match self {
515 } 397 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
516} 398 GenericDefId::AdtId(it) => it.module(db),
517 399 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
518pub trait HasSource { 400 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
519 type Value; 401 GenericDefId::ImplId(it) => it.lookup(db).container.module(db),
520 fn source(&self, db: &impl db::DefDatabase) -> Source<Self::Value>; 402 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
521} 403 GenericDefId::ConstId(it) => it.lookup(db).module(db),
522 404 }
523impl HasSource for FunctionLoc {
524 type Value = ast::FnDef;
525
526 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::FnDef> {
527 let node = self.ast_id.to_node(db);
528 Source::new(self.ast_id.file_id(), node)
529 }
530}
531
532impl HasSource for TypeAliasLoc {
533 type Value = ast::TypeAliasDef;
534
535 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::TypeAliasDef> {
536 let node = self.ast_id.to_node(db);
537 Source::new(self.ast_id.file_id(), node)
538 }
539}
540
541impl HasSource for ConstLoc {
542 type Value = ast::ConstDef;
543
544 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::ConstDef> {
545 let node = self.ast_id.to_node(db);
546 Source::new(self.ast_id.file_id(), node)
547 } 405 }
548} 406}
549 407
550impl HasSource for StaticLoc { 408impl HasModule for StaticLoc {
551 type Value = ast::StaticDef; 409 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
552 410 self.container.module(db)
553 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::StaticDef> {
554 let node = self.ast_id.to_node(db);
555 Source::new(self.ast_id.file_id(), node)
556 } 411 }
557} 412}
558
559pub trait HasChildSource {
560 type ChildId;
561 type Value;
562 fn child_source(
563 &self,
564 db: &impl db::DefDatabase,
565 ) -> Source<ArenaMap<Self::ChildId, Self::Value>>;
566}