mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
Move traits to hir_def
This commit is contained in:
parent
3d56e3d855
commit
06fa3d8389
10 changed files with 103 additions and 117 deletions
|
@ -10,8 +10,9 @@ use hir_def::{
|
||||||
adt::VariantData,
|
adt::VariantData,
|
||||||
body::scope::ExprScopes,
|
body::scope::ExprScopes,
|
||||||
builtin_type::BuiltinType,
|
builtin_type::BuiltinType,
|
||||||
|
traits::TraitData,
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId,
|
AssocItemId, CrateModuleId, ImplId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
diagnostics::DiagnosticSink,
|
diagnostics::DiagnosticSink,
|
||||||
|
@ -30,7 +31,6 @@ use crate::{
|
||||||
TypeAliasId,
|
TypeAliasId,
|
||||||
},
|
},
|
||||||
resolve::{Resolver, Scope, TypeNs},
|
resolve::{Resolver, Scope, TypeNs},
|
||||||
traits::TraitData,
|
|
||||||
ty::{InferenceResult, Namespace, TraitRef},
|
ty::{InferenceResult, Namespace, TraitRef},
|
||||||
Either, HasSource, ImportId, Name, ScopeDef, Source, Ty,
|
Either, HasSource, ImportId, Name, ScopeDef, Source, Ty,
|
||||||
};
|
};
|
||||||
|
@ -230,15 +230,7 @@ impl Module {
|
||||||
|
|
||||||
pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> {
|
pub fn declarations(self, db: &impl DefDatabase) -> Vec<ModuleDef> {
|
||||||
let def_map = db.crate_def_map(self.id.krate);
|
let def_map = db.crate_def_map(self.id.krate);
|
||||||
def_map[self.id.module_id]
|
def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect()
|
||||||
.scope
|
|
||||||
.entries()
|
|
||||||
.filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
|
|
||||||
.flat_map(|per_ns| {
|
|
||||||
per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
|
|
||||||
})
|
|
||||||
.map(ModuleDef::from)
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
|
pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
|
||||||
|
@ -693,7 +685,7 @@ impl Function {
|
||||||
|
|
||||||
/// The containing trait, if this is a trait method definition.
|
/// The containing trait, if this is a trait method definition.
|
||||||
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
||||||
db.trait_items_index(self.module(db)).get_parent_trait(self.into())
|
db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
|
@ -757,7 +749,7 @@ impl Const {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
||||||
db.trait_items_index(self.module(db)).get_parent_trait(self.into())
|
db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
|
@ -861,11 +853,11 @@ impl Trait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
|
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
|
||||||
self.trait_data(db).name().clone()
|
self.trait_data(db).name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
|
pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> {
|
||||||
self.trait_data(db).items().to_vec()
|
self.trait_data(db).items.iter().map(|it| (*it).into()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
|
fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
|
||||||
|
@ -912,10 +904,10 @@ impl Trait {
|
||||||
pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
|
pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
|
||||||
let trait_data = self.trait_data(db);
|
let trait_data = self.trait_data(db);
|
||||||
trait_data
|
trait_data
|
||||||
.items()
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item {
|
||||||
AssocItem::TypeAlias(t) => Some(*t),
|
AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.find(|t| &t.name(db) == name)
|
.find(|t| &t.name(db) == name)
|
||||||
|
@ -930,7 +922,7 @@ impl Trait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> {
|
pub(crate) fn trait_data(self, db: &impl DefDatabase) -> Arc<TraitData> {
|
||||||
db.trait_data(self)
|
db.trait_data(self.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
|
pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
|
||||||
|
@ -938,7 +930,7 @@ impl Trait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_auto(self, db: &impl DefDatabase) -> bool {
|
pub fn is_auto(self, db: &impl DefDatabase) -> bool {
|
||||||
self.trait_data(db).is_auto()
|
self.trait_data(db).auto
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
|
pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
|
||||||
|
@ -971,7 +963,7 @@ impl TypeAlias {
|
||||||
|
|
||||||
/// The containing trait, if this is a trait method definition.
|
/// The containing trait, if this is a trait method definition.
|
||||||
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
pub fn parent_trait(self, db: &impl DefDatabase) -> Option<Trait> {
|
||||||
db.trait_items_index(self.module(db)).get_parent_trait(self.into())
|
db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
pub fn container(self, db: &impl DefDatabase) -> Option<Container> {
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::{
|
||||||
generics::{GenericDef, GenericParams},
|
generics::{GenericDef, GenericParams},
|
||||||
ids,
|
ids,
|
||||||
lang_item::{LangItemTarget, LangItems},
|
lang_item::{LangItemTarget, LangItems},
|
||||||
traits::TraitData,
|
|
||||||
ty::{
|
ty::{
|
||||||
method_resolution::CrateImplBlocks,
|
method_resolution::CrateImplBlocks,
|
||||||
traits::{AssocTyValue, Impl},
|
traits::{AssocTyValue, Impl},
|
||||||
|
@ -26,7 +25,8 @@ use crate::{
|
||||||
pub use hir_def::db::{
|
pub use hir_def::db::{
|
||||||
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
||||||
EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
EnumDataQuery, ExprScopesQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage,
|
||||||
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery,
|
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery, TraitDataQuery,
|
||||||
|
TraitItemsIndexQuery,
|
||||||
};
|
};
|
||||||
pub use hir_expand::db::{
|
pub use hir_expand::db::{
|
||||||
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
||||||
|
@ -37,12 +37,6 @@ pub use hir_expand::db::{
|
||||||
#[salsa::query_group(DefDatabaseStorage)]
|
#[salsa::query_group(DefDatabaseStorage)]
|
||||||
#[salsa::requires(AstDatabase)]
|
#[salsa::requires(AstDatabase)]
|
||||||
pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
|
pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
|
||||||
#[salsa::invoke(crate::traits::TraitData::trait_data_query)]
|
|
||||||
fn trait_data(&self, t: Trait) -> Arc<TraitData>;
|
|
||||||
|
|
||||||
#[salsa::invoke(crate::traits::TraitItemsIndex::trait_items_index)]
|
|
||||||
fn trait_items_index(&self, module: Module) -> crate::traits::TraitItemsIndex;
|
|
||||||
|
|
||||||
#[salsa::invoke(crate::generics::generic_params_query)]
|
#[salsa::invoke(crate::generics::generic_params_query)]
|
||||||
fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>;
|
fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ pub mod source_binder;
|
||||||
|
|
||||||
mod ids;
|
mod ids;
|
||||||
mod adt;
|
mod adt;
|
||||||
mod traits;
|
|
||||||
mod type_alias;
|
mod type_alias;
|
||||||
mod ty;
|
mod ty;
|
||||||
mod impl_block;
|
mod impl_block;
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
//! HIR for trait definitions.
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use hir_expand::name::AsName;
|
|
||||||
|
|
||||||
use ra_syntax::ast::{self, NameOwner};
|
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
db::{AstDatabase, DefDatabase},
|
|
||||||
ids::LocationCtx,
|
|
||||||
AssocItem, Const, Function, HasSource, Module, Name, Trait, TypeAlias,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct TraitData {
|
|
||||||
name: Option<Name>,
|
|
||||||
items: Vec<AssocItem>,
|
|
||||||
auto: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TraitData {
|
|
||||||
pub(crate) fn trait_data_query(
|
|
||||||
db: &(impl DefDatabase + AstDatabase),
|
|
||||||
tr: Trait,
|
|
||||||
) -> Arc<TraitData> {
|
|
||||||
let src = tr.source(db);
|
|
||||||
let name = src.value.name().map(|n| n.as_name());
|
|
||||||
let module = tr.module(db);
|
|
||||||
let ctx = LocationCtx::new(db, module.id, src.file_id);
|
|
||||||
let auto = src.value.is_auto();
|
|
||||||
let items = if let Some(item_list) = src.value.item_list() {
|
|
||||||
item_list
|
|
||||||
.impl_items()
|
|
||||||
.map(|item_node| match item_node {
|
|
||||||
ast::ImplItem::FnDef(it) => Function { id: ctx.to_def(&it) }.into(),
|
|
||||||
ast::ImplItem::ConstDef(it) => Const { id: ctx.to_def(&it) }.into(),
|
|
||||||
ast::ImplItem::TypeAliasDef(it) => TypeAlias { id: ctx.to_def(&it) }.into(),
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
};
|
|
||||||
Arc::new(TraitData { name, items, auto })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn name(&self) -> &Option<Name> {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn items(&self) -> &[AssocItem] {
|
|
||||||
&self.items
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn is_auto(&self) -> bool {
|
|
||||||
self.auto
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct TraitItemsIndex {
|
|
||||||
traits_by_def: FxHashMap<AssocItem, Trait>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TraitItemsIndex {
|
|
||||||
pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex {
|
|
||||||
let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
|
|
||||||
for decl in module.declarations(db) {
|
|
||||||
if let crate::ModuleDef::Trait(tr) = decl {
|
|
||||||
for item in tr.trait_data(db).items() {
|
|
||||||
index.traits_by_def.insert(*item, tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_parent_trait(&self, item: AssocItem) -> Option<Trait> {
|
|
||||||
self.traits_by_def.get(&item).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -232,8 +232,8 @@ fn iterate_trait_method_candidates<T>(
|
||||||
// trait, but if we find out it doesn't, we'll skip the rest of the
|
// trait, but if we find out it doesn't, we'll skip the rest of the
|
||||||
// iteration
|
// iteration
|
||||||
let mut known_implemented = false;
|
let mut known_implemented = false;
|
||||||
for &item in data.items() {
|
for &item in data.items.iter() {
|
||||||
if !is_valid_candidate(db, name, mode, item) {
|
if !is_valid_candidate(db, name, mode, item.into()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !known_implemented {
|
if !known_implemented {
|
||||||
|
@ -243,7 +243,7 @@ fn iterate_trait_method_candidates<T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
known_implemented = true;
|
known_implemented = true;
|
||||||
if let Some(result) = callback(&ty.value, item) {
|
if let Some(result) = callback(&ty.value, item.into()) {
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,13 @@ use ra_syntax::ast;
|
||||||
use crate::{
|
use crate::{
|
||||||
adt::{EnumData, StructData},
|
adt::{EnumData, StructData},
|
||||||
body::{scope::ExprScopes, Body, BodySourceMap},
|
body::{scope::ExprScopes, Body, BodySourceMap},
|
||||||
imp::ImplData,
|
impls::ImplData,
|
||||||
nameres::{
|
nameres::{
|
||||||
raw::{ImportSourceMap, RawItems},
|
raw::{ImportSourceMap, RawItems},
|
||||||
CrateDefMap,
|
CrateDefMap,
|
||||||
},
|
},
|
||||||
DefWithBodyId, EnumId, ImplId, ItemLoc, StructOrUnionId,
|
traits::{TraitData, TraitItemsIndex},
|
||||||
|
DefWithBodyId, EnumId, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::query_group(InternDatabaseStorage)]
|
#[salsa::query_group(InternDatabaseStorage)]
|
||||||
|
@ -59,6 +60,12 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
|
||||||
#[salsa::invoke(ImplData::impl_data_query)]
|
#[salsa::invoke(ImplData::impl_data_query)]
|
||||||
fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
|
fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
|
||||||
|
|
||||||
|
#[salsa::invoke(TraitData::trait_data_query)]
|
||||||
|
fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
|
||||||
|
|
||||||
|
#[salsa::invoke(TraitItemsIndex::trait_items_index)]
|
||||||
|
fn trait_items_index(&self, module: ModuleId) -> TraitItemsIndex;
|
||||||
|
|
||||||
#[salsa::invoke(Body::body_with_source_map_query)]
|
#[salsa::invoke(Body::body_with_source_map_query)]
|
||||||
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,12 @@ pub mod path;
|
||||||
pub mod type_ref;
|
pub mod type_ref;
|
||||||
pub mod builtin_type;
|
pub mod builtin_type;
|
||||||
pub mod adt;
|
pub mod adt;
|
||||||
pub mod imp;
|
pub mod impls;
|
||||||
pub mod diagnostics;
|
pub mod diagnostics;
|
||||||
pub mod expr;
|
pub mod expr;
|
||||||
pub mod body;
|
pub mod body;
|
||||||
pub mod generics;
|
pub mod generics;
|
||||||
|
pub mod traits;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db;
|
mod test_db;
|
||||||
|
|
|
@ -165,6 +165,14 @@ impl ModuleScope {
|
||||||
self.items.iter().chain(BUILTIN_SCOPE.iter())
|
self.items.iter().chain(BUILTIN_SCOPE.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
|
||||||
|
self.entries()
|
||||||
|
.filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
|
||||||
|
.flat_map(|per_ns| {
|
||||||
|
per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterate over all module scoped macros
|
/// Iterate over all module scoped macros
|
||||||
pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
||||||
self.items
|
self.items
|
||||||
|
|
67
crates/ra_hir_def/src/traits.rs
Normal file
67
crates/ra_hir_def/src/traits.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//! HIR for trait definitions.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use hir_expand::name::{AsName, Name};
|
||||||
|
|
||||||
|
use ra_syntax::ast::{self, NameOwner};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionId, LocationCtx, ModuleDefId,
|
||||||
|
ModuleId, TraitId, TypeAliasId,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct TraitData {
|
||||||
|
pub name: Option<Name>,
|
||||||
|
pub items: Vec<AssocItemId>,
|
||||||
|
pub auto: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraitData {
|
||||||
|
pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc<TraitData> {
|
||||||
|
let src = tr.source(db);
|
||||||
|
let name = src.value.name().map(|n| n.as_name());
|
||||||
|
let module = tr.module(db);
|
||||||
|
let ctx = LocationCtx::new(db, module, src.file_id);
|
||||||
|
let auto = src.value.is_auto();
|
||||||
|
let items = if let Some(item_list) = src.value.item_list() {
|
||||||
|
item_list
|
||||||
|
.impl_items()
|
||||||
|
.map(|item_node| match item_node {
|
||||||
|
ast::ImplItem::FnDef(it) => FunctionId::from_ast(ctx, &it).into(),
|
||||||
|
ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(),
|
||||||
|
ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
Arc::new(TraitData { name, items, auto })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct TraitItemsIndex {
|
||||||
|
traits_by_def: FxHashMap<AssocItemId, TraitId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraitItemsIndex {
|
||||||
|
pub fn trait_items_index(db: &impl DefDatabase2, module: ModuleId) -> TraitItemsIndex {
|
||||||
|
let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() };
|
||||||
|
let crate_def_map = db.crate_def_map(module.krate);
|
||||||
|
for decl in crate_def_map[module.module_id].scope.declarations() {
|
||||||
|
if let ModuleDefId::TraitId(tr) = decl {
|
||||||
|
for item in db.trait_data(tr).items.iter() {
|
||||||
|
index.traits_by_def.insert(*item, tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_parent_trait(&self, item: AssocItemId) -> Option<TraitId> {
|
||||||
|
self.traits_by_def.get(&item).cloned()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue