aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs59
-rw-r--r--crates/ra_hir/src/code_model/src.rs4
-rw-r--r--crates/ra_hir/src/db.rs1
-rw-r--r--crates/ra_hir/src/from_source.rs137
-rw-r--r--crates/ra_hir/src/impl_block.rs8
-rw-r--r--crates/ra_hir/src/source_binder.rs7
-rw-r--r--crates/ra_hir/src/ty.rs5
-rw-r--r--crates/ra_hir/src/ty/tests.rs7
-rw-r--r--crates/ra_hir_def/src/body.rs1
-rw-r--r--crates/ra_hir_def/src/db.rs13
-rw-r--r--crates/ra_hir_def/src/generics.rs2
-rw-r--r--crates/ra_hir_def/src/impls.rs25
-rw-r--r--crates/ra_hir_def/src/lib.rs103
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs28
-rw-r--r--crates/ra_hir_def/src/traits.rs53
-rw-r--r--crates/ra_ide_api/src/change.rs1
-rw-r--r--crates/ra_ide_api/src/hover.rs8
17 files changed, 287 insertions, 175 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index c49190a0f..920899dce 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -12,7 +12,7 @@ use hir_def::{
12 builtin_type::BuiltinType, 12 builtin_type::BuiltinType,
13 traits::TraitData, 13 traits::TraitData,
14 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
15 AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, 15 AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId,
16 LocalStructFieldId, Lookup, ModuleId, UnionId, 16 LocalStructFieldId, Lookup, ModuleId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
@@ -697,9 +697,9 @@ impl Function {
697 697
698 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 698 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
699 match self.id.lookup(db).container { 699 match self.id.lookup(db).container {
700 FunctionContainerId::TraitId(it) => Some(Container::Trait(it.into())), 700 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
701 FunctionContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), 701 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
702 FunctionContainerId::ModuleId(_) => None, 702 ContainerId::ModuleId(_) => None,
703 } 703 }
704 } 704 }
705 705
@@ -729,7 +729,7 @@ pub struct Const {
729 729
730impl Const { 730impl Const {
731 pub fn module(self, db: &impl DefDatabase) -> Module { 731 pub fn module(self, db: &impl DefDatabase) -> Module {
732 Module { id: self.id.module(db) } 732 Module { id: self.id.lookup(db).module(db) }
733 } 733 }
734 734
735 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 735 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
@@ -748,22 +748,27 @@ impl Const {
748 db.infer(self.into()) 748 db.infer(self.into())
749 } 749 }
750 750
751 /// The containing impl block, if this is a method. 751 /// The containing impl block, if this is a type alias.
752 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 752 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
753 ImplBlock::containing(db, self.into()) 753 match self.container(db) {
754 Some(Container::ImplBlock(it)) => Some(it),
755 _ => None,
756 }
754 } 757 }
755 758
759 /// The containing trait, if this is a trait type alias definition.
756 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 760 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
757 db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) 761 match self.container(db) {
762 Some(Container::Trait(it)) => Some(it),
763 _ => None,
764 }
758 } 765 }
759 766
760 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 767 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
761 if let Some(impl_block) = self.impl_block(db) { 768 match self.id.lookup(db).container {
762 Some(impl_block.into()) 769 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
763 } else if let Some(trait_) = self.parent_trait(db) { 770 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
764 Some(trait_.into()) 771 ContainerId::ModuleId(_) => None,
765 } else {
766 None
767 } 772 }
768 } 773 }
769 774
@@ -954,30 +959,34 @@ pub struct TypeAlias {
954 959
955impl TypeAlias { 960impl TypeAlias {
956 pub fn module(self, db: &impl DefDatabase) -> Module { 961 pub fn module(self, db: &impl DefDatabase) -> Module {
957 Module { id: self.id.module(db) } 962 Module { id: self.id.lookup(db).module(db) }
958 } 963 }
959 964
960 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { 965 pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
961 Some(self.module(db).krate()) 966 Some(self.module(db).krate())
962 } 967 }
963 968
964 /// The containing impl block, if this is a method. 969 /// The containing impl block, if this is a type alias.
965 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { 970 pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> {
966 ImplBlock::containing(db, self.into()) 971 match self.container(db) {
972 Some(Container::ImplBlock(it)) => Some(it),
973 _ => None,
974 }
967 } 975 }
968 976
969 /// The containing trait, if this is a trait method definition. 977 /// The containing trait, if this is a trait type alias definition.
970 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { 978 pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
971 db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) 979 match self.container(db) {
980 Some(Container::Trait(it)) => Some(it),
981 _ => None,
982 }
972 } 983 }
973 984
974 pub fn container(self, db: &impl DefDatabase) -> Option<Container> { 985 pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
975 if let Some(impl_block) = self.impl_block(db) { 986 match self.id.lookup(db).container {
976 Some(impl_block.into()) 987 ContainerId::TraitId(it) => Some(Container::Trait(it.into())),
977 } else if let Some(trait_) = self.parent_trait(db) { 988 ContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())),
978 Some(trait_.into()) 989 ContainerId::ModuleId(_) => None,
979 } else {
980 None
981 } 990 }
982 } 991 }
983 992
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 91cab7414..354d2c98f 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -120,7 +120,7 @@ impl HasSource for Function {
120impl HasSource for Const { 120impl HasSource for Const {
121 type Ast = ast::ConstDef; 121 type Ast = ast::ConstDef;
122 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { 122 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> {
123 self.id.source(db) 123 self.id.lookup(db).source(db)
124 } 124 }
125} 125}
126impl HasSource for Static { 126impl HasSource for Static {
@@ -138,7 +138,7 @@ impl HasSource for Trait {
138impl HasSource for TypeAlias { 138impl HasSource for TypeAlias {
139 type Ast = ast::TypeAliasDef; 139 type Ast = ast::TypeAliasDef;
140 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { 140 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> {
141 self.id.source(db) 141 self.id.lookup(db).source(db)
142 } 142 }
143} 143}
144impl HasSource for MacroDef { 144impl HasSource for MacroDef {
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 73859e1e9..5bb7961b3 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -26,7 +26,6 @@ pub use hir_def::db::{
26 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, 26 BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
27 EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 27 EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
28 RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, 28 RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery,
29 TraitItemsIndexQuery,
30}; 29};
31pub use hir_expand::db::{ 30pub use hir_expand::db::{
32 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 31 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 303d5f138..b86307c58 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -4,7 +4,7 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 4use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, NameOwner}, 6 ast::{self, AstNode, NameOwner},
7 match_ast, AstPtr, 7 match_ast, AstPtr, SyntaxNode,
8}; 8};
9 9
10use crate::{ 10use crate::{
@@ -52,56 +52,54 @@ impl FromSource for Trait {
52impl FromSource for Function { 52impl FromSource for Function {
53 type Ast = ast::FnDef; 53 type Ast = ast::FnDef;
54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 54 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
55 // FIXME: this doesn't try to handle nested declarations 55 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
56 for container in src.value.syntax().ancestors() { 56 Container::Trait(it) => it.items(db),
57 let res = match_ast! { 57 Container::ImplBlock(it) => it.items(db),
58 match container { 58 Container::Module(m) => {
59 ast::TraitDef(it) => { 59 return m
60 let c = Trait::from_source(db, src.with_value(it))?; 60 .declarations(db)
61 c.items(db) 61 .into_iter()
62 .into_iter() 62 .filter_map(|it| match it {
63 .filter_map(|it| match it { 63 ModuleDef::Function(it) => Some(it),
64 AssocItem::Function(it) => Some(it), 64 _ => None,
65 _ => None 65 })
66 }) 66 .find(|it| same_source(&it.source(db), &src))
67 .find(|it| same_source(&it.source(db), &src))? 67 }
68 }, 68 };
69 ast::ImplBlock(it) => { 69 items
70 let c = ImplBlock::from_source(db, src.with_value(it))?;
71 c.items(db)
72 .into_iter()
73 .filter_map(|it| match it {
74 AssocItem::Function(it) => Some(it),
75 _ => None
76 })
77 .find(|it| same_source(&it.source(db), &src))?
78
79 },
80 _ => { continue },
81 }
82 };
83 return Some(res);
84 }
85
86 let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
87 let c = Module::from_definition(db, src.with_value(module_source))?;
88 let res = c
89 .declarations(db)
90 .into_iter() 70 .into_iter()
91 .filter_map(|it| match it { 71 .filter_map(|it| match it {
92 ModuleDef::Function(it) => Some(it), 72 AssocItem::Function(it) => Some(it),
93 _ => None, 73 _ => None,
94 }) 74 })
95 .find(|it| same_source(&it.source(db), &src)); 75 .find(|it| same_source(&it.source(db), &src))
96 res
97 } 76 }
98} 77}
99 78
100impl FromSource for Const { 79impl FromSource for Const {
101 type Ast = ast::ConstDef; 80 type Ast = ast::ConstDef;
102 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 81 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
103 let id = from_source(db, src)?; 82 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
104 Some(Const { id }) 83 Container::Trait(it) => it.items(db),
84 Container::ImplBlock(it) => it.items(db),
85 Container::Module(m) => {
86 return m
87 .declarations(db)
88 .into_iter()
89 .filter_map(|it| match it {
90 ModuleDef::Const(it) => Some(it),
91 _ => None,
92 })
93 .find(|it| same_source(&it.source(db), &src))
94 }
95 };
96 items
97 .into_iter()
98 .filter_map(|it| match it {
99 AssocItem::Const(it) => Some(it),
100 _ => None,
101 })
102 .find(|it| same_source(&it.source(db), &src))
105 } 103 }
106} 104}
107impl FromSource for Static { 105impl FromSource for Static {
@@ -114,8 +112,27 @@ impl FromSource for Static {
114impl FromSource for TypeAlias { 112impl FromSource for TypeAlias {
115 type Ast = ast::TypeAliasDef; 113 type Ast = ast::TypeAliasDef;
116 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 114 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
117 let id = from_source(db, src)?; 115 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
118 Some(TypeAlias { id }) 116 Container::Trait(it) => it.items(db),
117 Container::ImplBlock(it) => it.items(db),
118 Container::Module(m) => {
119 return m
120 .declarations(db)
121 .into_iter()
122 .filter_map(|it| match it {
123 ModuleDef::TypeAlias(it) => Some(it),
124 _ => None,
125 })
126 .find(|it| same_source(&it.source(db), &src))
127 }
128 };
129 items
130 .into_iter()
131 .filter_map(|it| match it {
132 AssocItem::TypeAlias(it) => Some(it),
133 _ => None,
134 })
135 .find(|it| same_source(&it.source(db), &src))
119 } 136 }
120} 137}
121 138
@@ -258,11 +275,43 @@ where
258 Some(DEF::from_ast(ctx, &src.value)) 275 Some(DEF::from_ast(ctx, &src.value))
259} 276}
260 277
278enum Container {
279 Trait(Trait),
280 ImplBlock(ImplBlock),
281 Module(Module),
282}
283
284impl Container {
285 fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> {
286 // FIXME: this doesn't try to handle nested declarations
287 for container in src.value.ancestors() {
288 let res = match_ast! {
289 match container {
290 ast::TraitDef(it) => {
291 let c = Trait::from_source(db, src.with_value(it))?;
292 Container::Trait(c)
293 },
294 ast::ImplBlock(it) => {
295 let c = ImplBlock::from_source(db, src.with_value(it))?;
296 Container::ImplBlock(c)
297 },
298 _ => { continue },
299 }
300 };
301 return Some(res);
302 }
303
304 let module_source = ModuleSource::from_child_node(db, src);
305 let c = Module::from_definition(db, src.with_value(module_source))?;
306 Some(Container::Module(c))
307 }
308}
309
261/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are 310/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
262/// equal if they point to exactly the same object. 311/// equal if they point to exactly the same object.
263/// 312///
264/// In general, we do not guarantee that we have exactly one instance of a 313/// In general, we do not guarantee that we have exactly one instance of a
265/// syntax tree for each file. We probably should add such guanratree, but, for 314/// syntax tree for each file. We probably should add such guarantee, but, for
266/// the time being, we will use identity-less AstPtr comparison. 315/// the time being, we will use identity-less AstPtr comparison.
267fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool { 316fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool {
268 s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) 317 s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 0c2bb8fee..0513f28a9 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -19,14 +19,6 @@ impl HasSource for ImplBlock {
19} 19}
20 20
21impl ImplBlock { 21impl ImplBlock {
22 pub(crate) fn containing(db: &impl DefDatabase, item: AssocItem) -> Option<ImplBlock> {
23 let module = item.module(db);
24 let crate_def_map = db.crate_def_map(module.id.krate);
25 crate_def_map[module.id.module_id].impls.iter().copied().map(ImplBlock::from).find(|it| {
26 db.impl_data(it.id).items().iter().copied().map(AssocItem::from).any(|it| it == item)
27 })
28 }
29
30 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { 22 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
31 db.impl_data(self.id).target_trait().cloned() 23 db.impl_data(self.id).target_trait().cloned()
32 } 24 }
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index caa8d0082..fd9994098 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -71,7 +71,7 @@ fn def_with_body_from_child_node(
71 match_ast! { 71 match_ast! {
72 match node { 72 match node {
73 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, 73 ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); },
74 ast::ConstDef(def) => { Some(Const { id: ctx.to_def(&def) }.into()) }, 74 ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); },
75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, 75 ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) },
76 _ => { None }, 76 _ => { None },
77 } 77 }
@@ -428,6 +428,11 @@ impl SourceAnalyzer {
428 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { 428 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
429 self.infer.clone().unwrap() 429 self.infer.clone().unwrap()
430 } 430 }
431
432 #[cfg(test)]
433 pub(crate) fn analyzed_declaration(&self) -> Option<DefWithBody> {
434 self.body_owner
435 }
431} 436}
432 437
433fn scope_for( 438fn scope_for(
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 776613c7c..36ece723f 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -3,8 +3,6 @@
3 3
4mod autoderef; 4mod autoderef;
5pub(crate) mod primitive; 5pub(crate) mod primitive;
6#[cfg(test)]
7mod tests;
8pub(crate) mod traits; 6pub(crate) mod traits;
9pub(crate) mod method_resolution; 7pub(crate) mod method_resolution;
10mod op; 8mod op;
@@ -12,6 +10,9 @@ mod lower;
12mod infer; 10mod infer;
13pub(crate) mod display; 11pub(crate) mod display;
14 12
13#[cfg(test)]
14mod tests;
15
15use std::ops::Deref; 16use std::ops::Deref;
16use std::sync::Arc; 17use std::sync::Arc;
17use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index abfaffb5e..74c12a0a2 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -11,6 +11,7 @@ use ra_syntax::{
11 ast::{self, AstNode}, 11 ast::{self, AstNode},
12 SyntaxKind::*, 12 SyntaxKind::*,
13}; 13};
14use rustc_hash::FxHashSet;
14use test_utils::covers; 15use test_utils::covers;
15 16
16use crate::{ 17use crate::{
@@ -2518,7 +2519,6 @@ fn test() {
2518 [167; 179) 'GLOBAL_CONST': u32 2519 [167; 179) 'GLOBAL_CONST': u32
2519 [189; 191) 'id': u32 2520 [189; 191) 'id': u32
2520 [194; 210) 'Foo::A..._CONST': u32 2521 [194; 210) 'Foo::A..._CONST': u32
2521 [126; 128) '99': u32
2522 "### 2522 "###
2523 ); 2523 );
2524} 2524}
@@ -4742,10 +4742,13 @@ fn infer(content: &str) -> String {
4742 } 4742 }
4743 }; 4743 };
4744 4744
4745 let mut analyzed = FxHashSet::default();
4745 for node in source_file.syntax().descendants() { 4746 for node in source_file.syntax().descendants() {
4746 if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { 4747 if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF {
4747 let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); 4748 let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None);
4748 infer_def(analyzer.inference_result(), analyzer.body_source_map()); 4749 if analyzed.insert(analyzer.analyzed_declaration()) {
4750 infer_def(analyzer.inference_result(), analyzer.body_source_map());
4751 }
4749 } 4752 }
4750 } 4753 }
4751 4754
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index b69d4dea6..dfb79a30a 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -155,6 +155,7 @@ impl Body {
155 (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))
156 } 156 }
157 DefWithBodyId::ConstId(c) => { 157 DefWithBodyId::ConstId(c) => {
158 let c = c.lookup(db);
158 let src = c.source(db); 159 let src = c.source(db);
159 (src.file_id, c.module(db), src.value.body()) 160 (src.file_id, c.module(db), src.value.body())
160 } 161 }
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index e4ffdebe9..c6cd4369b 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -13,26 +13,26 @@ use crate::{
13 raw::{ImportSourceMap, RawItems}, 13 raw::{ImportSourceMap, RawItems},
14 CrateDefMap, 14 CrateDefMap,
15 }, 15 },
16 traits::{TraitData, TraitItemsIndex}, 16 traits::TraitData,
17 DefWithBodyId, EnumId, FunctionLoc, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId, 17 DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId, TraitId,
18}; 18};
19 19
20#[salsa::query_group(InternDatabaseStorage)] 20#[salsa::query_group(InternDatabaseStorage)]
21pub trait InternDatabase: SourceDatabase { 21pub trait InternDatabase: SourceDatabase {
22 #[salsa::interned] 22 #[salsa::interned]
23 fn intern_function(&self, loc: FunctionLoc) -> crate::FunctionId; 23 fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId;
24 #[salsa::interned] 24 #[salsa::interned]
25 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;
26 #[salsa::interned] 26 #[salsa::interned]
27 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId; 27 fn intern_enum(&self, loc: ItemLoc<ast::EnumDef>) -> crate::EnumId;
28 #[salsa::interned] 28 #[salsa::interned]
29 fn intern_const(&self, loc: ItemLoc<ast::ConstDef>) -> crate::ConstId; 29 fn intern_const(&self, loc: crate::ConstLoc) -> crate::ConstId;
30 #[salsa::interned] 30 #[salsa::interned]
31 fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId; 31 fn intern_static(&self, loc: ItemLoc<ast::StaticDef>) -> crate::StaticId;
32 #[salsa::interned] 32 #[salsa::interned]
33 fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId; 33 fn intern_trait(&self, loc: ItemLoc<ast::TraitDef>) -> crate::TraitId;
34 #[salsa::interned] 34 #[salsa::interned]
35 fn intern_type_alias(&self, loc: ItemLoc<ast::TypeAliasDef>) -> crate::TypeAliasId; 35 fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId;
36 #[salsa::interned] 36 #[salsa::interned]
37 fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId; 37 fn intern_impl(&self, loc: ItemLoc<ast::ImplBlock>) -> crate::ImplId;
38} 38}
@@ -63,9 +63,6 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
63 #[salsa::invoke(TraitData::trait_data_query)] 63 #[salsa::invoke(TraitData::trait_data_query)]
64 fn trait_data(&self, e: TraitId) -> Arc<TraitData>; 64 fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
65 65
66 #[salsa::invoke(TraitItemsIndex::trait_items_index)]
67 fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex;
68
69 #[salsa::invoke(Body::body_with_source_map_query)] 66 #[salsa::invoke(Body::body_with_source_map_query)]
70 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>); 67 fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
71 68
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 11dd2a948..17a5d5f43 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -72,7 +72,7 @@ impl GenericParams {
72 let self_param = TypeRef::Path(name::SELF_TYPE.into()); 72 let self_param = TypeRef::Path(name::SELF_TYPE.into());
73 generics.fill_bounds(&it.source(db).value, self_param); 73 generics.fill_bounds(&it.source(db).value, self_param);
74 } 74 }
75 GenericDefId::TypeAliasId(it) => generics.fill(&it.source(db).value, start), 75 GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start),
76 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 76 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
77 // type-parameter, but rather is a type-alias for impl's target 77 // type-parameter, but rather is a type-alias for impl's target
78 // type, so this is handled by the resolver. 78 // type, so this is handled by the resolver.
diff --git a/crates/ra_hir_def/src/impls.rs b/crates/ra_hir_def/src/impls.rs
index 9be38c5e1..750a869f2 100644
--- a/crates/ra_hir_def/src/impls.rs
+++ b/crates/ra_hir_def/src/impls.rs
@@ -9,8 +9,8 @@ use hir_expand::AstId;
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionContainerId, 12 db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstLoc, ContainerId,
13 FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasId, 13 FunctionLoc, ImplId, Intern, TypeAliasLoc,
14}; 14};
15 15
16#[derive(Debug, Clone, PartialEq, Eq)] 16#[derive(Debug, Clone, PartialEq, Eq)]
@@ -31,23 +31,32 @@ impl ImplData {
31 let negative = src.value.is_negative(); 31 let negative = src.value.is_negative();
32 32
33 let items = if let Some(item_list) = src.value.item_list() { 33 let items = if let Some(item_list) = src.value.item_list() {
34 let ctx = LocationCtx::new(db, id.module(db), src.file_id);
35 item_list 34 item_list
36 .impl_items() 35 .impl_items()
37 .map(|item_node| match item_node { 36 .map(|item_node| match item_node {
38 ast::ImplItem::FnDef(it) => { 37 ast::ImplItem::FnDef(it) => {
39 let func_id = FunctionLoc { 38 let def = FunctionLoc {
40 container: FunctionContainerId::ImplId(id), 39 container: ContainerId::ImplId(id),
41 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 40 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
42 } 41 }
43 .intern(db); 42 .intern(db);
44 func_id.into() 43 def.into()
45 } 44 }
46 ast::ImplItem::ConstDef(it) => { 45 ast::ImplItem::ConstDef(it) => {
47 ConstId::from_ast_id(ctx, items.ast_id(&it)).into() 46 let def = ConstLoc {
47 container: ContainerId::ImplId(id),
48 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
49 }
50 .intern(db);
51 def.into()
48 } 52 }
49 ast::ImplItem::TypeAliasDef(it) => { 53 ast::ImplItem::TypeAliasDef(it) => {
50 TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() 54 let def = TypeAliasLoc {
55 container: ContainerId::ImplId(id),
56 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
57 }
58 .intern(db);
59 def.into()
51 } 60 }
52 }) 61 })
53 .collect() 62 .collect()
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index b9a13776f..0af41de87 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -201,7 +201,7 @@ impl_intern_key!(FunctionId);
201 201
202#[derive(Debug, Clone, PartialEq, Eq, Hash)] 202#[derive(Debug, Clone, PartialEq, Eq, Hash)]
203pub struct FunctionLoc { 203pub struct FunctionLoc {
204 pub container: FunctionContainerId, 204 pub container: ContainerId,
205 pub ast_id: AstId<ast::FnDef>, 205 pub ast_id: AstId<ast::FnDef>,
206} 206}
207 207
@@ -220,13 +220,6 @@ impl Lookup for FunctionId {
220} 220}
221 221
222#[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)]
230pub struct StructOrUnionId(salsa::InternId); 223pub struct StructOrUnionId(salsa::InternId);
231impl_intern_key!(StructOrUnionId); 224impl_intern_key!(StructOrUnionId);
232impl AstItemDef<ast::StructDef> for StructOrUnionId { 225impl AstItemDef<ast::StructDef> for StructOrUnionId {
@@ -296,12 +289,23 @@ impl_arena_id!(LocalStructFieldId);
296#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 289#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
297pub struct ConstId(salsa::InternId); 290pub struct ConstId(salsa::InternId);
298impl_intern_key!(ConstId); 291impl_intern_key!(ConstId);
299impl AstItemDef<ast::ConstDef> for ConstId { 292#[derive(Debug, Clone, PartialEq, Eq, Hash)]
300 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { 293pub struct ConstLoc {
301 db.intern_const(loc) 294 pub container: ContainerId,
295 pub ast_id: AstId<ast::ConstDef>,
296}
297
298impl Intern for ConstLoc {
299 type ID = ConstId;
300 fn intern(self, db: &impl db::DefDatabase2) -> ConstId {
301 db.intern_const(self)
302 } 302 }
303 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::ConstDef> { 303}
304 db.lookup_intern_const(self) 304
305impl Lookup for ConstId {
306 type Data = ConstLoc;
307 fn lookup(&self, db: &impl db::DefDatabase2) -> ConstLoc {
308 db.lookup_intern_const(*self)
305 } 309 }
306} 310}
307 311
@@ -332,12 +336,24 @@ impl AstItemDef<ast::TraitDef> for TraitId {
332#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 336#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
333pub struct TypeAliasId(salsa::InternId); 337pub struct TypeAliasId(salsa::InternId);
334impl_intern_key!(TypeAliasId); 338impl_intern_key!(TypeAliasId);
335impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { 339
336 fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self { 340#[derive(Debug, Clone, PartialEq, Eq, Hash)]
337 db.intern_type_alias(loc) 341pub struct TypeAliasLoc {
342 pub container: ContainerId,
343 pub ast_id: AstId<ast::TypeAliasDef>,
344}
345
346impl Intern for TypeAliasLoc {
347 type ID = TypeAliasId;
348 fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId {
349 db.intern_type_alias(self)
338 } 350 }
339 fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc<ast::TypeAliasDef> { 351}
340 db.lookup_intern_type_alias(self) 352
353impl Lookup for TypeAliasId {
354 type Data = TypeAliasLoc;
355 fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc {
356 db.lookup_intern_type_alias(*self)
341 } 357 }
342} 358}
343 359
@@ -372,6 +388,13 @@ macro_rules! impl_froms {
372 } 388 }
373} 389}
374 390
391#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
392pub enum ContainerId {
393 ModuleId(ModuleId),
394 ImplId(ImplId),
395 TraitId(TraitId),
396}
397
375/// A Data Type 398/// A Data Type
376#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 399#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
377pub enum AdtId { 400pub enum AdtId {
@@ -469,9 +492,29 @@ pub trait HasModule {
469impl HasModule for FunctionLoc { 492impl HasModule for FunctionLoc {
470 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { 493 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
471 match self.container { 494 match self.container {
472 FunctionContainerId::ModuleId(it) => it, 495 ContainerId::ModuleId(it) => it,
473 FunctionContainerId::ImplId(it) => it.module(db), 496 ContainerId::ImplId(it) => it.module(db),
474 FunctionContainerId::TraitId(it) => it.module(db), 497 ContainerId::TraitId(it) => it.module(db),
498 }
499 }
500}
501
502impl HasModule for TypeAliasLoc {
503 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
504 match self.container {
505 ContainerId::ModuleId(it) => it,
506 ContainerId::ImplId(it) => it.module(db),
507 ContainerId::TraitId(it) => it.module(db),
508 }
509 }
510}
511
512impl HasModule for ConstLoc {
513 fn module(&self, db: &impl db::DefDatabase2) -> ModuleId {
514 match self.container {
515 ContainerId::ModuleId(it) => it,
516 ContainerId::ImplId(it) => it.module(db),
517 ContainerId::TraitId(it) => it.module(db),
475 } 518 }
476 } 519 }
477} 520}
@@ -489,3 +532,21 @@ impl HasSource for FunctionLoc {
489 Source::new(self.ast_id.file_id(), node) 532 Source::new(self.ast_id.file_id(), node)
490 } 533 }
491} 534}
535
536impl HasSource for TypeAliasLoc {
537 type Value = ast::TypeAliasDef;
538
539 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::TypeAliasDef> {
540 let node = self.ast_id.to_node(db);
541 Source::new(self.ast_id.file_id(), node)
542 }
543}
544
545impl HasSource for ConstLoc {
546 type Value = ast::ConstDef;
547
548 fn source(&self, db: &impl db::DefDatabase2) -> Source<ast::ConstDef> {
549 let node = self.ast_id.to_node(db);
550 Source::new(self.ast_id.file_id(), node)
551 }
552}
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index d2ed94a87..aae3dcadf 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, FunctionContainerId, 22 AdtId, AstId, AstItemDef, ConstLoc, ContainerId, CrateModuleId, EnumId, EnumVariantId,
23 FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, 23 FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId,
24 StructOrUnionId, TraitId, TypeAliasId, UnionId, 24 StructOrUnionId, TraitId, TypeAliasLoc, 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,13 +673,13 @@ 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 = FunctionLoc { 676 let def = FunctionLoc {
677 container: FunctionContainerId::ModuleId(module), 677 container: ContainerId::ModuleId(module),
678 ast_id: AstId::new(self.file_id, ast_id), 678 ast_id: AstId::new(self.file_id, ast_id),
679 } 679 }
680 .intern(self.def_collector.db); 680 .intern(self.def_collector.db);
681 681
682 PerNs::values(f.into()) 682 PerNs::values(def.into())
683 } 683 }
684 raw::DefKind::Struct(ast_id) => { 684 raw::DefKind::Struct(ast_id) => {
685 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); 685 let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
@@ -692,13 +692,27 @@ where
692 PerNs::both(u, u) 692 PerNs::both(u, u)
693 } 693 }
694 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), 694 raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
695 raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()), 695 raw::DefKind::Const(ast_id) => {
696 let def = ConstLoc {
697 container: ContainerId::ModuleId(module),
698 ast_id: AstId::new(self.file_id, ast_id),
699 }
700 .intern(self.def_collector.db);
701
702 PerNs::values(def.into())
703 }
696 raw::DefKind::Static(ast_id) => { 704 raw::DefKind::Static(ast_id) => {
697 PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) 705 PerNs::values(StaticId::from_ast_id(ctx, ast_id).into())
698 } 706 }
699 raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), 707 raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()),
700 raw::DefKind::TypeAlias(ast_id) => { 708 raw::DefKind::TypeAlias(ast_id) => {
701 PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into()) 709 let def = TypeAliasLoc {
710 container: ContainerId::ModuleId(module),
711 ast_id: AstId::new(self.file_id, ast_id),
712 }
713 .intern(self.def_collector.db);
714
715 PerNs::types(def.into())
702 } 716 }
703 }; 717 };
704 let resolution = Resolution { def, import: None }; 718 let resolution = Resolution { def, import: None };
diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs
index 6e36bc0d0..877d73d66 100644
--- a/crates/ra_hir_def/src/traits.rs
+++ b/crates/ra_hir_def/src/traits.rs
@@ -8,11 +8,10 @@ use hir_expand::{
8}; 8};
9 9
10use ra_syntax::ast::{self, NameOwner}; 10use ra_syntax::ast::{self, NameOwner};
11use rustc_hash::FxHashMap;
12 11
13use crate::{ 12use crate::{
14 db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, 13 db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId,
15 LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId, 14 TypeAliasLoc,
16}; 15};
17 16
18#[derive(Debug, Clone, PartialEq, Eq)] 17#[derive(Debug, Clone, PartialEq, Eq)]
@@ -26,8 +25,6 @@ impl TraitData {
26 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> { 25 pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
27 let src = tr.source(db); 26 let src = tr.source(db);
28 let name = src.value.name().map(|n| n.as_name()); 27 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(); 28 let auto = src.value.is_auto();
32 let ast_id_map = db.ast_id_map(src.file_id); 29 let ast_id_map = db.ast_id_map(src.file_id);
33 let items = if let Some(item_list) = src.value.item_list() { 30 let items = if let Some(item_list) = src.value.item_list() {
@@ -35,13 +32,23 @@ impl TraitData {
35 .impl_items() 32 .impl_items()
36 .map(|item_node| match item_node { 33 .map(|item_node| match item_node {
37 ast::ImplItem::FnDef(it) => FunctionLoc { 34 ast::ImplItem::FnDef(it) => FunctionLoc {
38 container: FunctionContainerId::TraitId(tr), 35 container: ContainerId::TraitId(tr),
36 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
37 }
38 .intern(db)
39 .into(),
40 ast::ImplItem::ConstDef(it) => ConstLoc {
41 container: ContainerId::TraitId(tr),
42 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
43 }
44 .intern(db)
45 .into(),
46 ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc {
47 container: ContainerId::TraitId(tr),
39 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), 48 ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)),
40 } 49 }
41 .intern(db) 50 .intern(db)
42 .into(), 51 .into(),
43 ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(),
44 ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(),
45 }) 52 })
46 .collect() 53 .collect()
47 } else { 54 } else {
@@ -50,33 +57,3 @@ impl TraitData {
50 Arc::new(TraitData { name, items, auto }) 57 Arc::new(TraitData { name, items, auto })
51 } 58 }
52} 59}
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}
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 5c9dec13e..3c607d5b5 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -309,7 +309,6 @@ impl RootDatabase {
309 hir::db::StructDataQuery 309 hir::db::StructDataQuery
310 hir::db::EnumDataQuery 310 hir::db::EnumDataQuery
311 hir::db::TraitDataQuery 311 hir::db::TraitDataQuery
312 hir::db::TraitItemsIndexQuery
313 hir::db::RawItemsWithSourceMapQuery 312 hir::db::RawItemsWithSourceMapQuery
314 hir::db::RawItemsQuery 313 hir::db::RawItemsQuery
315 hir::db::CrateDefMapQuery 314 hir::db::CrateDefMapQuery
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index ae87ab9f9..9839be985 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -404,9 +404,7 @@ mod tests {
404 check_hover_result( 404 check_hover_result(
405 r#" 405 r#"
406 //- /main.rs 406 //- /main.rs
407 fn main() { 407 const foo<|>: u32 = 0;
408 const foo<|>: u32 = 0;
409 }
410 "#, 408 "#,
411 &["const foo: u32"], 409 &["const foo: u32"],
412 ); 410 );
@@ -414,9 +412,7 @@ mod tests {
414 check_hover_result( 412 check_hover_result(
415 r#" 413 r#"
416 //- /main.rs 414 //- /main.rs
417 fn main() { 415 static foo<|>: u32 = 0;
418 static foo<|>: u32 = 0;
419 }
420 "#, 416 "#,
421 &["static foo: u32"], 417 &["static foo: u32"],
422 ); 418 );