mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Move traits to hir_def
This commit is contained in:
		
							parent
							
								
									3d56e3d855
								
							
						
					
					
						commit
						06fa3d8389
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user