diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 65 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/traits.rs | 82 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 4 | ||||
-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.rs | 69 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_def/src/traits.rs | 82 | ||||
-rw-r--r-- | crates/ra_ide_api/src/expand.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/expand_macro.rs | 10 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 10 |
19 files changed, 301 insertions, 160 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index cb990f4e2..c49190a0f 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -10,8 +10,10 @@ use hir_def::{ | |||
10 | adt::VariantData, | 10 | adt::VariantData, |
11 | body::scope::ExprScopes, | 11 | body::scope::ExprScopes, |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | traits::TraitData, | ||
13 | type_ref::{Mutability, TypeRef}, | 14 | type_ref::{Mutability, TypeRef}, |
14 | CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId, | 15 | AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, |
16 | LocalStructFieldId, Lookup, ModuleId, UnionId, | ||
15 | }; | 17 | }; |
16 | use hir_expand::{ | 18 | use hir_expand::{ |
17 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -30,7 +32,6 @@ use crate::{ | |||
30 | TypeAliasId, | 32 | TypeAliasId, |
31 | }, | 33 | }, |
32 | resolve::{Resolver, Scope, TypeNs}, | 34 | resolve::{Resolver, Scope, TypeNs}, |
33 | traits::TraitData, | ||
34 | ty::{InferenceResult, Namespace, TraitRef}, | 35 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, | 36 | Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, |
36 | }; | 37 | }; |
@@ -230,15 +231,7 @@ impl Module { | |||
230 | 231 | ||
231 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { | 232 | pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> { |
232 | let def_map = db.crate_def_map(self.id.krate); | 233 | let def_map = db.crate_def_map(self.id.krate); |
233 | def_map[self.id.module_id] | 234 | def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() |
234 | .scope | ||
235 | .entries() | ||
236 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) | ||
237 | .flat_map(|per_ns| { | ||
238 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
239 | }) | ||
240 | .map(ModuleDef::from) | ||
241 | .collect() | ||
242 | } | 235 | } |
243 | 236 | ||
244 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { | 237 | pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { |
@@ -655,7 +648,7 @@ impl FnData { | |||
655 | 648 | ||
656 | impl Function { | 649 | impl Function { |
657 | pub fn module(self, db: &impl DefDatabase) -> Module { | 650 | pub fn module(self, db: &impl DefDatabase) -> Module { |
658 | Module { id: self.id.module(db) } | 651 | self.id.lookup(db).module(db).into() |
659 | } | 652 | } |
660 | 653 | ||
661 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { | 654 | pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> { |
@@ -688,21 +681,25 @@ impl Function { | |||
688 | 681 | ||
689 | /// The containing impl block, if this is a method. | 682 | /// The containing impl block, if this is a method. |
690 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { | 683 | pub fn impl_block(self, db: &impl DefDatabase) -> Option<ImplBlock> { |
691 | ImplBlock::containing(db, self.into()) | 684 | match self.container(db) { |
685 | Some(Container::ImplBlock(it)) => Some(it), | ||
686 | _ => None, | ||
687 | } | ||
692 | } | 688 | } |
693 | 689 | ||
694 | /// The containing trait, if this is a trait method definition. | 690 | /// The containing trait, if this is a trait method definition. |
695 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 691 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
696 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 692 | match self.container(db) { |
693 | Some(Container::Trait(it)) => Some(it), | ||
694 | _ => None, | ||
695 | } | ||
697 | } | 696 | } |
698 | 697 | ||
699 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 698 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
700 | if let Some(impl_block) = self.impl_block(db) { | 699 | match self.id.lookup(db).container { |
701 | Some(impl_block.into()) | 700 | FunctionContainerId::TraitId(it) => Some(Container::Trait(it.into())), |
702 | } else if let Some(trait_) = self.parent_trait(db) { | 701 | FunctionContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), |
703 | Some(trait_.into()) | 702 | FunctionContainerId::ModuleId(_) => None, |
704 | } else { | ||
705 | None | ||
706 | } | 703 | } |
707 | } | 704 | } |
708 | 705 | ||
@@ -757,7 +754,7 @@ impl Const { | |||
757 | } | 754 | } |
758 | 755 | ||
759 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 756 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
760 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 757 | db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) |
761 | } | 758 | } |
762 | 759 | ||
763 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 760 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
@@ -861,11 +858,11 @@ impl Trait { | |||
861 | } | 858 | } |
862 | 859 | ||
863 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 860 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
864 | self.trait_data(db).name().clone() | 861 | self.trait_data(db).name.clone() |
865 | } | 862 | } |
866 | 863 | ||
867 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 864 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
868 | self.trait_data(db).items().to_vec() | 865 | self.trait_data(db).items.iter().map(|it| (*it).into()).collect() |
869 | } | 866 | } |
870 | 867 | ||
871 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 868 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
@@ -912,10 +909,10 @@ impl Trait { | |||
912 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 909 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
913 | let trait_data = self.trait_data(db); | 910 | let trait_data = self.trait_data(db); |
914 | trait_data | 911 | trait_data |
915 | .items() | 912 | .items |
916 | .iter() | 913 | .iter() |
917 | .filter_map(|item| match item { | 914 | .filter_map(|item| match item { |
918 | AssocItem::TypeAlias(t) => Some(*t), | 915 | AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), |
919 | _ => None, | 916 | _ => None, |
920 | }) | 917 | }) |
921 | .find(|t| &t.name(db) == name) | 918 | .find(|t| &t.name(db) == name) |
@@ -930,7 +927,7 @@ impl Trait { | |||
930 | } | 927 | } |
931 | 928 | ||
932 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | 929 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { |
933 | db.trait_data(self) | 930 | db.trait_data(self.id) |
934 | } | 931 | } |
935 | 932 | ||
936 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 933 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |
@@ -938,7 +935,7 @@ impl Trait { | |||
938 | } | 935 | } |
939 | 936 | ||
940 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 937 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
941 | self.trait_data(db).is_auto() | 938 | self.trait_data(db).auto |
942 | } | 939 | } |
943 | 940 | ||
944 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { | 941 | pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { |
@@ -971,7 +968,7 @@ impl TypeAlias { | |||
971 | 968 | ||
972 | /// The containing trait, if this is a trait method definition. | 969 | /// The containing trait, if this is a trait method definition. |
973 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { | 970 | pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> { |
974 | db.trait_items_index(self.module(db)).get_parent_trait(self.into()) | 971 | db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) |
975 | } | 972 | } |
976 | 973 | ||
977 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { | 974 | pub fn container(self, db: &impl DefDatabase) -> Option<Container> { |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 556417b0f..91cab7414 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{HasSource as _, Lookup}; | ||
3 | use ra_syntax::ast::{self, AstNode}; | 4 | use ra_syntax::ast::{self, AstNode}; |
4 | 5 | ||
5 | use crate::{ | 6 | use crate::{ |
@@ -113,7 +114,7 @@ impl HasSource for EnumVariant { | |||
113 | impl HasSource for Function { | 114 | impl HasSource for Function { |
114 | type Ast = ast::FnDef; | 115 | type Ast = ast::FnDef; |
115 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { | 116 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { |
116 | self.id.source(db) | 117 | self.id.lookup(db).source(db) |
117 | } | 118 | } |
118 | } | 119 | } |
119 | impl HasSource for Const { | 120 | impl HasSource for Const { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 0d35014a0..73859e1e9 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -11,7 +11,6 @@ use crate::{ | |||
11 | generics::{GenericDef, GenericParams}, | 11 | generics::{GenericDef, GenericParams}, |
12 | ids, | 12 | ids, |
13 | lang_item::{LangItemTarget, LangItems}, | 13 | lang_item::{LangItemTarget, LangItems}, |
14 | traits::TraitData, | ||
15 | ty::{ | 14 | ty::{ |
16 | method_resolution::CrateImplBlocks, | 15 | method_resolution::CrateImplBlocks, |
17 | traits::{AssocTyValue, Impl}, | 16 | traits::{AssocTyValue, Impl}, |
@@ -26,7 +25,8 @@ use crate::{ | |||
26 | pub use hir_def::db::{ | 25 | pub use hir_def::db::{ |
27 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, | 26 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, |
28 | EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 27 | EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
29 | RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, | 28 | RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery, |
29 | TraitItemsIndexQuery, | ||
30 | }; | 30 | }; |
31 | pub use hir_expand::db::{ | 31 | pub use hir_expand::db::{ |
32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 32 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
@@ -37,12 +37,6 @@ pub use hir_expand::db::{ | |||
37 | #[salsa::query_group(DefDatabaseStorage)] | 37 | #[salsa::query_group(DefDatabaseStorage)] |
38 | #[salsa::requires(AstDatabase)] | 38 | #[salsa::requires(AstDatabase)] |
39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | 39 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { |
40 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] | ||
41 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; | ||
42 | |||
43 | #[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)] | ||
44 | fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex; | ||
45 | |||
46 | #[salsa::invoke(crate::generics::generic_params_query)] | 40 | #[salsa::invoke(crate::generics::generic_params_query)] |
47 | fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>; | 41 | fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>; |
48 | 42 | ||
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f4dca25cb..303d5f138 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -4,15 +4,15 @@ 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, | 7 | match_ast, AstPtr, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | ids::{AstItemDef, LocationCtx}, | 12 | ids::{AstItemDef, LocationCtx}, |
13 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, | 13 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, |
14 | Local, MacroDef, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, | 14 | ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, |
15 | Union, VariantDef, | 15 | StructField, Trait, TypeAlias, Union, VariantDef, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub trait FromSource: Sized { | 18 | pub trait FromSource: Sized { |
@@ -52,10 +52,51 @@ 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 | let id = from_source(db, src)?; | 55 | // FIXME: this doesn't try to handle nested declarations |
56 | Some(Function { id }) | 56 | for container in src.value.syntax().ancestors() { |
57 | let res = match_ast! { | ||
58 | match container { | ||
59 | ast::TraitDef(it) => { | ||
60 | let c = Trait::from_source(db, src.with_value(it))?; | ||
61 | c.items(db) | ||
62 | .into_iter() | ||
63 | .filter_map(|it| match it { | ||
64 | AssocItem::Function(it) => Some(it), | ||
65 | _ => None | ||
66 | }) | ||
67 | .find(|it| same_source(&it.source(db), &src))? | ||
68 | }, | ||
69 | ast::ImplBlock(it) => { | ||
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() | ||
91 | .filter_map(|it| match it { | ||
92 | ModuleDef::Function(it) => Some(it), | ||
93 | _ => None, | ||
94 | }) | ||
95 | .find(|it| same_source(&it.source(db), &src)); | ||
96 | res | ||
57 | } | 97 | } |
58 | } | 98 | } |
99 | |||
59 | impl FromSource for Const { | 100 | impl FromSource for Const { |
60 | type Ast = ast::ConstDef; | 101 | type Ast = ast::ConstDef; |
61 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 102 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
@@ -108,7 +149,7 @@ impl FromSource for EnumVariant { | |||
108 | let parent_enum = src.value.parent_enum(); | 149 | let parent_enum = src.value.parent_enum(); |
109 | let src_enum = Source { file_id: src.file_id, value: parent_enum }; | 150 | let src_enum = Source { file_id: src.file_id, value: parent_enum }; |
110 | let variants = Enum::from_source(db, src_enum)?.variants(db); | 151 | let variants = Enum::from_source(db, src_enum)?.variants(db); |
111 | variants.into_iter().find(|v| v.source(db) == src) | 152 | variants.into_iter().find(|v| same_source(&v.source(db), &src)) |
112 | } | 153 | } |
113 | } | 154 | } |
114 | 155 | ||
@@ -216,3 +257,13 @@ where | |||
216 | let ctx = LocationCtx::new(db, module.id, src.file_id); | 257 | let ctx = LocationCtx::new(db, module.id, src.file_id); |
217 | Some(DEF::from_ast(ctx, &src.value)) | 258 | Some(DEF::from_ast(ctx, &src.value)) |
218 | } | 259 | } |
260 | |||
261 | /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are | ||
262 | /// equal if they point to exactly the same object. | ||
263 | /// | ||
264 | /// 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 | ||
266 | /// the time being, we will use identity-less AstPtr comparison. | ||
267 | 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) | ||
269 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index da33c9591..7ac9a9041 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -33,7 +33,6 @@ pub mod source_binder; | |||
33 | 33 | ||
34 | mod ids; | 34 | mod ids; |
35 | mod adt; | 35 | mod adt; |
36 | mod traits; | ||
37 | mod type_alias; | 36 | mod type_alias; |
38 | mod ty; | 37 | mod ty; |
39 | mod impl_block; | 38 | mod impl_block; |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a1c1daacd..caa8d0082 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -70,7 +70,7 @@ fn def_with_body_from_child_node( | |||
70 | child.value.ancestors().find_map(|node| { | 70 | child.value.ancestors().find_map(|node| { |
71 | match_ast! { | 71 | match_ast! { |
72 | match node { | 72 | match node { |
73 | ast::FnDef(def) => { Some(Function {id: ctx.to_def(&def) }.into()) }, | 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) => { Some(Const { id: ctx.to_def(&def) }.into()) }, |
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 }, |
@@ -405,9 +405,16 @@ impl SourceAnalyzer { | |||
405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) | 405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) |
406 | } | 406 | } |
407 | 407 | ||
408 | pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option<Expansion> { | 408 | pub fn expand( |
409 | let def = self.resolve_macro_call(db, macro_call)?.id; | 409 | &self, |
410 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); | 410 | db: &impl HirDatabase, |
411 | macro_call: Source<&ast::MacroCall>, | ||
412 | ) -> Option<Expansion> { | ||
413 | let def = self.resolve_macro_call(db, macro_call.value)?.id; | ||
414 | let ast_id = AstId::new( | ||
415 | macro_call.file_id, | ||
416 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | ||
417 | ); | ||
411 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 418 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
412 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 419 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) |
413 | } | 420 | } |
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs deleted file mode 100644 index 858972c6f..000000000 --- a/crates/ra_hir/src/traits.rs +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | //! HIR for trait definitions. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::name::AsName; | ||
6 | |||
7 | use ra_syntax::ast::{self, NameOwner}; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | |||
10 | use crate::{ | ||
11 | db::{AstDatabase, DefDatabase}, | ||
12 | ids::LocationCtx, | ||
13 | AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias, | ||
14 | }; | ||
15 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
17 | pub struct TraitData { | ||
18 | name: Option<Name>, | ||
19 | items: Vec<AssocItem>, | ||
20 | auto: bool, | ||
21 | } | ||
22 | |||
23 | impl TraitData { | ||
24 | pub(crate) fn trait_data_query( | ||
25 | db: &(impl DefDatabase + AstDatabase), | ||
26 | tr: Trait, | ||
27 | ) -> Arc<TraitData> { | ||
28 | let src = tr.source(db); | ||
29 | let name = src.value.name().map(|n| n.as_name()); | ||
30 | let module = tr.module(db); | ||
31 | let ctx = LocationCtx::new(db, module.id, src.file_id); | ||
32 | let auto = src.value.is_auto(); | ||
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) => Function { id: ctx.to_def(&it) }.into(), | ||
38 | ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(), | ||
39 | ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(), | ||
40 | }) | ||
41 | .collect() | ||
42 | } else { | ||
43 | Vec::new() | ||
44 | }; | ||
45 | Arc::new(TraitData { name, items, auto }) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn name(&self) -> &Option<Name> { | ||
49 | &self.name | ||
50 | } | ||
51 | |||
52 | pub(crate) fn items(&self) -> &[AssocItem] { | ||
53 | &self.items | ||
54 | } | ||
55 | |||
56 | pub(crate) fn is_auto(&self) -> bool { | ||
57 | self.auto | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
62 | pub struct TraitItemsIndex { | ||
63 | traits_by_def: FxHashMap<AssocItem, Trait>, | ||
64 | } | ||
65 | |||
66 | impl TraitItemsIndex { | ||
67 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | ||
68 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
69 | for decl in module.declarations(db) { | ||
70 | if let crate::ModuleDef::Trait(tr) = decl { | ||
71 | for item in tr.trait_data(db).items() { | ||
72 | index.traits_by_def.insert(*item, tr); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | index | ||
77 | } | ||
78 | |||
79 | pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option<Trait> { | ||
80 | self.traits_by_def.get(&item).cloned() | ||
81 | } | ||
82 | } | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index d20aeaacf..f377fca48 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>( | |||
232 | // trait, but if we find out it doesn't, we'll skip the rest of the | 232 | // trait, but if we find out it doesn't, we'll skip the rest of the |
233 | // iteration | 233 | // iteration |
234 | let mut known_implemented = false; | 234 | let mut known_implemented = false; |
235 | for &item in data.items() { | 235 | for &item in data.items.iter() { |
236 | if !is_valid_candidate(db, name, mode, item) { | 236 | if !is_valid_candidate(db, name, mode, item.into()) { |
237 | continue; | 237 | continue; |
238 | } | 238 | } |
239 | if !known_implemented { | 239 | if !known_implemented { |
@@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>( | |||
243 | } | 243 | } |
244 | } | 244 | } |
245 | known_implemented = true; | 245 | known_implemented = true; |
246 | if let Some(result) = callback(&ty.value, item) { | 246 | if let Some(result) = callback(&ty.value, item.into()) { |
247 | return Some(result); | 247 | return Some(result); |
248 | } | 248 | } |
249 | } | 249 | } |
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 | ||
23 | pub struct Expander { | 23 | pub 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; | |||
8 | use crate::{ | 8 | use 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)] |
20 | pub trait InternDatabase: SourceDatabase { | 21 | pub 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}; | |||
11 | use crate::{ | 11 | use 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 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use hir_expand::AstId; | ||
8 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
9 | 10 | ||
10 | use crate::{ | 11 | use 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; | |||
13 | pub mod type_ref; | 13 | pub mod type_ref; |
14 | pub mod builtin_type; | 14 | pub mod builtin_type; |
15 | pub mod adt; | 15 | pub mod adt; |
16 | pub mod imp; | 16 | pub mod impls; |
17 | pub mod diagnostics; | 17 | pub mod diagnostics; |
18 | pub mod expr; | 18 | pub mod expr; |
19 | pub mod body; | 19 | pub mod body; |
20 | pub mod generics; | 20 | pub mod generics; |
21 | pub mod traits; | ||
21 | 22 | ||
22 | #[cfg(test)] | 23 | #[cfg(test)] |
23 | mod test_db; | 24 | mod test_db; |
@@ -198,16 +199,34 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone { | |||
198 | pub struct FunctionId(salsa::InternId); | 199 | pub struct FunctionId(salsa::InternId); |
199 | impl_intern_key!(FunctionId); | 200 | impl_intern_key!(FunctionId); |
200 | 201 | ||
201 | impl AstItemDef<ast::FnDef> for FunctionId { | 202 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
202 | fn intern(db: &impl InternDatabase, loc: ItemLoc<ast::FnDef>) -> Self { | 203 | pub struct FunctionLoc { |
203 | db.intern_function(loc) | 204 | pub container: FunctionContainerId, |
205 | pub ast_id: AstId<ast::FnDef>, | ||
206 | } | ||
207 | |||
208 | impl 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 | |
215 | impl 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)] |
223 | pub enum FunctionContainerId { | ||
224 | ModuleId(ModuleId), | ||
225 | ImplId(ImplId), | ||
226 | TraitId(TraitId), | ||
227 | } | ||
228 | |||
229 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
211 | pub struct StructOrUnionId(salsa::InternId); | 230 | pub struct StructOrUnionId(salsa::InternId); |
212 | impl_intern_key!(StructOrUnionId); | 231 | impl_intern_key!(StructOrUnionId); |
213 | impl AstItemDef<ast::StructDef> for StructOrUnionId { | 232 | impl AstItemDef<ast::StructDef> for StructOrUnionId { |
@@ -432,3 +451,41 @@ impl_froms!( | |||
432 | EnumVariantId, | 451 | EnumVariantId, |
433 | ConstId | 452 | ConstId |
434 | ); | 453 | ); |
454 | |||
455 | trait Intern { | ||
456 | type ID; | ||
457 | fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; | ||
458 | } | ||
459 | |||
460 | pub trait Lookup { | ||
461 | type Data; | ||
462 | fn lookup(&self, db: &impl db::DefDatabase2) -> Self::Data; | ||
463 | } | ||
464 | |||
465 | pub trait HasModule { | ||
466 | fn module(&self, db: &impl db::DefDatabase2) -> ModuleId; | ||
467 | } | ||
468 | |||
469 | impl 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 | |||
479 | pub trait HasSource { | ||
480 | type Value; | ||
481 | fn source(&self, db: &impl db::DefDatabase2) -> Source<Self::Value>; | ||
482 | } | ||
483 | |||
484 | impl 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 | ||
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,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 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{ | ||
6 | name::{AsName, Name}, | ||
7 | AstId, | ||
8 | }; | ||
9 | |||
10 | use ra_syntax::ast::{self, NameOwner}; | ||
11 | use rustc_hash::FxHashMap; | ||
12 | |||
13 | use crate::{ | ||
14 | db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, | ||
15 | LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId, | ||
16 | }; | ||
17 | |||
18 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
19 | pub struct TraitData { | ||
20 | pub name: Option<Name>, | ||
21 | pub items: Vec<AssocItemId>, | ||
22 | pub auto: bool, | ||
23 | } | ||
24 | |||
25 | impl 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)] | ||
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/expand.rs b/crates/ra_ide_api/src/expand.rs index 0ad125a9e..2f1abf509 100644 --- a/crates/ra_ide_api/src/expand.rs +++ b/crates/ra_ide_api/src/expand.rs | |||
@@ -55,7 +55,7 @@ pub(crate) fn descend_into_macros( | |||
55 | } | 55 | } |
56 | let source_analyzer = | 56 | let source_analyzer = |
57 | hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None); | 57 | hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None); |
58 | let exp = source_analyzer.expand(db, ¯o_call)?; | 58 | let exp = source_analyzer.expand(db, token.with_value(¯o_call))?; |
59 | exp.map_token_down(db, token.as_ref()) | 59 | exp.map_token_down(db, token.as_ref()) |
60 | }) | 60 | }) |
61 | .last() | 61 | .last() |
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 2d478ec09..7f39262dc 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs | |||
@@ -23,7 +23,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; | 23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; |
24 | 24 | ||
25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); | 25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); |
26 | let expanded = expand_macro_recur(db, source, &mac)?; | 26 | let expanded = expand_macro_recur(db, source, source.with_value(&mac))?; |
27 | 27 | ||
28 | // FIXME: | 28 | // FIXME: |
29 | // macro expansion may lose all white space information | 29 | // macro expansion may lose all white space information |
@@ -35,10 +35,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
35 | fn expand_macro_recur( | 35 | fn expand_macro_recur( |
36 | db: &RootDatabase, | 36 | db: &RootDatabase, |
37 | source: hir::Source<&SyntaxNode>, | 37 | source: hir::Source<&SyntaxNode>, |
38 | macro_call: &ast::MacroCall, | 38 | macro_call: hir::Source<&ast::MacroCall>, |
39 | ) -> Option<SyntaxNode> { | 39 | ) -> Option<SyntaxNode> { |
40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); | 40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); |
41 | let expansion = analyzer.expand(db, ¯o_call)?; | 41 | let expansion = analyzer.expand(db, macro_call)?; |
42 | let macro_file_id = expansion.file_id(); | 42 | let macro_file_id = expansion.file_id(); |
43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; | 43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; |
44 | 44 | ||
@@ -46,8 +46,8 @@ fn expand_macro_recur( | |||
46 | let mut replaces = FxHashMap::default(); | 46 | let mut replaces = FxHashMap::default(); |
47 | 47 | ||
48 | for child in children.into_iter() { | 48 | for child in children.into_iter() { |
49 | let source = hir::Source::new(macro_file_id, source.value); | 49 | let node = hir::Source::new(macro_file_id, &child); |
50 | let new_node = expand_macro_recur(db, source, &child)?; | 50 | let new_node = expand_macro_recur(db, source, node)?; |
51 | 51 | ||
52 | replaces.insert(child.syntax().clone().into(), new_node.into()); | 52 | replaces.insert(child.syntax().clone().into(), new_node.into()); |
53 | } | 53 | } |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index 31167cada..e049fce61 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -43,7 +43,7 @@ impl SyntaxNodePtr { | |||
43 | } | 43 | } |
44 | 44 | ||
45 | /// Like `SyntaxNodePtr`, but remembers the type of node | 45 | /// Like `SyntaxNodePtr`, but remembers the type of node |
46 | #[derive(Debug, PartialEq, Eq, Hash)] | 46 | #[derive(Debug, Hash)] |
47 | pub struct AstPtr<N: AstNode> { | 47 | pub struct AstPtr<N: AstNode> { |
48 | raw: SyntaxNodePtr, | 48 | raw: SyntaxNodePtr, |
49 | _ty: PhantomData<fn() -> N>, | 49 | _ty: PhantomData<fn() -> N>, |
@@ -56,6 +56,14 @@ impl<N: AstNode> Clone for AstPtr<N> { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | impl<N: AstNode> Eq for AstPtr<N> {} | ||
60 | |||
61 | impl<N: AstNode> PartialEq for AstPtr<N> { | ||
62 | fn eq(&self, other: &AstPtr<N>) -> bool { | ||
63 | self.raw == other.raw | ||
64 | } | ||
65 | } | ||
66 | |||
59 | impl<N: AstNode> AstPtr<N> { | 67 | impl<N: AstNode> AstPtr<N> { |
60 | pub fn new(node: &N) -> AstPtr<N> { | 68 | pub fn new(node: &N) -> AstPtr<N> { |
61 | AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData } | 69 | AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData } |