Skip to content

Commit 225fc35

Browse files
committed
Add more hir APIs for associated items
1 parent 759100f commit 225fc35

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use hir_def::{
1010
per_ns::PerNs,
1111
resolver::HasResolver,
1212
type_ref::{Mutability, TypeRef},
13-
AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
14-
LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId,
15-
TraitId, TypeAliasId, TypeParamId, UnionId,
13+
AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
14+
ImplId, LocalEnumVariantId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId,
15+
StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
1616
};
1717
use hir_expand::{
1818
diagnostics::DiagnosticSink,
@@ -25,7 +25,10 @@ use hir_ty::{
2525
};
2626
use ra_db::{CrateId, Edition, FileId};
2727
use ra_prof::profile;
28-
use ra_syntax::ast::{self, AttrsOwner};
28+
use ra_syntax::{
29+
ast::{self, AttrsOwner},
30+
AstNode,
31+
};
2932

3033
use crate::{
3134
db::{DefDatabase, HirDatabase},
@@ -119,7 +122,9 @@ impl_froms!(
119122
BuiltinType
120123
);
121124

122-
pub use hir_def::{attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId};
125+
pub use hir_def::{
126+
attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc,
127+
};
123128
use rustc_hash::FxHashSet;
124129

125130
impl Module {
@@ -639,17 +644,49 @@ pub struct MacroDef {
639644
pub(crate) id: MacroDefId,
640645
}
641646

647+
/// Invariant: `inner.as_assoc_item(db).is_some()`
648+
/// We do not actively enforce this invariant.
642649
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
643650
pub enum AssocItem {
644651
Function(Function),
645652
Const(Const),
646653
TypeAlias(TypeAlias),
647654
}
648-
// FIXME: not every function, ... is actually an assoc item. maybe we should make
649-
// sure that you can only turn actual assoc items into AssocItems. This would
650-
// require not implementing From, and instead having some checked way of
651-
// casting them, and somehow making the constructors private, which would be annoying.
652-
impl_froms!(AssocItem: Function, Const, TypeAlias);
655+
pub enum AssocItemContainer {
656+
Trait(Trait),
657+
ImplBlock(ImplBlock),
658+
}
659+
pub trait AsAssocItem {
660+
fn as_assoc_item(self, db: &impl DefDatabase) -> Option<AssocItem>;
661+
}
662+
663+
impl 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+
}
668+
impl 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+
}
673+
impl 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+
}
678+
fn as_assoc_item<ID, DEF, CTOR, AST>(db: &impl DefDatabase, ctor: CTOR, id: ID) -> Option<AssocItem>
679+
where
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+
}
653690

654691
impl AssocItem {
655692
pub fn module(self, db: &impl DefDatabase) -> Module {
@@ -659,6 +696,18 @@ impl AssocItem {
659696
AssocItem::TypeAlias(t) => t.module(db),
660697
}
661698
}
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+
}
662711
}
663712

664713
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
@@ -769,6 +818,7 @@ impl TypeParam {
769818
}
770819
}
771820

821+
// FIXME: rename to `ImplBlock`
772822
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
773823
pub struct ImplBlock {
774824
pub(crate) id: ImplId,

crates/ra_hir/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ mod has_source;
3939

4040
pub use crate::{
4141
code_model::{
42-
Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum,
43-
EnumVariant, FieldSource, Function, GenericDef, HasAttrs, HasVisibility, ImplBlock, Local,
44-
MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias,
45-
TypeParam, Union, VariantDef,
42+
Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrDef, Const, Crate, CrateDependency,
43+
DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, HasAttrs,
44+
HasVisibility, ImplBlock, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, Struct,
45+
StructField, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
4646
},
4747
has_source::HasSource,
4848
source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},

0 commit comments

Comments
 (0)