diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 305 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/attrs.rs | 92 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/docs.rs | 97 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 112 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir/src/debug.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 46 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/lang_item.rs | 160 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir/src/test_db.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/coerce.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 55 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/type_alias.rs | 31 |
20 files changed, 386 insertions, 722 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 5690040a7..fd7776fb7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -1,8 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | pub(crate) mod src; | 3 | pub(crate) mod src; |
4 | pub(crate) mod docs; | ||
5 | pub(crate) mod attrs; | ||
6 | 4 | ||
7 | use std::sync::Arc; | 5 | use std::sync::Arc; |
8 | 6 | ||
@@ -10,29 +8,30 @@ use hir_def::{ | |||
10 | adt::VariantData, | 8 | adt::VariantData, |
11 | body::scope::ExprScopes, | 9 | body::scope::ExprScopes, |
12 | builtin_type::BuiltinType, | 10 | builtin_type::BuiltinType, |
13 | nameres::per_ns::PerNs, | 11 | docs::Documentation, |
12 | per_ns::PerNs, | ||
14 | resolver::{HasResolver, TypeNs}, | 13 | resolver::{HasResolver, TypeNs}, |
15 | traits::TraitData, | 14 | type_ref::TypeRef, |
16 | type_ref::{Mutability, TypeRef}, | 15 | ContainerId, HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, |
17 | ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, | 16 | LocalStructFieldId, Lookup, ModuleId, UnionId, |
18 | ModuleId, UnionId, | ||
19 | }; | 17 | }; |
20 | use hir_expand::{ | 18 | use hir_expand::{ |
21 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
22 | name::{self, AsName}, | 20 | name::{self, AsName}, |
21 | AstId, | ||
23 | }; | 22 | }; |
24 | use ra_db::{CrateId, Edition}; | 23 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
25 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | 24 | use ra_syntax::{ast, AstNode, SyntaxNode}; |
26 | 25 | ||
27 | use crate::{ | 26 | use crate::{ |
28 | db::{AstDatabase, DefDatabase, HirDatabase}, | 27 | db::{DefDatabase, HirDatabase}, |
29 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
30 | ids::{ | 29 | ids::{ |
31 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, | 30 | AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, |
32 | TypeAliasId, | 31 | TypeAliasId, |
33 | }, | 32 | }, |
34 | ty::{InferenceResult, Namespace, TraitRef}, | 33 | ty::{InferenceResult, Namespace, TraitRef}, |
35 | Either, HasSource, ImportId, Name, Source, Ty, | 34 | Either, HasSource, Name, Source, Ty, |
36 | }; | 35 | }; |
37 | 36 | ||
38 | /// hir::Crate describes a single crate. It's the main interface with which | 37 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -80,6 +79,64 @@ impl Crate { | |||
80 | } | 79 | } |
81 | } | 80 | } |
82 | 81 | ||
82 | pub enum ModuleSource { | ||
83 | SourceFile(ast::SourceFile), | ||
84 | Module(ast::Module), | ||
85 | } | ||
86 | |||
87 | impl ModuleSource { | ||
88 | pub fn new( | ||
89 | db: &impl DefDatabase, | ||
90 | file_id: Option<FileId>, | ||
91 | decl_id: Option<AstId<ast::Module>>, | ||
92 | ) -> ModuleSource { | ||
93 | match (file_id, decl_id) { | ||
94 | (Some(file_id), _) => { | ||
95 | let source_file = db.parse(file_id).tree(); | ||
96 | ModuleSource::SourceFile(source_file) | ||
97 | } | ||
98 | (None, Some(item_id)) => { | ||
99 | let module = item_id.to_node(db); | ||
100 | assert!(module.item_list().is_some(), "expected inline module"); | ||
101 | ModuleSource::Module(module) | ||
102 | } | ||
103 | (None, None) => panic!(), | ||
104 | } | ||
105 | } | ||
106 | |||
107 | // FIXME: this methods do not belong here | ||
108 | pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { | ||
109 | let parse = db.parse(position.file_id); | ||
110 | match &ra_syntax::algo::find_node_at_offset::<ast::Module>( | ||
111 | parse.tree().syntax(), | ||
112 | position.offset, | ||
113 | ) { | ||
114 | Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), | ||
115 | _ => { | ||
116 | let source_file = parse.tree(); | ||
117 | ModuleSource::SourceFile(source_file) | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { | ||
123 | if let Some(m) = | ||
124 | child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) | ||
125 | { | ||
126 | ModuleSource::Module(m) | ||
127 | } else { | ||
128 | let file_id = child.file_id.original_file(db); | ||
129 | let source_file = db.parse(file_id).tree(); | ||
130 | ModuleSource::SourceFile(source_file) | ||
131 | } | ||
132 | } | ||
133 | |||
134 | pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { | ||
135 | let source_file = db.parse(file_id).tree(); | ||
136 | ModuleSource::SourceFile(source_file) | ||
137 | } | ||
138 | } | ||
139 | |||
83 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 140 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
84 | pub struct Module { | 141 | pub struct Module { |
85 | pub(crate) id: ModuleId, | 142 | pub(crate) id: ModuleId, |
@@ -111,10 +168,10 @@ impl_froms!( | |||
111 | BuiltinType | 168 | BuiltinType |
112 | ); | 169 | ); |
113 | 170 | ||
114 | pub use hir_def::ModuleSource; | 171 | pub use hir_def::attr::Attrs; |
115 | 172 | ||
116 | impl Module { | 173 | impl Module { |
117 | pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module { | 174 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
118 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } | 175 | Module { id: ModuleId { krate: krate.crate_id, module_id: crate_module_id } } |
119 | } | 176 | } |
120 | 177 | ||
@@ -131,17 +188,6 @@ impl Module { | |||
131 | }) | 188 | }) |
132 | } | 189 | } |
133 | 190 | ||
134 | /// Returns the syntax of the last path segment corresponding to this import | ||
135 | pub fn import_source( | ||
136 | self, | ||
137 | db: &impl HirDatabase, | ||
138 | import: ImportId, | ||
139 | ) -> Either<ast::UseTree, ast::ExternCrateItem> { | ||
140 | let src = self.definition_source(db); | ||
141 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | ||
142 | source_map.get(&src.value, import) | ||
143 | } | ||
144 | |||
145 | /// Returns the crate this module is part of. | 191 | /// Returns the crate this module is part of. |
146 | pub fn krate(self) -> Crate { | 192 | pub fn krate(self) -> Crate { |
147 | Crate { crate_id: self.id.krate } | 193 | Crate { crate_id: self.id.krate } |
@@ -191,11 +237,13 @@ impl Module { | |||
191 | } | 237 | } |
192 | 238 | ||
193 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 239 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
194 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<ImportId>)> { | 240 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { |
195 | db.crate_def_map(self.id.krate)[self.id.module_id] | 241 | db.crate_def_map(self.id.krate)[self.id.module_id] |
196 | .scope | 242 | .scope |
197 | .entries() | 243 | .entries() |
198 | .map(|(name, res)| (name.clone(), res.def.into(), res.import)) | 244 | .map(|(name, res)| { |
245 | (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id })) | ||
246 | }) | ||
199 | .collect() | 247 | .collect() |
200 | } | 248 | } |
201 | 249 | ||
@@ -233,11 +281,16 @@ impl Module { | |||
233 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() | 281 | def_map[self.id.module_id].impls.iter().copied().map(ImplBlock::from).collect() |
234 | } | 282 | } |
235 | 283 | ||
236 | fn with_module_id(self, module_id: CrateModuleId) -> Module { | 284 | fn with_module_id(self, module_id: LocalModuleId) -> Module { |
237 | Module::new(self.krate(), module_id) | 285 | Module::new(self.krate(), module_id) |
238 | } | 286 | } |
239 | } | 287 | } |
240 | 288 | ||
289 | pub struct Import { | ||
290 | pub(crate) parent: Module, | ||
291 | pub(crate) id: LocalImportId, | ||
292 | } | ||
293 | |||
241 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 294 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
242 | pub struct StructField { | 295 | pub struct StructField { |
243 | pub(crate) parent: VariantDef, | 296 | pub(crate) parent: VariantDef, |
@@ -561,77 +614,6 @@ pub struct Function { | |||
561 | pub(crate) id: FunctionId, | 614 | pub(crate) id: FunctionId, |
562 | } | 615 | } |
563 | 616 | ||
564 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
565 | pub struct FnData { | ||
566 | pub(crate) name: Name, | ||
567 | pub(crate) params: Vec<TypeRef>, | ||
568 | pub(crate) ret_type: TypeRef, | ||
569 | /// True if the first param is `self`. This is relevant to decide whether this | ||
570 | /// can be called as a method. | ||
571 | pub(crate) has_self_param: bool, | ||
572 | } | ||
573 | |||
574 | impl FnData { | ||
575 | pub(crate) fn fn_data_query( | ||
576 | db: &(impl DefDatabase + AstDatabase), | ||
577 | func: Function, | ||
578 | ) -> Arc<FnData> { | ||
579 | let src = func.source(db); | ||
580 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | ||
581 | let mut params = Vec::new(); | ||
582 | let mut has_self_param = false; | ||
583 | if let Some(param_list) = src.value.param_list() { | ||
584 | if let Some(self_param) = param_list.self_param() { | ||
585 | let self_type = if let Some(type_ref) = self_param.ascribed_type() { | ||
586 | TypeRef::from_ast(type_ref) | ||
587 | } else { | ||
588 | let self_type = TypeRef::Path(name::SELF_TYPE.into()); | ||
589 | match self_param.kind() { | ||
590 | ast::SelfParamKind::Owned => self_type, | ||
591 | ast::SelfParamKind::Ref => { | ||
592 | TypeRef::Reference(Box::new(self_type), Mutability::Shared) | ||
593 | } | ||
594 | ast::SelfParamKind::MutRef => { | ||
595 | TypeRef::Reference(Box::new(self_type), Mutability::Mut) | ||
596 | } | ||
597 | } | ||
598 | }; | ||
599 | params.push(self_type); | ||
600 | has_self_param = true; | ||
601 | } | ||
602 | for param in param_list.params() { | ||
603 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | ||
604 | params.push(type_ref); | ||
605 | } | ||
606 | } | ||
607 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | ||
608 | TypeRef::from_ast(type_ref) | ||
609 | } else { | ||
610 | TypeRef::unit() | ||
611 | }; | ||
612 | |||
613 | let sig = FnData { name, params, ret_type, has_self_param }; | ||
614 | Arc::new(sig) | ||
615 | } | ||
616 | pub fn name(&self) -> &Name { | ||
617 | &self.name | ||
618 | } | ||
619 | |||
620 | pub fn params(&self) -> &[TypeRef] { | ||
621 | &self.params | ||
622 | } | ||
623 | |||
624 | pub fn ret_type(&self) -> &TypeRef { | ||
625 | &self.ret_type | ||
626 | } | ||
627 | |||
628 | /// True if the first arg is `self`. This is relevant to decide whether this | ||
629 | /// can be called as a method. | ||
630 | pub fn has_self_param(&self) -> bool { | ||
631 | self.has_self_param | ||
632 | } | ||
633 | } | ||
634 | |||
635 | impl Function { | 617 | impl Function { |
636 | pub fn module(self, db: &impl DefDatabase) -> Module { | 618 | pub fn module(self, db: &impl DefDatabase) -> Module { |
637 | self.id.lookup(db).module(db).into() | 619 | self.id.lookup(db).module(db).into() |
@@ -642,7 +624,15 @@ impl Function { | |||
642 | } | 624 | } |
643 | 625 | ||
644 | pub fn name(self, db: &impl HirDatabase) -> Name { | 626 | pub fn name(self, db: &impl HirDatabase) -> Name { |
645 | self.data(db).name.clone() | 627 | db.function_data(self.id).name.clone() |
628 | } | ||
629 | |||
630 | pub fn has_self_param(self, db: &impl HirDatabase) -> bool { | ||
631 | db.function_data(self.id).has_self_param | ||
632 | } | ||
633 | |||
634 | pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> { | ||
635 | db.function_data(self.id).params.clone() | ||
646 | } | 636 | } |
647 | 637 | ||
648 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 638 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
@@ -657,10 +647,6 @@ impl Function { | |||
657 | db.type_for_def(self.into(), Namespace::Values) | 647 | db.type_for_def(self.into(), Namespace::Values) |
658 | } | 648 | } |
659 | 649 | ||
660 | pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> { | ||
661 | db.fn_data(self) | ||
662 | } | ||
663 | |||
664 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 650 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
665 | db.infer(self.into()) | 651 | db.infer(self.into()) |
666 | } | 652 | } |
@@ -711,12 +697,8 @@ impl Const { | |||
711 | Some(self.module(db).krate()) | 697 | Some(self.module(db).krate()) |
712 | } | 698 | } |
713 | 699 | ||
714 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | ||
715 | db.const_data(self) | ||
716 | } | ||
717 | |||
718 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 700 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
719 | self.data(db).name().cloned() | 701 | db.const_data(self.id).name.clone() |
720 | } | 702 | } |
721 | 703 | ||
722 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 704 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
@@ -748,45 +730,6 @@ impl Const { | |||
748 | } | 730 | } |
749 | } | 731 | } |
750 | 732 | ||
751 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
752 | pub struct ConstData { | ||
753 | pub(crate) name: Option<Name>, | ||
754 | pub(crate) type_ref: TypeRef, | ||
755 | } | ||
756 | |||
757 | impl ConstData { | ||
758 | pub fn name(&self) -> Option<&Name> { | ||
759 | self.name.as_ref() | ||
760 | } | ||
761 | |||
762 | pub fn type_ref(&self) -> &TypeRef { | ||
763 | &self.type_ref | ||
764 | } | ||
765 | |||
766 | pub(crate) fn const_data_query( | ||
767 | db: &(impl DefDatabase + AstDatabase), | ||
768 | konst: Const, | ||
769 | ) -> Arc<ConstData> { | ||
770 | let node = konst.source(db).value; | ||
771 | const_data_for(&node) | ||
772 | } | ||
773 | |||
774 | pub(crate) fn static_data_query( | ||
775 | db: &(impl DefDatabase + AstDatabase), | ||
776 | konst: Static, | ||
777 | ) -> Arc<ConstData> { | ||
778 | let node = konst.source(db).value; | ||
779 | const_data_for(&node) | ||
780 | } | ||
781 | } | ||
782 | |||
783 | fn const_data_for<N: NameOwner + TypeAscriptionOwner>(node: &N) -> Arc<ConstData> { | ||
784 | let name = node.name().map(|n| n.as_name()); | ||
785 | let type_ref = TypeRef::from_ast_opt(node.ascribed_type()); | ||
786 | let sig = ConstData { name, type_ref }; | ||
787 | Arc::new(sig) | ||
788 | } | ||
789 | |||
790 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 733 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
791 | pub struct Static { | 734 | pub struct Static { |
792 | pub(crate) id: StaticId, | 735 | pub(crate) id: StaticId, |
@@ -801,10 +744,6 @@ impl Static { | |||
801 | Some(self.module(db).krate()) | 744 | Some(self.module(db).krate()) |
802 | } | 745 | } |
803 | 746 | ||
804 | pub fn data(self, db: &impl HirDatabase) -> Arc<ConstData> { | ||
805 | db.static_data(self) | ||
806 | } | ||
807 | |||
808 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 747 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
809 | db.infer(self.into()) | 748 | db.infer(self.into()) |
810 | } | 749 | } |
@@ -821,11 +760,11 @@ impl Trait { | |||
821 | } | 760 | } |
822 | 761 | ||
823 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { | 762 | pub fn name(self, db: &impl DefDatabase) -> Option<Name> { |
824 | self.trait_data(db).name.clone() | 763 | db.trait_data(self.id).name.clone() |
825 | } | 764 | } |
826 | 765 | ||
827 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 766 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
828 | self.trait_data(db).items.iter().map(|it| (*it).into()).collect() | 767 | db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() |
829 | } | 768 | } |
830 | 769 | ||
831 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { | 770 | fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> { |
@@ -871,7 +810,7 @@ impl Trait { | |||
871 | } | 810 | } |
872 | 811 | ||
873 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { | 812 | pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { |
874 | let trait_data = self.trait_data(db); | 813 | let trait_data = db.trait_data(self.id); |
875 | let res = | 814 | let res = |
876 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; | 815 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; |
877 | Some(res) | 816 | Some(res) |
@@ -885,16 +824,12 @@ impl Trait { | |||
885 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) | 824 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) |
886 | } | 825 | } |
887 | 826 | ||
888 | pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> { | ||
889 | db.trait_data(self.id) | ||
890 | } | ||
891 | |||
892 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 827 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |
893 | TraitRef::for_trait(db, self) | 828 | TraitRef::for_trait(db, self) |
894 | } | 829 | } |
895 | 830 | ||
896 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | 831 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { |
897 | self.trait_data(db).auto | 832 | db.trait_data(self.id).auto |
898 | } | 833 | } |
899 | } | 834 | } |
900 | 835 | ||
@@ -937,7 +872,7 @@ impl TypeAlias { | |||
937 | } | 872 | } |
938 | 873 | ||
939 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { | 874 | pub fn type_ref(self, db: &impl DefDatabase) -> Option<TypeRef> { |
940 | db.type_alias_data(self).type_ref.clone() | 875 | db.type_alias_data(self.id).type_ref.clone() |
941 | } | 876 | } |
942 | 877 | ||
943 | pub fn ty(self, db: &impl HirDatabase) -> Ty { | 878 | pub fn ty(self, db: &impl HirDatabase) -> Ty { |
@@ -945,7 +880,7 @@ impl TypeAlias { | |||
945 | } | 880 | } |
946 | 881 | ||
947 | pub fn name(self, db: &impl DefDatabase) -> Name { | 882 | pub fn name(self, db: &impl DefDatabase) -> Name { |
948 | db.type_alias_data(self).name.clone() | 883 | db.type_alias_data(self.id).name.clone() |
949 | } | 884 | } |
950 | } | 885 | } |
951 | 886 | ||
@@ -1110,3 +1045,51 @@ impl From<PerNs> for ScopeDef { | |||
1110 | .unwrap_or(ScopeDef::Unknown) | 1045 | .unwrap_or(ScopeDef::Unknown) |
1111 | } | 1046 | } |
1112 | } | 1047 | } |
1048 | |||
1049 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
1050 | pub enum AttrDef { | ||
1051 | Module(Module), | ||
1052 | StructField(StructField), | ||
1053 | Adt(Adt), | ||
1054 | Function(Function), | ||
1055 | EnumVariant(EnumVariant), | ||
1056 | Static(Static), | ||
1057 | Const(Const), | ||
1058 | Trait(Trait), | ||
1059 | TypeAlias(TypeAlias), | ||
1060 | MacroDef(MacroDef), | ||
1061 | } | ||
1062 | |||
1063 | impl_froms!( | ||
1064 | AttrDef: Module, | ||
1065 | StructField, | ||
1066 | Adt(Struct, Enum, Union), | ||
1067 | EnumVariant, | ||
1068 | Static, | ||
1069 | Const, | ||
1070 | Function, | ||
1071 | Trait, | ||
1072 | TypeAlias, | ||
1073 | MacroDef | ||
1074 | ); | ||
1075 | |||
1076 | pub trait HasAttrs { | ||
1077 | fn attrs(self, db: &impl DefDatabase) -> Attrs; | ||
1078 | } | ||
1079 | |||
1080 | impl<T: Into<AttrDef>> HasAttrs for T { | ||
1081 | fn attrs(self, db: &impl DefDatabase) -> Attrs { | ||
1082 | let def: AttrDef = self.into(); | ||
1083 | db.attrs(def.into()) | ||
1084 | } | ||
1085 | } | ||
1086 | |||
1087 | pub trait Docs { | ||
1088 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; | ||
1089 | } | ||
1090 | impl<T: Into<AttrDef> + Copy> Docs for T { | ||
1091 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | ||
1092 | let def: AttrDef = (*self).into(); | ||
1093 | db.documentation(def.into()) | ||
1094 | } | ||
1095 | } | ||
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs deleted file mode 100644 index 9e304217c..000000000 --- a/crates/ra_hir/src/code_model/attrs.rs +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use crate::{ | ||
4 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
5 | Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, | ||
6 | Struct, StructField, Trait, TypeAlias, Union, | ||
7 | }; | ||
8 | use hir_def::attr::Attr; | ||
9 | use hir_expand::hygiene::Hygiene; | ||
10 | use ra_syntax::ast; | ||
11 | use std::sync::Arc; | ||
12 | |||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
14 | pub enum AttrDef { | ||
15 | Module(Module), | ||
16 | StructField(StructField), | ||
17 | Adt(Adt), | ||
18 | Function(Function), | ||
19 | EnumVariant(EnumVariant), | ||
20 | Static(Static), | ||
21 | Const(Const), | ||
22 | Trait(Trait), | ||
23 | TypeAlias(TypeAlias), | ||
24 | MacroDef(MacroDef), | ||
25 | } | ||
26 | |||
27 | impl_froms!( | ||
28 | AttrDef: Module, | ||
29 | StructField, | ||
30 | Adt(Struct, Enum, Union), | ||
31 | EnumVariant, | ||
32 | Static, | ||
33 | Const, | ||
34 | Function, | ||
35 | Trait, | ||
36 | TypeAlias, | ||
37 | MacroDef | ||
38 | ); | ||
39 | |||
40 | pub trait Attrs { | ||
41 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>>; | ||
42 | } | ||
43 | |||
44 | pub(crate) fn attributes_query( | ||
45 | db: &(impl DefDatabase + AstDatabase), | ||
46 | def: AttrDef, | ||
47 | ) -> Option<Arc<[Attr]>> { | ||
48 | match def { | ||
49 | AttrDef::Module(it) => { | ||
50 | let src = it.declaration_source(db)?; | ||
51 | let hygiene = Hygiene::new(db, src.file_id); | ||
52 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
53 | } | ||
54 | AttrDef::StructField(it) => match it.source(db).value { | ||
55 | FieldSource::Named(named) => { | ||
56 | let src = it.source(db); | ||
57 | let hygiene = Hygiene::new(db, src.file_id); | ||
58 | Attr::from_attrs_owner(&named, &hygiene) | ||
59 | } | ||
60 | FieldSource::Pos(..) => None, | ||
61 | }, | ||
62 | AttrDef::Adt(it) => match it { | ||
63 | Adt::Struct(it) => attrs_from_ast(it, db), | ||
64 | Adt::Enum(it) => attrs_from_ast(it, db), | ||
65 | Adt::Union(it) => attrs_from_ast(it, db), | ||
66 | }, | ||
67 | AttrDef::EnumVariant(it) => attrs_from_ast(it, db), | ||
68 | AttrDef::Static(it) => attrs_from_ast(it, db), | ||
69 | AttrDef::Const(it) => attrs_from_ast(it, db), | ||
70 | AttrDef::Function(it) => attrs_from_ast(it, db), | ||
71 | AttrDef::Trait(it) => attrs_from_ast(it, db), | ||
72 | AttrDef::TypeAlias(it) => attrs_from_ast(it, db), | ||
73 | AttrDef::MacroDef(it) => attrs_from_ast(it, db), | ||
74 | } | ||
75 | } | ||
76 | |||
77 | fn attrs_from_ast<T, D>(node: T, db: &D) -> Option<Arc<[Attr]>> | ||
78 | where | ||
79 | T: HasSource, | ||
80 | T::Ast: ast::AttrsOwner, | ||
81 | D: DefDatabase + AstDatabase, | ||
82 | { | ||
83 | let src = node.source(db); | ||
84 | let hygiene = Hygiene::new(db, src.file_id); | ||
85 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
86 | } | ||
87 | |||
88 | impl<T: Into<AttrDef> + Copy> Attrs for T { | ||
89 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>> { | ||
90 | db.attrs((*self).into()) | ||
91 | } | ||
92 | } | ||
diff --git a/crates/ra_hir/src/code_model/docs.rs b/crates/ra_hir/src/code_model/docs.rs deleted file mode 100644 index e40efef34..000000000 --- a/crates/ra_hir/src/code_model/docs.rs +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use ra_syntax::ast; | ||
6 | |||
7 | use crate::{ | ||
8 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
9 | Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, | ||
10 | Struct, StructField, Trait, TypeAlias, Union, | ||
11 | }; | ||
12 | |||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
14 | pub enum DocDef { | ||
15 | Module(Module), | ||
16 | StructField(StructField), | ||
17 | Adt(Adt), | ||
18 | EnumVariant(EnumVariant), | ||
19 | Static(Static), | ||
20 | Const(Const), | ||
21 | Function(Function), | ||
22 | Trait(Trait), | ||
23 | TypeAlias(TypeAlias), | ||
24 | MacroDef(MacroDef), | ||
25 | } | ||
26 | |||
27 | impl_froms!( | ||
28 | DocDef: Module, | ||
29 | StructField, | ||
30 | Adt(Struct, Enum, Union), | ||
31 | EnumVariant, | ||
32 | Static, | ||
33 | Const, | ||
34 | Function, | ||
35 | Trait, | ||
36 | TypeAlias, | ||
37 | MacroDef | ||
38 | ); | ||
39 | |||
40 | /// Holds documentation | ||
41 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
42 | pub struct Documentation(Arc<str>); | ||
43 | |||
44 | impl Documentation { | ||
45 | fn new(s: &str) -> Documentation { | ||
46 | Documentation(s.into()) | ||
47 | } | ||
48 | |||
49 | pub fn as_str(&self) -> &str { | ||
50 | &*self.0 | ||
51 | } | ||
52 | } | ||
53 | |||
54 | impl Into<String> for Documentation { | ||
55 | fn into(self) -> String { | ||
56 | self.as_str().to_owned() | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub trait Docs { | ||
61 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>; | ||
62 | } | ||
63 | |||
64 | pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { | ||
65 | node.doc_comment_text().map(|it| Documentation::new(&it)) | ||
66 | } | ||
67 | |||
68 | pub(crate) fn documentation_query( | ||
69 | db: &(impl DefDatabase + AstDatabase), | ||
70 | def: DocDef, | ||
71 | ) -> Option<Documentation> { | ||
72 | match def { | ||
73 | DocDef::Module(it) => docs_from_ast(&it.declaration_source(db)?.value), | ||
74 | DocDef::StructField(it) => match it.source(db).value { | ||
75 | FieldSource::Named(named) => docs_from_ast(&named), | ||
76 | FieldSource::Pos(..) => None, | ||
77 | }, | ||
78 | DocDef::Adt(it) => match it { | ||
79 | Adt::Struct(it) => docs_from_ast(&it.source(db).value), | ||
80 | Adt::Enum(it) => docs_from_ast(&it.source(db).value), | ||
81 | Adt::Union(it) => docs_from_ast(&it.source(db).value), | ||
82 | }, | ||
83 | DocDef::EnumVariant(it) => docs_from_ast(&it.source(db).value), | ||
84 | DocDef::Static(it) => docs_from_ast(&it.source(db).value), | ||
85 | DocDef::Const(it) => docs_from_ast(&it.source(db).value), | ||
86 | DocDef::Function(it) => docs_from_ast(&it.source(db).value), | ||
87 | DocDef::Trait(it) => docs_from_ast(&it.source(db).value), | ||
88 | DocDef::TypeAlias(it) => docs_from_ast(&it.source(db).value), | ||
89 | DocDef::MacroDef(it) => docs_from_ast(&it.source(db).value), | ||
90 | } | ||
91 | } | ||
92 | |||
93 | impl<T: Into<DocDef> + Copy> Docs for T { | ||
94 | fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> { | ||
95 | db.documentation((*self).into()) | ||
96 | } | ||
97 | } | ||
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 4aa427de4..b7bafe23d 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -1,151 +1,127 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{HasSource as _, Lookup}; | 3 | use hir_def::{HasChildSource, HasSource as _, Lookup, VariantId}; |
4 | use hir_expand::either::Either; | ||
4 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
5 | 6 | ||
6 | use crate::{ | 7 | use crate::{ |
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | 8 | db::{DefDatabase, HirDatabase}, |
8 | ids::AstItemDef, | 9 | ids::AstItemDef, |
9 | Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module, | 10 | Const, Enum, EnumVariant, FieldSource, Function, HasBody, Import, MacroDef, Module, |
10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, | 11 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, |
11 | }; | 12 | }; |
12 | 13 | ||
13 | pub use hir_expand::Source; | 14 | pub use hir_expand::Source; |
14 | 15 | ||
15 | pub trait HasSource { | 16 | pub trait HasSource { |
16 | type Ast; | 17 | type Ast; |
17 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; | 18 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>; |
18 | } | 19 | } |
19 | 20 | ||
20 | /// NB: Module is !HasSource, because it has two source nodes at the same time: | 21 | /// NB: Module is !HasSource, because it has two source nodes at the same time: |
21 | /// definition and declaration. | 22 | /// definition and declaration. |
22 | impl Module { | 23 | impl Module { |
23 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 24 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
24 | pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { | 25 | pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { |
25 | let def_map = db.crate_def_map(self.id.krate); | 26 | let def_map = db.crate_def_map(self.id.krate); |
26 | let decl_id = def_map[self.id.module_id].declaration; | 27 | let src = def_map[self.id.module_id].definition_source(db); |
27 | let file_id = def_map[self.id.module_id].definition; | 28 | src.map(|it| match it { |
28 | let value = ModuleSource::new(db, file_id, decl_id); | 29 | Either::A(it) => ModuleSource::SourceFile(it), |
29 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); | 30 | Either::B(it) => ModuleSource::Module(it), |
30 | Source { file_id, value } | 31 | }) |
31 | } | 32 | } |
32 | 33 | ||
33 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | 34 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. |
34 | /// `None` for the crate root. | 35 | /// `None` for the crate root. |
35 | pub fn declaration_source( | 36 | pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { |
36 | self, | ||
37 | db: &(impl DefDatabase + AstDatabase), | ||
38 | ) -> Option<Source<ast::Module>> { | ||
39 | let def_map = db.crate_def_map(self.id.krate); | 37 | let def_map = db.crate_def_map(self.id.krate); |
40 | let decl = def_map[self.id.module_id].declaration?; | 38 | def_map[self.id.module_id].declaration_source(db) |
41 | let value = decl.to_node(db); | ||
42 | Some(Source { file_id: decl.file_id(), value }) | ||
43 | } | 39 | } |
44 | } | 40 | } |
45 | 41 | ||
46 | impl HasSource for StructField { | 42 | impl HasSource for StructField { |
47 | type Ast = FieldSource; | 43 | type Ast = FieldSource; |
48 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> { | 44 | fn source(self, db: &impl DefDatabase) -> Source<FieldSource> { |
49 | let var_data = self.parent.variant_data(db); | 45 | let var = VariantId::from(self.parent); |
50 | let fields = var_data.fields().unwrap(); | 46 | let src = var.child_source(db); |
51 | let ss; | 47 | src.map(|it| match it[self.id].clone() { |
52 | let es; | 48 | Either::A(it) => FieldSource::Pos(it), |
53 | let (file_id, struct_kind) = match self.parent { | 49 | Either::B(it) => FieldSource::Named(it), |
54 | VariantDef::Struct(s) => { | 50 | }) |
55 | ss = s.source(db); | ||
56 | (ss.file_id, ss.value.kind()) | ||
57 | } | ||
58 | VariantDef::EnumVariant(e) => { | ||
59 | es = e.source(db); | ||
60 | (es.file_id, es.value.kind()) | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | let field_sources = match struct_kind { | ||
65 | ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(), | ||
66 | ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(), | ||
67 | ast::StructKind::Unit => Vec::new(), | ||
68 | }; | ||
69 | let value = field_sources | ||
70 | .into_iter() | ||
71 | .zip(fields.iter()) | ||
72 | .find(|(_syntax, (id, _))| *id == self.id) | ||
73 | .unwrap() | ||
74 | .0; | ||
75 | Source { file_id, value } | ||
76 | } | 51 | } |
77 | } | 52 | } |
78 | impl HasSource for Struct { | 53 | impl HasSource for Struct { |
79 | type Ast = ast::StructDef; | 54 | type Ast = ast::StructDef; |
80 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { | 55 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { |
81 | self.id.0.source(db) | 56 | self.id.0.source(db) |
82 | } | 57 | } |
83 | } | 58 | } |
84 | impl HasSource for Union { | 59 | impl HasSource for Union { |
85 | type Ast = ast::StructDef; | 60 | type Ast = ast::StructDef; |
86 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { | 61 | fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { |
87 | self.id.0.source(db) | 62 | self.id.0.source(db) |
88 | } | 63 | } |
89 | } | 64 | } |
90 | impl HasSource for Enum { | 65 | impl HasSource for Enum { |
91 | type Ast = ast::EnumDef; | 66 | type Ast = ast::EnumDef; |
92 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumDef> { | 67 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> { |
93 | self.id.source(db) | 68 | self.id.source(db) |
94 | } | 69 | } |
95 | } | 70 | } |
96 | impl HasSource for EnumVariant { | 71 | impl HasSource for EnumVariant { |
97 | type Ast = ast::EnumVariant; | 72 | type Ast = ast::EnumVariant; |
98 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { | 73 | fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> { |
99 | let enum_data = db.enum_data(self.parent.id); | 74 | self.parent.id.child_source(db).map(|map| map[self.id].clone()) |
100 | let src = self.parent.id.source(db); | ||
101 | let value = src | ||
102 | .value | ||
103 | .variant_list() | ||
104 | .into_iter() | ||
105 | .flat_map(|it| it.variants()) | ||
106 | .zip(enum_data.variants.iter()) | ||
107 | .find(|(_syntax, (id, _))| *id == self.id) | ||
108 | .unwrap() | ||
109 | .0; | ||
110 | Source { file_id: src.file_id, value } | ||
111 | } | 75 | } |
112 | } | 76 | } |
113 | impl HasSource for Function { | 77 | impl HasSource for Function { |
114 | type Ast = ast::FnDef; | 78 | type Ast = ast::FnDef; |
115 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { | 79 | fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> { |
116 | self.id.lookup(db).source(db) | 80 | self.id.lookup(db).source(db) |
117 | } | 81 | } |
118 | } | 82 | } |
119 | impl HasSource for Const { | 83 | impl HasSource for Const { |
120 | type Ast = ast::ConstDef; | 84 | type Ast = ast::ConstDef; |
121 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { | 85 | fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> { |
122 | self.id.lookup(db).source(db) | 86 | self.id.lookup(db).source(db) |
123 | } | 87 | } |
124 | } | 88 | } |
125 | impl HasSource for Static { | 89 | impl HasSource for Static { |
126 | type Ast = ast::StaticDef; | 90 | type Ast = ast::StaticDef; |
127 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StaticDef> { | 91 | fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> { |
128 | self.id.source(db) | 92 | self.id.source(db) |
129 | } | 93 | } |
130 | } | 94 | } |
131 | impl HasSource for Trait { | 95 | impl HasSource for Trait { |
132 | type Ast = ast::TraitDef; | 96 | type Ast = ast::TraitDef; |
133 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TraitDef> { | 97 | fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> { |
134 | self.id.source(db) | 98 | self.id.source(db) |
135 | } | 99 | } |
136 | } | 100 | } |
137 | impl HasSource for TypeAlias { | 101 | impl HasSource for TypeAlias { |
138 | type Ast = ast::TypeAliasDef; | 102 | type Ast = ast::TypeAliasDef; |
139 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { | 103 | fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> { |
140 | self.id.lookup(db).source(db) | 104 | self.id.lookup(db).source(db) |
141 | } | 105 | } |
142 | } | 106 | } |
143 | impl HasSource for MacroDef { | 107 | impl HasSource for MacroDef { |
144 | type Ast = ast::MacroCall; | 108 | type Ast = ast::MacroCall; |
145 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { | 109 | fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> { |
146 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } | 110 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } |
147 | } | 111 | } |
148 | } | 112 | } |
113 | impl HasSource for Import { | ||
114 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; | ||
115 | |||
116 | /// Returns the syntax of the last path segment corresponding to this import | ||
117 | fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> { | ||
118 | let src = self.parent.definition_source(db); | ||
119 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | ||
120 | let root = db.parse_or_expand(src.file_id).unwrap(); | ||
121 | let ptr = source_map.get(self.id); | ||
122 | src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) | ||
123 | } | ||
124 | } | ||
149 | 125 | ||
150 | pub trait HasBodySource: HasBody + HasSource | 126 | pub trait HasBodySource: HasBody + HasSource |
151 | where | 127 | where |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index ed0d68001..3ae5df8d5 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,71 +2,34 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::attr::Attr; | ||
6 | use ra_db::salsa; | 5 | use ra_db::salsa; |
7 | use ra_syntax::SmolStr; | ||
8 | 6 | ||
9 | use crate::{ | 7 | use crate::{ |
10 | debug::HirDebugDatabase, | ||
11 | ids, | 8 | ids, |
12 | lang_item::{LangItemTarget, LangItems}, | ||
13 | ty::{ | 9 | ty::{ |
14 | method_resolution::CrateImplBlocks, | 10 | method_resolution::CrateImplBlocks, |
15 | traits::{AssocTyValue, Impl}, | 11 | traits::{AssocTyValue, Impl}, |
16 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, | 12 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, |
17 | TypeCtor, | 13 | TypeCtor, |
18 | }, | 14 | }, |
19 | type_alias::TypeAliasData, | 15 | Crate, DefWithBody, GenericDef, ImplBlock, StructField, Trait, |
20 | Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static, | ||
21 | StructField, Trait, TypeAlias, | ||
22 | }; | 16 | }; |
23 | 17 | ||
24 | pub use hir_def::db::{ | 18 | pub use hir_def::db::{ |
25 | BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, | 19 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, |
26 | EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, | 20 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
27 | InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, | 21 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
28 | TraitDataQuery, | 22 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, |
23 | StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, | ||
29 | }; | 24 | }; |
30 | pub use hir_expand::db::{ | 25 | pub use hir_expand::db::{ |
31 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 26 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
32 | ParseMacroQuery, | 27 | ParseMacroQuery, |
33 | }; | 28 | }; |
34 | 29 | ||
35 | // This database uses `AstDatabase` internally, | ||
36 | #[salsa::query_group(DefDatabaseStorage)] | ||
37 | #[salsa::requires(AstDatabase)] | ||
38 | pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | ||
39 | #[salsa::invoke(FnData::fn_data_query)] | ||
40 | fn fn_data(&self, func: Function) -> Arc<FnData>; | ||
41 | |||
42 | #[salsa::invoke(TypeAliasData::type_alias_data_query)] | ||
43 | fn type_alias_data(&self, typ: TypeAlias) -> Arc<TypeAliasData>; | ||
44 | |||
45 | #[salsa::invoke(ConstData::const_data_query)] | ||
46 | fn const_data(&self, konst: Const) -> Arc<ConstData>; | ||
47 | |||
48 | #[salsa::invoke(ConstData::static_data_query)] | ||
49 | fn static_data(&self, konst: Static) -> Arc<ConstData>; | ||
50 | |||
51 | #[salsa::invoke(LangItems::module_lang_items_query)] | ||
52 | fn module_lang_items(&self, module: Module) -> Option<Arc<LangItems>>; | ||
53 | |||
54 | #[salsa::invoke(LangItems::crate_lang_items_query)] | ||
55 | fn crate_lang_items(&self, krate: Crate) -> Arc<LangItems>; | ||
56 | |||
57 | #[salsa::invoke(LangItems::lang_item_query)] | ||
58 | fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>; | ||
59 | |||
60 | #[salsa::invoke(crate::code_model::docs::documentation_query)] | ||
61 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; | ||
62 | |||
63 | #[salsa::invoke(crate::code_model::attrs::attributes_query)] | ||
64 | fn attrs(&self, def: crate::AttrDef) -> Option<Arc<[Attr]>>; | ||
65 | } | ||
66 | |||
67 | #[salsa::query_group(HirDatabaseStorage)] | 30 | #[salsa::query_group(HirDatabaseStorage)] |
68 | #[salsa::requires(salsa::Database)] | 31 | #[salsa::requires(salsa::Database)] |
69 | pub trait HirDatabase: DefDatabase + AstDatabase { | 32 | pub trait HirDatabase: DefDatabase { |
70 | #[salsa::invoke(crate::ty::infer_query)] | 33 | #[salsa::invoke(crate::ty::infer_query)] |
71 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; | 34 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; |
72 | 35 | ||
diff --git a/crates/ra_hir/src/debug.rs b/crates/ra_hir/src/debug.rs index 4f3e922c3..8ec371f6e 100644 --- a/crates/ra_hir/src/debug.rs +++ b/crates/ra_hir/src/debug.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | //! XXX: This does not work at the moment. | ||
2 | //! | ||
1 | //! printf debugging infrastructure for rust-analyzer. | 3 | //! printf debugging infrastructure for rust-analyzer. |
2 | //! | 4 | //! |
3 | //! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, | 5 | //! When you print a hir type, like a module, using `eprintln!("{:?}", module)`, |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index e8ed04056..529ac8251 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -4,14 +4,14 @@ | |||
4 | //! are splitting the hir. | 4 | //! are splitting the hir. |
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, | 7 | AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, |
8 | ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, | 8 | GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ty::{CallableDef, TypableDef}, | 12 | ty::{CallableDef, TypableDef}, |
13 | Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, | 13 | Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, |
14 | Static, TypeAlias, | 14 | ModuleDef, Static, StructField, TypeAlias, VariantDef, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | impl From<ra_db::CrateId> for Crate { | 17 | impl From<ra_db::CrateId> for Crate { |
@@ -70,6 +70,12 @@ impl From<EnumVariantId> for EnumVariant { | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | impl From<EnumVariant> for EnumVariantId { | ||
74 | fn from(def: EnumVariant) -> Self { | ||
75 | EnumVariantId { parent: def.parent.id, local_id: def.id } | ||
76 | } | ||
77 | } | ||
78 | |||
73 | impl From<ModuleDefId> for ModuleDef { | 79 | impl From<ModuleDefId> for ModuleDef { |
74 | fn from(id: ModuleDefId) -> Self { | 80 | fn from(id: ModuleDefId) -> Self { |
75 | match id { | 81 | match id { |
@@ -219,3 +225,35 @@ impl From<CallableDef> for GenericDefId { | |||
219 | } | 225 | } |
220 | } | 226 | } |
221 | } | 227 | } |
228 | |||
229 | impl From<VariantDef> for VariantId { | ||
230 | fn from(def: VariantDef) -> Self { | ||
231 | match def { | ||
232 | VariantDef::Struct(it) => VariantId::StructId(it.id), | ||
233 | VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | |||
238 | impl From<StructField> for StructFieldId { | ||
239 | fn from(def: StructField) -> Self { | ||
240 | StructFieldId { parent: def.parent.into(), local_id: def.id } | ||
241 | } | ||
242 | } | ||
243 | |||
244 | impl From<AttrDef> for AttrDefId { | ||
245 | fn from(def: AttrDef) -> Self { | ||
246 | match def { | ||
247 | AttrDef::Module(it) => AttrDefId::ModuleId(it.id), | ||
248 | AttrDef::StructField(it) => AttrDefId::StructFieldId(it.into()), | ||
249 | AttrDef::Adt(it) => AttrDefId::AdtId(it.into()), | ||
250 | AttrDef::Function(it) => AttrDefId::FunctionId(it.id), | ||
251 | AttrDef::EnumVariant(it) => AttrDefId::EnumVariantId(it.into()), | ||
252 | AttrDef::Static(it) => AttrDefId::StaticId(it.id), | ||
253 | AttrDef::Const(it) => AttrDefId::ConstId(it.id), | ||
254 | AttrDef::Trait(it) => AttrDefId::TraitId(it.id), | ||
255 | AttrDef::TypeAlias(it) => AttrDefId::TypeAliasId(it.id), | ||
256 | AttrDef::MacroDef(it) => AttrDefId::MacroDefId(it.id), | ||
257 | } | ||
258 | } | ||
259 | } | ||
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 774fa1d96..334eeebac 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -18,11 +18,11 @@ impl HasSource for ImplBlock { | |||
18 | 18 | ||
19 | impl ImplBlock { | 19 | impl ImplBlock { |
20 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 20 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
21 | db.impl_data(self.id).target_trait().cloned() | 21 | db.impl_data(self.id).target_trait.clone() |
22 | } | 22 | } |
23 | 23 | ||
24 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { | 24 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { |
25 | db.impl_data(self.id).target_type().clone() | 25 | db.impl_data(self.id).target_type.clone() |
26 | } | 26 | } |
27 | 27 | ||
28 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | 28 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { |
@@ -35,11 +35,11 @@ impl ImplBlock { | |||
35 | } | 35 | } |
36 | 36 | ||
37 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | 37 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { |
38 | db.impl_data(self.id).items().iter().map(|it| (*it).into()).collect() | 38 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() |
39 | } | 39 | } |
40 | 40 | ||
41 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | 41 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { |
42 | db.impl_data(self.id).is_negative() | 42 | db.impl_data(self.id).is_negative |
43 | } | 43 | } |
44 | 44 | ||
45 | pub fn module(&self, db: &impl DefDatabase) -> Module { | 45 | pub fn module(&self, db: &impl DefDatabase) -> Module { |
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs deleted file mode 100644 index 89fd85f59..000000000 --- a/crates/ra_hir/src/lang_item.rs +++ /dev/null | |||
@@ -1,160 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use rustc_hash::FxHashMap; | ||
4 | use std::sync::Arc; | ||
5 | |||
6 | use ra_syntax::{ast::AttrsOwner, SmolStr}; | ||
7 | |||
8 | use crate::{ | ||
9 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
10 | Adt, Crate, Enum, Function, HasSource, ImplBlock, Module, ModuleDef, Static, Struct, Trait, | ||
11 | }; | ||
12 | |||
13 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
14 | pub enum LangItemTarget { | ||
15 | Enum(Enum), | ||
16 | Function(Function), | ||
17 | ImplBlock(ImplBlock), | ||
18 | Static(Static), | ||
19 | Struct(Struct), | ||
20 | Trait(Trait), | ||
21 | } | ||
22 | |||
23 | impl LangItemTarget { | ||
24 | pub(crate) fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | ||
25 | Some(match self { | ||
26 | LangItemTarget::Enum(e) => e.module(db).krate(), | ||
27 | LangItemTarget::Function(f) => f.module(db).krate(), | ||
28 | LangItemTarget::ImplBlock(i) => i.krate(db), | ||
29 | LangItemTarget::Static(s) => s.module(db).krate(), | ||
30 | LangItemTarget::Struct(s) => s.module(db).krate(), | ||
31 | LangItemTarget::Trait(t) => t.module(db).krate(), | ||
32 | }) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | ||
37 | pub struct LangItems { | ||
38 | items: FxHashMap<SmolStr, LangItemTarget>, | ||
39 | } | ||
40 | |||
41 | impl LangItems { | ||
42 | pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> { | ||
43 | self.items.get(item) | ||
44 | } | ||
45 | |||
46 | /// Salsa query. This will look for lang items in a specific crate. | ||
47 | pub(crate) fn crate_lang_items_query( | ||
48 | db: &(impl DefDatabase + AstDatabase), | ||
49 | krate: Crate, | ||
50 | ) -> Arc<LangItems> { | ||
51 | let mut lang_items = LangItems::default(); | ||
52 | |||
53 | if let Some(module) = krate.root_module(db) { | ||
54 | lang_items.collect_lang_items_recursive(db, module); | ||
55 | } | ||
56 | |||
57 | Arc::new(lang_items) | ||
58 | } | ||
59 | |||
60 | pub(crate) fn module_lang_items_query( | ||
61 | db: &(impl DefDatabase + AstDatabase), | ||
62 | module: Module, | ||
63 | ) -> Option<Arc<LangItems>> { | ||
64 | let mut lang_items = LangItems::default(); | ||
65 | lang_items.collect_lang_items(db, module); | ||
66 | if lang_items.items.is_empty() { | ||
67 | None | ||
68 | } else { | ||
69 | Some(Arc::new(lang_items)) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively | ||
74 | /// traversing its dependencies. | ||
75 | pub(crate) fn lang_item_query( | ||
76 | db: &impl DefDatabase, | ||
77 | start_crate: Crate, | ||
78 | item: SmolStr, | ||
79 | ) -> Option<LangItemTarget> { | ||
80 | let lang_items = db.crate_lang_items(start_crate); | ||
81 | let start_crate_target = lang_items.items.get(&item); | ||
82 | if let Some(target) = start_crate_target { | ||
83 | Some(*target) | ||
84 | } else { | ||
85 | for dep in start_crate.dependencies(db) { | ||
86 | let dep_crate = dep.krate; | ||
87 | let dep_target = db.lang_item(dep_crate, item.clone()); | ||
88 | if dep_target.is_some() { | ||
89 | return dep_target; | ||
90 | } | ||
91 | } | ||
92 | None | ||
93 | } | ||
94 | } | ||
95 | |||
96 | fn collect_lang_items(&mut self, db: &(impl DefDatabase + AstDatabase), module: Module) { | ||
97 | // Look for impl targets | ||
98 | for impl_block in module.impl_blocks(db) { | ||
99 | let src = impl_block.source(db); | ||
100 | if let Some(lang_item_name) = lang_item_name(&src.value) { | ||
101 | self.items | ||
102 | .entry(lang_item_name) | ||
103 | .or_insert_with(|| LangItemTarget::ImplBlock(impl_block)); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | for def in module.declarations(db) { | ||
108 | match def { | ||
109 | ModuleDef::Trait(trait_) => { | ||
110 | self.collect_lang_item(db, trait_, LangItemTarget::Trait) | ||
111 | } | ||
112 | ModuleDef::Adt(Adt::Enum(e)) => self.collect_lang_item(db, e, LangItemTarget::Enum), | ||
113 | ModuleDef::Adt(Adt::Struct(s)) => { | ||
114 | self.collect_lang_item(db, s, LangItemTarget::Struct) | ||
115 | } | ||
116 | ModuleDef::Function(f) => self.collect_lang_item(db, f, LangItemTarget::Function), | ||
117 | ModuleDef::Static(s) => self.collect_lang_item(db, s, LangItemTarget::Static), | ||
118 | _ => {} | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | fn collect_lang_items_recursive( | ||
124 | &mut self, | ||
125 | db: &(impl DefDatabase + AstDatabase), | ||
126 | module: Module, | ||
127 | ) { | ||
128 | if let Some(module_lang_items) = db.module_lang_items(module) { | ||
129 | self.items.extend(module_lang_items.items.iter().map(|(k, v)| (k.clone(), *v))) | ||
130 | } | ||
131 | |||
132 | // Look for lang items in the children | ||
133 | for child in module.children(db) { | ||
134 | self.collect_lang_items_recursive(db, child); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | fn collect_lang_item<T, N>( | ||
139 | &mut self, | ||
140 | db: &(impl DefDatabase + AstDatabase), | ||
141 | item: T, | ||
142 | constructor: fn(T) -> LangItemTarget, | ||
143 | ) where | ||
144 | T: Copy + HasSource<Ast = N>, | ||
145 | N: AttrsOwner, | ||
146 | { | ||
147 | let node = item.source(db).value; | ||
148 | if let Some(lang_item_name) = lang_item_name(&node) { | ||
149 | self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> { | ||
155 | node.attrs() | ||
156 | .filter_map(|a| a.as_simple_key_value()) | ||
157 | .filter(|(key, _)| key == "lang") | ||
158 | .map(|(_, val)| val) | ||
159 | .nth(0) | ||
160 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 8c6834392..e51d4d063 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -32,11 +32,9 @@ pub mod db; | |||
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ids; | 34 | mod ids; |
35 | mod type_alias; | ||
36 | mod ty; | 35 | mod ty; |
37 | mod impl_block; | 36 | mod impl_block; |
38 | mod expr; | 37 | mod expr; |
39 | mod lang_item; | ||
40 | pub mod diagnostics; | 38 | pub mod diagnostics; |
41 | mod util; | 39 | mod util; |
42 | 40 | ||
@@ -52,13 +50,11 @@ mod marks; | |||
52 | 50 | ||
53 | pub use crate::{ | 51 | pub use crate::{ |
54 | code_model::{ | 52 | code_model::{ |
55 | attrs::{AttrDef, Attrs}, | ||
56 | docs::{DocDef, Docs, Documentation}, | ||
57 | src::{HasBodySource, HasSource}, | 53 | src::{HasBodySource, HasSource}, |
58 | Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, | 54 | Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum, |
59 | EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock, | 55 | EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock, |
60 | Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, | 56 | Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, |
61 | Trait, TypeAlias, Union, VariantDef, | 57 | StructField, Trait, TypeAlias, Union, VariantDef, |
62 | }, | 58 | }, |
63 | expr::ExprScopes, | 59 | expr::ExprScopes, |
64 | from_source::FromSource, | 60 | from_source::FromSource, |
@@ -73,7 +69,7 @@ pub use crate::{ | |||
73 | 69 | ||
74 | pub use hir_def::{ | 70 | pub use hir_def::{ |
75 | builtin_type::BuiltinType, | 71 | builtin_type::BuiltinType, |
76 | nameres::{per_ns::PerNs, raw::ImportId}, | 72 | docs::Documentation, |
77 | path::{Path, PathKind}, | 73 | path::{Path, PathKind}, |
78 | type_ref::Mutability, | 74 | type_ref::Mutability, |
79 | }; | 75 | }; |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c42ceabdf..797f90d50 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -131,6 +131,7 @@ pub struct ReferenceDescriptor { | |||
131 | } | 131 | } |
132 | 132 | ||
133 | pub struct Expansion { | 133 | pub struct Expansion { |
134 | macro_file_kind: MacroFileKind, | ||
134 | macro_call_id: MacroCallId, | 135 | macro_call_id: MacroCallId, |
135 | } | 136 | } |
136 | 137 | ||
@@ -145,7 +146,7 @@ impl Expansion { | |||
145 | } | 146 | } |
146 | 147 | ||
147 | pub fn file_id(&self) -> HirFileId { | 148 | pub fn file_id(&self) -> HirFileId { |
148 | self.macro_call_id.as_file(MacroFileKind::Items) | 149 | self.macro_call_id.as_file(self.macro_file_kind) |
149 | } | 150 | } |
150 | } | 151 | } |
151 | 152 | ||
@@ -439,7 +440,10 @@ impl SourceAnalyzer { | |||
439 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | 440 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), |
440 | ); | 441 | ); |
441 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 442 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
442 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 443 | Some(Expansion { |
444 | macro_call_id: db.intern_macro(macro_call_loc), | ||
445 | macro_file_kind: to_macro_file_kind(macro_call.value), | ||
446 | }) | ||
443 | } | 447 | } |
444 | 448 | ||
445 | #[cfg(test)] | 449 | #[cfg(test)] |
@@ -538,3 +542,35 @@ fn adjust( | |||
538 | }) | 542 | }) |
539 | .map(|(_ptr, scope)| *scope) | 543 | .map(|(_ptr, scope)| *scope) |
540 | } | 544 | } |
545 | |||
546 | /// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. | ||
547 | /// FIXME: Not completed | ||
548 | fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { | ||
549 | let syn = macro_call.syntax(); | ||
550 | let parent = match syn.parent() { | ||
551 | Some(it) => it, | ||
552 | None => { | ||
553 | // FIXME: | ||
554 | // If it is root, which means the parent HirFile | ||
555 | // MacroKindFile must be non-items | ||
556 | // return expr now. | ||
557 | return MacroFileKind::Expr; | ||
558 | } | ||
559 | }; | ||
560 | |||
561 | match parent.kind() { | ||
562 | MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, | ||
563 | LET_STMT => { | ||
564 | // FIXME: Handle Pattern | ||
565 | MacroFileKind::Expr | ||
566 | } | ||
567 | EXPR_STMT => MacroFileKind::Statements, | ||
568 | BLOCK => MacroFileKind::Statements, | ||
569 | ARG_LIST => MacroFileKind::Expr, | ||
570 | TRY_EXPR => MacroFileKind::Expr, | ||
571 | _ => { | ||
572 | // Unknown , Just guess it is `Items` | ||
573 | MacroFileKind::Items | ||
574 | } | ||
575 | } | ||
576 | } | ||
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs index 1caa2e875..03c7ac155 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir/src/test_db.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{panic, sync::Arc}; | 3 | use std::{panic, sync::Arc}; |
4 | 4 | ||
5 | use hir_def::{db::DefDatabase2, ModuleId}; | 5 | use hir_def::{db::DefDatabase, ModuleId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use parking_lot::Mutex; | 7 | use parking_lot::Mutex; |
8 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; | 8 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase}; |
@@ -15,7 +15,6 @@ use crate::{db, debug::HirDebugHelper}; | |||
15 | db::InternDatabaseStorage, | 15 | db::InternDatabaseStorage, |
16 | db::AstDatabaseStorage, | 16 | db::AstDatabaseStorage, |
17 | db::DefDatabaseStorage, | 17 | db::DefDatabaseStorage, |
18 | db::DefDatabase2Storage, | ||
19 | db::HirDatabaseStorage | 18 | db::HirDatabaseStorage |
20 | )] | 19 | )] |
21 | #[derive(Debug, Default)] | 20 | #[derive(Debug, Default)] |
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index b60e4bb31..41c99d227 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -5,12 +5,13 @@ | |||
5 | 5 | ||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use hir_def::resolver::Resolver; | 8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; |
9 | use hir_expand::name; | 9 | use hir_expand::name; |
10 | use log::{info, warn}; | 10 | use log::{info, warn}; |
11 | 11 | ||
12 | use crate::{db::HirDatabase, Trait}; | ||
13 | |||
12 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 14 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; |
13 | use crate::db::HirDatabase; | ||
14 | 15 | ||
15 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 16 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
16 | 17 | ||
@@ -41,7 +42,7 @@ fn deref_by_trait( | |||
41 | ) -> Option<Canonical<Ty>> { | 42 | ) -> Option<Canonical<Ty>> { |
42 | let krate = resolver.krate()?; | 43 | let krate = resolver.krate()?; |
43 | let deref_trait = match db.lang_item(krate.into(), "deref".into())? { | 44 | let deref_trait = match db.lang_item(krate.into(), "deref".into())? { |
44 | crate::lang_item::LangItemTarget::Trait(t) => t, | 45 | LangItemTarget::TraitId(t) => Trait::from(t), |
45 | _ => return None, | 46 | _ => return None, |
46 | }; | 47 | }; |
47 | let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; | 48 | let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 69b13baef..471bdc387 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -22,6 +22,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
22 | use rustc_hash::FxHashMap; | 22 | use rustc_hash::FxHashMap; |
23 | 23 | ||
24 | use hir_def::{ | 24 | use hir_def::{ |
25 | data::{ConstData, FunctionData}, | ||
25 | path::known, | 26 | path::known, |
26 | resolver::{HasResolver, Resolver, TypeNs}, | 27 | resolver::{HasResolver, Resolver, TypeNs}, |
27 | type_ref::{Mutability, TypeRef}, | 28 | type_ref::{Mutability, TypeRef}, |
@@ -43,8 +44,8 @@ use crate::{ | |||
43 | db::HirDatabase, | 44 | db::HirDatabase, |
44 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 45 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
45 | ty::infer::diagnostics::InferenceDiagnostic, | 46 | ty::infer::diagnostics::InferenceDiagnostic, |
46 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, | 47 | Adt, AssocItem, DefWithBody, FloatTy, Function, HasBody, IntTy, Path, StructField, Trait, |
47 | StructField, Trait, VariantDef, | 48 | VariantDef, |
48 | }; | 49 | }; |
49 | 50 | ||
50 | macro_rules! ty_app { | 51 | macro_rules! ty_app { |
@@ -68,10 +69,10 @@ pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResu | |||
68 | let resolver = DefWithBodyId::from(def).resolver(db); | 69 | let resolver = DefWithBodyId::from(def).resolver(db); |
69 | let mut ctx = InferenceContext::new(db, def, resolver); | 70 | let mut ctx = InferenceContext::new(db, def, resolver); |
70 | 71 | ||
71 | match def { | 72 | match &def { |
72 | DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), | 73 | DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)), |
73 | DefWithBody::Function(ref f) => ctx.collect_fn(&f.data(db)), | 74 | DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)), |
74 | DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)), | 75 | DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)), |
75 | } | 76 | } |
76 | 77 | ||
77 | ctx.infer_body(); | 78 | ctx.infer_body(); |
@@ -559,17 +560,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
559 | } | 560 | } |
560 | 561 | ||
561 | fn collect_const(&mut self, data: &ConstData) { | 562 | fn collect_const(&mut self, data: &ConstData) { |
562 | self.return_ty = self.make_ty(data.type_ref()); | 563 | self.return_ty = self.make_ty(&data.type_ref); |
563 | } | 564 | } |
564 | 565 | ||
565 | fn collect_fn(&mut self, data: &FnData) { | 566 | fn collect_fn(&mut self, data: &FunctionData) { |
566 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 567 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
567 | for (type_ref, pat) in data.params().iter().zip(body.params()) { | 568 | for (type_ref, pat) in data.params.iter().zip(body.params()) { |
568 | let ty = self.make_ty(type_ref); | 569 | let ty = self.make_ty(type_ref); |
569 | 570 | ||
570 | self.infer_pat(*pat, &ty, BindingMode::default()); | 571 | self.infer_pat(*pat, &ty, BindingMode::default()); |
571 | } | 572 | } |
572 | self.return_ty = self.make_ty(data.ret_type()); | 573 | self.return_ty = self.make_ty(&data.ret_type); |
573 | } | 574 | } |
574 | 575 | ||
575 | fn infer_body(&mut self) { | 576 | fn infer_body(&mut self) { |
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 0772b9df5..4ea038d99 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
@@ -4,13 +4,12 @@ | |||
4 | //! | 4 | //! |
5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html | 5 | //! See: https://doc.rust-lang.org/nomicon/coercions.html |
6 | 6 | ||
7 | use hir_def::resolver::Resolver; | 7 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; |
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | use test_utils::tested_by; | 9 | use test_utils::tested_by; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | db::HirDatabase, | 12 | db::HirDatabase, |
13 | lang_item::LangItemTarget, | ||
14 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, | 13 | ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, |
15 | Adt, Mutability, | 14 | Adt, Mutability, |
16 | }; | 15 | }; |
@@ -50,7 +49,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
50 | ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { | 49 | ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { |
51 | let krate = resolver.krate().unwrap(); | 50 | let krate = resolver.krate().unwrap(); |
52 | let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { | 51 | let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { |
53 | Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_), | 52 | Some(LangItemTarget::TraitId(trait_)) => { |
53 | db.impls_for_trait(krate.into(), trait_.into()) | ||
54 | } | ||
54 | _ => return FxHashMap::default(), | 55 | _ => return FxHashMap::default(), |
55 | }; | 56 | }; |
56 | 57 | ||
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 75c552569..2272510e8 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -622,10 +622,10 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> | |||
622 | } | 622 | } |
623 | 623 | ||
624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { |
625 | let data = def.data(db); | 625 | let data = db.function_data(def.id); |
626 | let resolver = def.id.resolver(db); | 626 | let resolver = def.id.resolver(db); |
627 | let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | 627 | let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); |
628 | let ret = Ty::from_hir(db, &resolver, data.ret_type()); | 628 | let ret = Ty::from_hir(db, &resolver, &data.ret_type); |
629 | FnSig::from_params_and_return(params, ret) | 629 | FnSig::from_params_and_return(params, ret) |
630 | } | 630 | } |
631 | 631 | ||
@@ -639,18 +639,18 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | |||
639 | 639 | ||
640 | /// Build the declared type of a const. | 640 | /// Build the declared type of a const. |
641 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { | 641 | fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { |
642 | let data = def.data(db); | 642 | let data = db.const_data(def.id); |
643 | let resolver = def.id.resolver(db); | 643 | let resolver = def.id.resolver(db); |
644 | 644 | ||
645 | Ty::from_hir(db, &resolver, data.type_ref()) | 645 | Ty::from_hir(db, &resolver, &data.type_ref) |
646 | } | 646 | } |
647 | 647 | ||
648 | /// Build the declared type of a static. | 648 | /// Build the declared type of a static. |
649 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { | 649 | fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { |
650 | let data = def.data(db); | 650 | let data = db.static_data(def.id); |
651 | let resolver = def.id.resolver(db); | 651 | let resolver = def.id.resolver(db); |
652 | 652 | ||
653 | Ty::from_hir(db, &resolver, data.type_ref()) | 653 | Ty::from_hir(db, &resolver, &data.type_ref) |
654 | } | 654 | } |
655 | 655 | ||
656 | /// Build the declared type of a static. | 656 | /// Build the declared type of a static. |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 64adb814d..caa5f5f74 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::resolver::Resolver; | 8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; |
9 | use rustc_hash::FxHashMap; | 9 | use rustc_hash::FxHashMap; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
@@ -91,34 +91,43 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV | |||
91 | // Types like slice can have inherent impls in several crates, (core and alloc). | 91 | // Types like slice can have inherent impls in several crates, (core and alloc). |
92 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. | 92 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. |
93 | macro_rules! lang_item_crate { | 93 | macro_rules! lang_item_crate { |
94 | ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{ | 94 | ($($name:expr),+ $(,)?) => {{ |
95 | let mut v = ArrayVec::<[Crate; 2]>::new(); | 95 | let mut v = ArrayVec::<[LangItemTarget; 2]>::new(); |
96 | $( | 96 | $( |
97 | v.extend($db.lang_item($cur_crate, $name.into()).and_then(|item| item.krate($db))); | 97 | v.extend(db.lang_item(cur_crate.crate_id, $name.into())); |
98 | )+ | 98 | )+ |
99 | Some(v) | 99 | v |
100 | }}; | 100 | }}; |
101 | } | 101 | } |
102 | 102 | ||
103 | match ty { | 103 | let lang_item_targets = match ty { |
104 | Ty::Apply(a_ty) => match a_ty.ctor { | 104 | Ty::Apply(a_ty) => match a_ty.ctor { |
105 | TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()), | 105 | TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), |
106 | TypeCtor::Bool => lang_item_crate!(db, cur_crate, "bool"), | 106 | TypeCtor::Bool => lang_item_crate!("bool"), |
107 | TypeCtor::Char => lang_item_crate!(db, cur_crate, "char"), | 107 | TypeCtor::Char => lang_item_crate!("char"), |
108 | TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { | 108 | TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { |
109 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 109 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
110 | FloatBitness::X32 => lang_item_crate!(db, cur_crate, "f32", "f32_runtime"), | 110 | FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), |
111 | FloatBitness::X64 => lang_item_crate!(db, cur_crate, "f64", "f64_runtime"), | 111 | FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), |
112 | }, | 112 | }, |
113 | TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(db, cur_crate, i.ty_to_string()), | 113 | TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()), |
114 | TypeCtor::Str => lang_item_crate!(db, cur_crate, "str_alloc", "str"), | 114 | TypeCtor::Str => lang_item_crate!("str_alloc", "str"), |
115 | TypeCtor::Slice => lang_item_crate!(db, cur_crate, "slice_alloc", "slice"), | 115 | TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), |
116 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!(db, cur_crate, "const_ptr"), | 116 | TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), |
117 | TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!(db, cur_crate, "mut_ptr"), | 117 | TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"), |
118 | _ => None, | 118 | _ => return None, |
119 | }, | 119 | }, |
120 | _ => None, | 120 | _ => return None, |
121 | } | 121 | }; |
122 | let res = lang_item_targets | ||
123 | .into_iter() | ||
124 | .filter_map(|it| match it { | ||
125 | LangItemTarget::ImplBlockId(it) => Some(it), | ||
126 | _ => None, | ||
127 | }) | ||
128 | .map(|it| it.module(db).krate.into()) | ||
129 | .collect(); | ||
130 | Some(res) | ||
122 | } | 131 | } |
123 | 132 | ||
124 | /// Look up the method with the given name, returning the actual autoderefed | 133 | /// Look up the method with the given name, returning the actual autoderefed |
@@ -233,7 +242,7 @@ fn iterate_trait_method_candidates<T>( | |||
233 | .chain(traits_from_env) | 242 | .chain(traits_from_env) |
234 | .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); | 243 | .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); |
235 | 'traits: for t in traits { | 244 | 'traits: for t in traits { |
236 | let data = t.trait_data(db); | 245 | let data = db.trait_data(t.id); |
237 | 246 | ||
238 | // we'll be lazy about checking whether the type implements the | 247 | // we'll be lazy about checking whether the type implements the |
239 | // trait, but if we find out it doesn't, we'll skip the rest of the | 248 | // trait, but if we find out it doesn't, we'll skip the rest of the |
@@ -291,9 +300,9 @@ fn is_valid_candidate( | |||
291 | ) -> bool { | 300 | ) -> bool { |
292 | match item { | 301 | match item { |
293 | AssocItem::Function(m) => { | 302 | AssocItem::Function(m) => { |
294 | let data = m.data(db); | 303 | let data = db.function_data(m.id); |
295 | name.map_or(true, |name| data.name() == name) | 304 | name.map_or(true, |name| data.name == *name) |
296 | && (data.has_self_param() || mode == LookupMode::Path) | 305 | && (data.has_self_param || mode == LookupMode::Path) |
297 | } | 306 | } |
298 | AssocItem::Const(c) => { | 307 | AssocItem::Const(c) => { |
299 | name.map_or(true, |name| Some(name) == c.name(db).as_ref()) | 308 | name.map_or(true, |name| Some(name) == c.name(db).as_ref()) |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 74c12a0a2..17a50cf74 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -4857,3 +4857,41 @@ fn main() { | |||
4857 | "### | 4857 | "### |
4858 | ); | 4858 | ); |
4859 | } | 4859 | } |
4860 | |||
4861 | #[test] | ||
4862 | fn infer_builtin_macros_file() { | ||
4863 | assert_snapshot!( | ||
4864 | infer(r#" | ||
4865 | #[rustc_builtin_macro] | ||
4866 | macro_rules! file {() => {}} | ||
4867 | |||
4868 | fn main() { | ||
4869 | let x = file!(); | ||
4870 | } | ||
4871 | "#), | ||
4872 | @r###" | ||
4873 | ![0; 2) '""': &str | ||
4874 | [64; 88) '{ ...!(); }': () | ||
4875 | [74; 75) 'x': &str | ||
4876 | "### | ||
4877 | ); | ||
4878 | } | ||
4879 | |||
4880 | #[test] | ||
4881 | fn infer_builtin_macros_column() { | ||
4882 | assert_snapshot!( | ||
4883 | infer(r#" | ||
4884 | #[rustc_builtin_macro] | ||
4885 | macro_rules! column {() => {}} | ||
4886 | |||
4887 | fn main() { | ||
4888 | let x = column!(); | ||
4889 | } | ||
4890 | "#), | ||
4891 | @r###" | ||
4892 | ![0; 2) '13': i32 | ||
4893 | [66; 92) '{ ...!(); }': () | ||
4894 | [76; 77) 'x': i32 | ||
4895 | "### | ||
4896 | ); | ||
4897 | } | ||
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 88785f305..53818a5e5 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -9,6 +9,7 @@ use chalk_ir::{ | |||
9 | }; | 9 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
12 | use hir_def::lang_item::LangItemTarget; | ||
12 | use hir_expand::name; | 13 | use hir_expand::name; |
13 | 14 | ||
14 | use ra_db::salsa::{InternId, InternKey}; | 15 | use ra_db::salsa::{InternId, InternKey}; |
@@ -832,9 +833,9 @@ fn closure_fn_trait_output_assoc_ty_value( | |||
832 | } | 833 | } |
833 | 834 | ||
834 | fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> { | 835 | fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> { |
835 | let target = db.lang_item(krate, fn_trait.lang_item_name().into())?; | 836 | let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?; |
836 | match target { | 837 | match target { |
837 | crate::lang_item::LangItemTarget::Trait(t) => Some(t), | 838 | LangItemTarget::TraitId(t) => Some(t.into()), |
838 | _ => None, | 839 | _ => None, |
839 | } | 840 | } |
840 | } | 841 | } |
diff --git a/crates/ra_hir/src/type_alias.rs b/crates/ra_hir/src/type_alias.rs deleted file mode 100644 index 392f244cf..000000000 --- a/crates/ra_hir/src/type_alias.rs +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | //! HIR for type aliases (i.e. the `type` keyword). | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_def::type_ref::TypeRef; | ||
6 | use hir_expand::name::{AsName, Name}; | ||
7 | |||
8 | use ra_syntax::ast::NameOwner; | ||
9 | |||
10 | use crate::{ | ||
11 | db::{AstDatabase, DefDatabase}, | ||
12 | HasSource, TypeAlias, | ||
13 | }; | ||
14 | |||
15 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
16 | pub struct TypeAliasData { | ||
17 | pub(crate) name: Name, | ||
18 | pub(crate) type_ref: Option<TypeRef>, | ||
19 | } | ||
20 | |||
21 | impl TypeAliasData { | ||
22 | pub(crate) fn type_alias_data_query( | ||
23 | db: &(impl DefDatabase + AstDatabase), | ||
24 | typ: TypeAlias, | ||
25 | ) -> Arc<TypeAliasData> { | ||
26 | let node = typ.source(db).value; | ||
27 | let name = node.name().map_or_else(Name::missing, |n| n.as_name()); | ||
28 | let type_ref = node.type_ref().map(TypeRef::from_ast); | ||
29 | Arc::new(TypeAliasData { name, type_ref }) | ||
30 | } | ||
31 | } | ||