aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/body.rs3
-rw-r--r--crates/ra_hir_def/src/db.rs13
-rw-r--r--crates/ra_hir_def/src/generics.rs4
-rw-r--r--crates/ra_hir_def/src/impls.rs (renamed from crates/ra_hir_def/src/imp.rs)12
-rw-r--r--crates/ra_hir_def/src/lib.rs69
-rw-r--r--crates/ra_hir_def/src/nameres.rs8
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs13
-rw-r--r--crates/ra_hir_def/src/traits.rs82
8 files changed, 185 insertions, 19 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 3804b65c7..b69d4dea6 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -17,7 +17,7 @@ use crate::{
17 expr::{Expr, ExprId, Pat, PatId}, 17 expr::{Expr, ExprId, Pat, PatId},
18 nameres::CrateDefMap, 18 nameres::CrateDefMap,
19 path::Path, 19 path::Path,
20 AstItemDef, DefWithBodyId, ModuleId, 20 AstItemDef, DefWithBodyId, HasModule, HasSource, Lookup, ModuleId,
21}; 21};
22 22
23pub struct Expander { 23pub struct Expander {
@@ -149,6 +149,7 @@ impl Body {
149 149
150 let (file_id, module, body) = match def { 150 let (file_id, module, body) = match def {
151 DefWithBodyId::FunctionId(f) => { 151 DefWithBodyId::FunctionId(f) => {
152 let f = f.lookup(db);
152 let src = f.source(db); 153 let src = f.source(db);
153 params = src.value.param_list(); 154 params = src.value.param_list();
154 (src.file_id, f.module(db), src.value.body().map(ast::Expr::from)) 155 (src.file_id, f.module(db), src.value.body().map(ast::Expr::from))
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 348aca07f..e4ffdebe9 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -8,18 +8,19 @@ use ra_syntax::ast;
8use crate::{ 8use crate::{
9 adt::{EnumData, StructData}, 9 adt::{EnumData, StructData},
10 body::{scope::ExprScopes, Body, BodySourceMap}, 10 body::{scope::ExprScopes, Body, BodySourceMap},
11 imp::ImplData, 11 impls::ImplData,
12 nameres::{ 12 nameres::{
13 raw::{ImportSourceMap, RawItems}, 13 raw::{ImportSourceMap, RawItems},
14 CrateDefMap, 14 CrateDefMap,
15 }, 15 },
16 DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, 16 traits::{TraitData, TraitItemsIndex},
17 DefWithBodyId, EnumId, FunctionLoc, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId,
17}; 18};
18 19
19#[salsa::query_group(InternDatabaseStorage)] 20#[salsa::query_group(InternDatabaseStorage)]
20pub trait InternDatabase: SourceDatabase { 21pub trait InternDatabase: SourceDatabase {
21 #[salsa::interned] 22 #[salsa::interned]
22 fn intern_function(&self, loc: ItemLoc<ast::FnDef>) -> crate::FunctionId; 23 fn intern_function(&self, loc: FunctionLoc) -> crate::FunctionId;
23 #[salsa::interned] 24 #[salsa::interned]
24 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId; 25 fn intern_struct_or_union(&self, loc: ItemLoc<ast::StructDef>) -> crate::StructOrUnionId;
25 #[salsa::interned] 26 #[salsa::interned]
@@ -59,6 +60,12 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
59 #[salsa::invoke(ImplData::impl_data_query)] 60 #[salsa::invoke(ImplData::impl_data_query)]
60 fn impl_data(&self, e: ImplId) -> Arc<ImplData>; 61 fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
61 62
63 #[salsa::invoke(TraitData::trait_data_query)]
64 fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
65
66 #[salsa::invoke(TraitItemsIndex::trait_items_index)]
67 fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex;
68
62 #[salsa::invoke(Body::body_with_source_map_query)] 69 #[salsa::invoke(Body::body_with_source_map_query)]
63 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); 70 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
64 71
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 4adfc16bb..11dd2a948 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -11,7 +11,7 @@ use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
11use crate::{ 11use crate::{
12 db::DefDatabase2, 12 db::DefDatabase2,
13 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TypeBound, TypeRef},
14 AdtId, AstItemDef, GenericDefId, 14 AdtId, AstItemDef, GenericDefId, HasSource, Lookup,
15}; 15};
16 16
17/// Data about a generic parameter (to a function, struct, impl, ...). 17/// Data about a generic parameter (to a function, struct, impl, ...).
@@ -53,7 +53,7 @@ impl GenericParams {
53 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; 53 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
54 // FIXME: add `: Sized` bound for everything except for `Self` in traits 54 // FIXME: add `: Sized` bound for everything except for `Self` in traits
55 match def { 55 match def {
56 GenericDefId::FunctionId(it) => generics.fill(&it.source(db).value, start), 56 GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start),
57 GenericDefId::AdtId(AdtId::StructId(it)) => { 57 GenericDefId::AdtId(AdtId::StructId(it)) => {
58 generics.fill(&it.0.source(db).value, start) 58 generics.fill(&it.0.source(db).value, start)
59 } 59 }
diff --git a/crates/ra_hir_def/src/imp.rs b/crates/ra_hir_def/src/impls.rs
index 4323dfcb6..9be38c5e1 100644
--- a/crates/ra_hir_def/src/imp.rs
+++ b/crates/ra_hir_def/src/impls.rs
@@ -5,11 +5,12 @@
5 5
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use hir_expand::AstId;
8use ra_syntax::ast; 9use ra_syntax::ast;
9 10
10use crate::{ 11use crate::{
11 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionId, ImplId, 12 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionContainerId,
12 LocationCtx, TypeAliasId, 13 FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasId,
13}; 14};
14 15
15#[derive(Debug, Clone, PartialEq, Eq)] 16#[derive(Debug, Clone, PartialEq, Eq)]
@@ -35,7 +36,12 @@ impl ImplData {
35 .impl_items() 36 .impl_items()
36 .map(|item_node| match item_node { 37 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => { 38 ast::ImplItem::FnDef(it) => {
38 FunctionId::from_ast_id(ctx, items.ast_id(&it)).into() 39 let func_id = FunctionLoc {
40 container: FunctionContainerId::ImplId(id),
41 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
42 }
43 .intern(db);
44 func_id.into()
39 } 45 }
40 ast::ImplItem::ConstDef(it) => { 46 ast::ImplItem::ConstDef(it) => {
41 ConstId::from_ast_id(ctx, items.ast_id(&it)).into() 47 ConstId::from_ast_id(ctx, items.ast_id(&it)).into()
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index dffc82ff8..b9a13776f 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -13,11 +13,12 @@ pub mod path;
13pub mod type_ref; 13pub mod type_ref;
14pub mod builtin_type; 14pub mod builtin_type;
15pub mod adt; 15pub mod adt;
16pub mod imp; 16pub mod impls;
17pub mod diagnostics; 17pub mod diagnostics;
18pub mod expr; 18pub mod expr;
19pub mod body; 19pub mod body;
20pub mod generics; 20pub mod generics;
21pub mod traits;
21 22
22#[cfg(test)] 23#[cfg(test)]
23mod test_db; 24mod test_db;
@@ -198,16 +199,34 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
198pub struct FunctionId(salsa::InternId); 199pub struct FunctionId(salsa::InternId);
199impl_intern_key!(FunctionId); 200impl_intern_key!(FunctionId);
200 201
201impl AstItemDef<ast::FnDef> for FunctionId { 202#[derive(Debug, Clone, PartialEq, Eq, Hash)]
202 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self { 203pub struct FunctionLoc {
203 db.intern_function(loc) 204 pub container: FunctionContainerId,
205 pub ast_id: AstId<ast::FnDef>,
206}
207
208impl Intern for FunctionLoc {
209 type ID = FunctionId;
210 fn intern(self, db: &impl db::DefDatabase2) -> FunctionId {
211 db.intern_function(self)
204 } 212 }
205 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::FnDef> { 213}
206 db.lookup_intern_function(self) 214
215impl Lookup for FunctionId {
216 type Data = FunctionLoc;
217 fn lookup(&self, db: &impl db::DefDatabase2) -> FunctionLoc {
218 db.lookup_intern_function(*self)
207 } 219 }
208} 220}
209 221
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
223pub enum FunctionContainerId {
224 ModuleId(ModuleId),
225 ImplId(ImplId),
226 TraitId(TraitId),
227}
228
229#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
211pub struct StructOrUnionId(salsa::InternId); 230pub struct StructOrUnionId(salsa::InternId);
212impl_intern_key!(StructOrUnionId); 231impl_intern_key!(StructOrUnionId);
213impl AstItemDef<ast::StructDef> for StructOrUnionId { 232impl AstItemDef<ast::StructDef> for StructOrUnionId {
@@ -432,3 +451,41 @@ impl_froms!(
432 EnumVariantId, 451 EnumVariantId,
433 ConstId 452 ConstId
434); 453);
454
455trait Intern {
456 type ID;
457 fn intern(self, db: &impl db::DefDatabase2) -> Self::ID;
458}
459
460pub trait Lookup {
461 type Data;
462 fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data;
463}
464
465pub trait HasModule {
466 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId;
467}
468
469impl HasModule for FunctionLoc {
470 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
471 match self.container {
472 FunctionContainerId::ModuleId(it) => it,
473 FunctionContainerId::ImplId(it) => it.module(db),
474 FunctionContainerId::TraitId(it) => it.module(db),
475 }
476 }
477}
478
479pub trait HasSource {
480 type Value;
481 fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>;
482}
483
484impl HasSource for FunctionLoc {
485 type Value = ast::FnDef;
486
487 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::FnDef> {
488 let node = self.ast_id.to_node(db);
489 Source::new(self.ast_id.file_id(), node)
490 }
491}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index e5b073a0f..c01e020ef 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -165,6 +165,14 @@ impl ModuleScope {
165 self.items.iter().chain(BUILTIN_SCOPE.iter()) 165 self.items.iter().chain(BUILTIN_SCOPE.iter())
166 } 166 }
167 167
168 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
169 self.entries()
170 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
171 .flat_map(|per_ns| {
172 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
173 })
174 }
175
168 /// Iterate over all module scoped macros 176 /// Iterate over all module scoped macros
169 pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { 177 pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
170 self.items 178 self.items
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8f426b097..d2ed94a87 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -19,9 +19,9 @@ use crate::{
19 per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode, 19 per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
20 }, 20 },
21 path::{Path, PathKind}, 21 path::{Path, PathKind},
22 AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, ImplId, 22 AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionContainerId,
23 LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, 23 FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
24 UnionId, 24 StructOrUnionId, TraitId, TypeAliasId, UnionId,
25}; 25};
26 26
27pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { 27pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -673,7 +673,12 @@ where
673 let name = def.name.clone(); 673 let name = def.name.clone();
674 let def: PerNs = match def.kind { 674 let def: PerNs = match def.kind {
675 raw::DefKind::Function(ast_id) => { 675 raw::DefKind::Function(ast_id) => {
676 let f = FunctionId::from_ast_id(ctx, ast_id); 676 let f = FunctionLoc {
677 container: FunctionContainerId::ModuleId(module),
678 ast_id: AstId::new(self.file_id, ast_id),
679 }
680 .intern(self.def_collector.db);
681
677 PerNs::values(f.into()) 682 PerNs::values(f.into())
678 } 683 }
679 raw::DefKind::Struct(ast_id) => { 684 raw::DefKind::Struct(ast_id) => {
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs
new file mode 100644
index 000000000..6e36bc0d0
--- /dev/null
+++ b/crates/ra_hir_def/src/traits.rs
@@ -0,0 +1,82 @@
1//! HIR for trait definitions.
2
3use std::sync::Arc;
4
5use hir_expand::{
6 name::{AsName, Name},
7 AstId,
8};
9
10use ra_syntax::ast::{self, NameOwner};
11use rustc_hash::FxHashMap;
12
13use crate::{
14 db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern,
15 LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId,
16};
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct TraitData {
20 pub name: Option<Name>,
21 pub items: Vec<AssocItemId>,
22 pub auto: bool,
23}
24
25impl TraitData {
26 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
27 let src = tr.source(db);
28 let name = src.value.name().map(|n| n.as_name());
29 let module = tr.module(db);
30 let ctx = LocationCtx::new(db, module, src.file_id);
31 let auto = src.value.is_auto();
32 let ast_id_map = db.ast_id_map(src.file_id);
33 let items = if let Some(item_list) = src.value.item_list() {
34 item_list
35 .impl_items()
36 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => FunctionLoc {
38 container: FunctionContainerId::TraitId(tr),
39 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
40 }
41 .intern(db)
42 .into(),
43 ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(),
44 ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(),
45 })
46 .collect()
47 } else {
48 Vec::new()
49 };
50 Arc::new(TraitData { name, items, auto })
51 }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct TraitItemsIndex {
56 traits_by_def: FxHashMap<AssocItemId, TraitId>,
57}
58
59impl TraitItemsIndex {
60 pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex {
61 let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
62 let crate_def_map = db.crate_def_map(module.krate);
63 for decl in crate_def_map[module.module_id].scope.declarations() {
64 if let ModuleDefId::TraitId(tr) = decl {
65 for item in db.trait_data(tr).items.iter() {
66 match item {
67 AssocItemId::FunctionId(_) => (),
68 _ => {
69 let prev = index.traits_by_def.insert(*item, tr);
70 assert!(prev.is_none());
71 }
72 }
73 }
74 }
75 }
76 index
77 }
78
79 pub fn get_parent_trait(&self, item: AssocItemId) -> Option<TraitId> {
80 self.traits_by_def.get(&item).cloned()
81 }
82}