aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs70
-rw-r--r--crates/ra_hir/src/lib.rs8
2 files changed, 64 insertions, 14 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 4d9641728..4fb679f6d 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -10,9 +10,9 @@ use hir_def::{
10 per_ns::PerNs, 10 per_ns::PerNs,
11 resolver::HasResolver, 11 resolver::HasResolver,
12 type_ref::{Mutability, TypeRef}, 12 type_ref::{Mutability, TypeRef},
13 AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, 13 AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
14 LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, 14 ImplId, LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId,
15 TraitId, TypeAliasId, TypeParamId, UnionId, 15 StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
16}; 16};
17use hir_expand::{ 17use hir_expand::{
18 diagnostics::DiagnosticSink, 18 diagnostics::DiagnosticSink,
@@ -25,7 +25,10 @@ use hir_ty::{
25}; 25};
26use ra_db::{CrateId, Edition, FileId}; 26use ra_db::{CrateId, Edition, FileId};
27use ra_prof::profile; 27use ra_prof::profile;
28use ra_syntax::ast::{self, AttrsOwner}; 28use ra_syntax::{
29 ast::{self, AttrsOwner},
30 AstNode,
31};
29 32
30use crate::{ 33use crate::{
31 db::{DefDatabase, HirDatabase}, 34 db::{DefDatabase, HirDatabase},
@@ -119,7 +122,9 @@ impl_froms!(
119 BuiltinType 122 BuiltinType
120); 123);
121 124
122pub use hir_def::{attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId}; 125pub use hir_def::{
126 attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc,
127};
123use rustc_hash::FxHashSet; 128use rustc_hash::FxHashSet;
124 129
125impl Module { 130impl Module {
@@ -639,17 +644,49 @@ pub struct MacroDef {
639 pub(crate) id: MacroDefId, 644 pub(crate) id: MacroDefId,
640} 645}
641 646
647/// Invariant: `inner.as_assoc_item(db).is_some()`
648/// We do not actively enforce this invariant.
642#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 649#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
643pub enum AssocItem { 650pub enum AssocItem {
644 Function(Function), 651 Function(Function),
645 Const(Const), 652 Const(Const),
646 TypeAlias(TypeAlias), 653 TypeAlias(TypeAlias),
647} 654}
648// FIXME: not every function, ... is actually an assoc item. maybe we should make 655pub enum AssocItemContainer {
649// sure that you can only turn actual assoc items into AssocItems. This would 656 Trait(Trait),
650// require not implementing From, and instead having some checked way of 657 ImplBlock(ImplBlock),
651// casting them, and somehow making the constructors private, which would be annoying. 658}
652impl_froms!(AssocItem: Function, Const, TypeAlias); 659pub trait AsAssocItem {
660 fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem>;
661}
662
663impl AsAssocItem for Function {
664 fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> {
665 as_assoc_item(db, AssocItem::Function, self.id)
666 }
667}
668impl AsAssocItem for Const {
669 fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> {
670 as_assoc_item(db, AssocItem::Const, self.id)
671 }
672}
673impl AsAssocItem for TypeAlias {
674 fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem> {
675 as_assoc_item(db, AssocItem::TypeAlias, self.id)
676 }
677}
678fn as_assoc_item<ID, DEF, CTOR, AST>(db: &impl DefDatabase, ctor: CTOR, id: ID) -> Option<AssocItem>
679where
680 ID: Lookup<Data = AssocItemLoc<AST>>,
681 DEF: From<ID>,
682 CTOR: FnOnce(DEF) -> AssocItem,
683 AST: AstNode,
684{
685 match id.lookup(db).container {
686 AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
687 AssocContainerId::ContainerId(_) => None,
688 }
689}
653 690
654impl AssocItem { 691impl AssocItem {
655 pub fn module(self, db: &impl DefDatabase) -> Module { 692 pub fn module(self, db: &impl DefDatabase) -> Module {
@@ -659,6 +696,18 @@ impl AssocItem {
659 AssocItem::TypeAlias(t) => t.module(db), 696 AssocItem::TypeAlias(t) => t.module(db),
660 } 697 }
661 } 698 }
699 pub fn container(self, db: &impl DefDatabase) -> AssocItemContainer {
700 let container = match self {
701 AssocItem::Function(it) => it.id.lookup(db).container,
702 AssocItem::Const(it) => it.id.lookup(db).container,
703 AssocItem::TypeAlias(it) => it.id.lookup(db).container,
704 };
705 match container {
706 AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
707 AssocContainerId::ImplId(id) => AssocItemContainer::ImplBlock(id.into()),
708 AssocContainerId::ContainerId(_) => panic!("invalid AssocItem"),
709 }
710 }
662} 711}
663 712
664#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 713#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
@@ -769,6 +818,7 @@ impl TypeParam {
769 } 818 }
770} 819}
771 820
821// FIXME: rename to `ImplBlock`
772#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 822#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
773pub struct ImplBlock { 823pub struct ImplBlock {
774 pub(crate) id: ImplId, 824 pub(crate) id: ImplId,
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index e1c7b7a20..5cd965f7a 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -39,10 +39,10 @@ mod has_source;
39 39
40pub use crate::{ 40pub use crate::{
41 code_model::{ 41 code_model::{
42 Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, 42 Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, CrateDependency,
43 EnumVariant, FieldSource, Function, GenericDef, HasAttrs, HasVisibility, ImplBlock, Local, 43 DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, HasAttrs,
44 MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, 44 HasVisibility, ImplBlock, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct,
45 TypeParam, Union, VariantDef, 45 StructField, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
46 }, 46 },
47 has_source::HasSource, 47 has_source::HasSource,
48 source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, 48 source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},