diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 59 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 137 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/impls.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 103 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 53 | ||||
-rw-r--r-- | crates/ra_ide_api/src/change.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide_api/src/hover.rs | 8 |
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 | }; |
18 | use hir_expand::{ | 18 | use 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 | ||
730 | impl Const { | 730 | impl 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 | ||
955 | impl TypeAlias { | 960 | impl 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 { | |||
120 | impl HasSource for Const { | 120 | impl 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 | } |
126 | impl HasSource for Static { | 126 | impl HasSource for Static { |
@@ -138,7 +138,7 @@ impl HasSource for Trait { | |||
138 | impl HasSource for TypeAlias { | 138 | impl 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 | } |
144 | impl HasSource for MacroDef { | 144 | impl 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 | }; |
31 | pub use hir_expand::db::{ | 30 | pub 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}; | |||
4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 4 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
5 | use ra_syntax::{ | 5 | use 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 | ||
10 | use crate::{ | 10 | use crate::{ |
@@ -52,56 +52,54 @@ impl FromSource for Trait { | |||
52 | impl FromSource for Function { | 52 | impl 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 | ||
100 | impl FromSource for Const { | 79 | impl 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 | } |
107 | impl FromSource for Static { | 105 | impl FromSource for Static { |
@@ -114,8 +112,27 @@ impl FromSource for Static { | |||
114 | impl FromSource for TypeAlias { | 112 | impl 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 | ||
278 | enum Container { | ||
279 | Trait(Trait), | ||
280 | ImplBlock(ImplBlock), | ||
281 | Module(Module), | ||
282 | } | ||
283 | |||
284 | impl 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. |
267 | fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool { | 316 | fn 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 | ||
21 | impl ImplBlock { | 21 | impl 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 | ||
433 | fn scope_for( | 438 | fn 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 | ||
4 | mod autoderef; | 4 | mod autoderef; |
5 | pub(crate) mod primitive; | 5 | pub(crate) mod primitive; |
6 | #[cfg(test)] | ||
7 | mod tests; | ||
8 | pub(crate) mod traits; | 6 | pub(crate) mod traits; |
9 | pub(crate) mod method_resolution; | 7 | pub(crate) mod method_resolution; |
10 | mod op; | 8 | mod op; |
@@ -12,6 +10,9 @@ mod lower; | |||
12 | mod infer; | 10 | mod infer; |
13 | pub(crate) mod display; | 11 | pub(crate) mod display; |
14 | 12 | ||
13 | #[cfg(test)] | ||
14 | mod tests; | ||
15 | |||
15 | use std::ops::Deref; | 16 | use std::ops::Deref; |
16 | use std::sync::Arc; | 17 | use std::sync::Arc; |
17 | use std::{fmt, iter, mem}; | 18 | use 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 | }; |
14 | use rustc_hash::FxHashSet; | ||
14 | use test_utils::covers; | 15 | use test_utils::covers; |
15 | 16 | ||
16 | use crate::{ | 17 | use 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)] |
21 | pub trait InternDatabase: SourceDatabase { | 21 | pub 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; | |||
9 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
10 | 10 | ||
11 | use crate::{ | 11 | use 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)] |
203 | pub struct FunctionLoc { | 203 | pub 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)] |
223 | pub enum FunctionContainerId { | ||
224 | ModuleId(ModuleId), | ||
225 | ImplId(ImplId), | ||
226 | TraitId(TraitId), | ||
227 | } | ||
228 | |||
229 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
230 | pub struct StructOrUnionId(salsa::InternId); | 223 | pub struct StructOrUnionId(salsa::InternId); |
231 | impl_intern_key!(StructOrUnionId); | 224 | impl_intern_key!(StructOrUnionId); |
232 | impl AstItemDef<ast::StructDef> for StructOrUnionId { | 225 | impl 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)] |
297 | pub struct ConstId(salsa::InternId); | 290 | pub struct ConstId(salsa::InternId); |
298 | impl_intern_key!(ConstId); | 291 | impl_intern_key!(ConstId); |
299 | impl AstItemDef<ast::ConstDef> for ConstId { | 292 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
300 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::ConstDef>) -> Self { | 293 | pub struct ConstLoc { |
301 | db.intern_const(loc) | 294 | pub container: ContainerId, |
295 | pub ast_id: AstId<ast::ConstDef>, | ||
296 | } | ||
297 | |||
298 | impl 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 | |
305 | impl 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)] |
333 | pub struct TypeAliasId(salsa::InternId); | 337 | pub struct TypeAliasId(salsa::InternId); |
334 | impl_intern_key!(TypeAliasId); | 338 | impl_intern_key!(TypeAliasId); |
335 | impl 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) | 341 | pub struct TypeAliasLoc { |
342 | pub container: ContainerId, | ||
343 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
344 | } | ||
345 | |||
346 | impl 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 | |
353 | impl 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)] | ||
392 | pub 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)] |
377 | pub enum AdtId { | 400 | pub enum AdtId { |
@@ -469,9 +492,29 @@ pub trait HasModule { | |||
469 | impl HasModule for FunctionLoc { | 492 | impl 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 | |||
502 | impl 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 | |||
512 | impl 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 | |||
536 | impl 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 | |||
545 | impl 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 | ||
27 | pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { | 27 | pub(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 | ||
10 | use ra_syntax::ast::{self, NameOwner}; | 10 | use ra_syntax::ast::{self, NameOwner}; |
11 | use rustc_hash::FxHashMap; | ||
12 | 11 | ||
13 | use crate::{ | 12 | use 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)] | ||
55 | pub struct TraitItemsIndex { | ||
56 | traits_by_def: FxHashMap<AssocItemId, TraitId>, | ||
57 | } | ||
58 | |||
59 | impl 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 | ); |