lang_item::{LangItems, LangItemTarget}, type_alias::TypeAliasData,
};
-// This database has access to source code, so queries here are not really
-// incremental.
-#[salsa::query_group(AstDatabaseStorage)]
-pub trait AstDatabase: SourceDatabase {
+/// We store all interned things in the single QueryGroup.
+///
+/// This is done mainly to allow both "volatile" `AstDatabase` and "stable"
+/// `DefDatabase` to access macros, without adding hard dependencies between the
+/// two.
+#[salsa::query_group(InternDatabaseStorage)]
+pub trait InternDatabase: SourceDatabase {
#[salsa::interned]
fn intern_macro(&self, macro_call: MacroCallLoc) -> ids::MacroCallId;
+ #[salsa::interned]
+ fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId;
+ #[salsa::interned]
+ fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId;
+ #[salsa::interned]
+ fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId;
+ #[salsa::interned]
+ fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId;
+ #[salsa::interned]
+ fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId;
+ #[salsa::interned]
+ fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId;
+ #[salsa::interned]
+ fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId;
+ // Interned IDs for Chalk integration
+ #[salsa::interned]
+ fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
+ #[salsa::interned]
+ fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId;
+}
+
+/// This database has access to source code, so queries here are not really
+/// incremental.
+#[salsa::query_group(AstDatabaseStorage)]
+pub trait AstDatabase: InternDatabase {
#[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)]
fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
#[salsa::transparent]
#[salsa::invoke(crate::ids::macro_def_query)]
fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>;
-
#[salsa::invoke(crate::ids::macro_arg_query)]
fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option<Arc<tt::Subtree>>;
// This database uses `AstDatabase` internally,
#[salsa::query_group(DefDatabaseStorage)]
#[salsa::requires(AstDatabase)]
-pub trait DefDatabase: SourceDatabase {
- #[salsa::interned]
- fn intern_function(&self, loc: ids::ItemLoc<ast::FnDef>) -> ids::FunctionId;
- #[salsa::interned]
- fn intern_struct(&self, loc: ids::ItemLoc<ast::StructDef>) -> ids::StructId;
- #[salsa::interned]
- fn intern_enum(&self, loc: ids::ItemLoc<ast::EnumDef>) -> ids::EnumId;
- #[salsa::interned]
- fn intern_const(&self, loc: ids::ItemLoc<ast::ConstDef>) -> ids::ConstId;
- #[salsa::interned]
- fn intern_static(&self, loc: ids::ItemLoc<ast::StaticDef>) -> ids::StaticId;
- #[salsa::interned]
- fn intern_trait(&self, loc: ids::ItemLoc<ast::TraitDef>) -> ids::TraitId;
- #[salsa::interned]
- fn intern_type_alias(&self, loc: ids::ItemLoc<ast::TypeAliasDef>) -> ids::TypeAliasId;
-
- // Interned IDs for Chalk integration
- #[salsa::interned]
- fn intern_type_ctor(&self, type_ctor: TypeCtor) -> ids::TypeCtorId;
- #[salsa::interned]
- fn intern_impl_block(&self, impl_block: ImplBlock) -> ids::GlobalImplId;
-
+pub trait DefDatabase: InternDatabase {
#[salsa::invoke(crate::adt::StructData::struct_data_query)]
fn struct_data(&self, s: Struct) -> Arc<StructData>;
use mbe::MacroRules;
use crate::{
- Module, DefDatabase, AstId, FileAstId, AstDatabase, Source,
+ Module, DefDatabase, AstId, FileAstId, AstDatabase, Source, InternDatabase,
};
/// hir makes heavy use of ids: integer (u32) handlers to various things. You
impl HirFileId {
/// For macro-expansion files, returns the file original source file the
/// expansion originated from.
- pub fn original_file(self, db: &impl AstDatabase) -> FileId {
+ pub fn original_file(self, db: &impl InternDatabase) -> FileId {
match self.0 {
HirFileIdRepr::File(file_id) => file_id,
HirFileIdRepr::Macro(macro_file) => {
}
impl MacroCallId {
- pub(crate) fn loc(self, db: &impl AstDatabase) -> MacroCallLoc {
+ pub(crate) fn loc(self, db: &impl InternDatabase) -> MacroCallLoc {
db.lookup_intern_macro(self)
}
}
impl MacroCallLoc {
- pub(crate) fn id(self, db: &impl AstDatabase) -> MacroCallId {
+ pub(crate) fn id(self, db: &impl InternDatabase) -> MacroCallId {
db.intern_macro(self)
}
}
file_id: HirFileId,
}
-impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> {
+impl<'a, DB: DefDatabase> LocationCtx<&'a DB> {
pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> {
LocationCtx { db, module, file_id }
}
+}
+
+impl<'a, DB: DefDatabase + AstDatabase> LocationCtx<&'a DB> {
pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF
where
N: AstNode,
let item_id = items.ast_id(ast);
Self::from_ast_id(ctx, item_id)
}
- fn from_ast_id(
- ctx: LocationCtx<&(impl AstDatabase + DefDatabase)>,
- ast_id: FileAstId<N>,
- ) -> Self {
+ fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self {
let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) };
Self::intern(ctx.db, loc)
}
mod marks;
use crate::{
- db::{AstDatabase, DefDatabase, HirDatabase},
+ db::{InternDatabase, AstDatabase, DefDatabase, HirDatabase},
name::{AsName, KnownName},
source_id::{FileAstId, AstId},
resolve::Resolver,
#[salsa::database(
ra_db::SourceDatabaseStorage,
+ db::InternDatabaseStorage,
db::AstDatabaseStorage,
db::DefDatabaseStorage,
db::HirDatabaseStorage
impl CrateDefMap {
pub(crate) fn crate_def_map_query(
- db: &(impl DefDatabase + AstDatabase),
+ // Note that this doesn't have `+ AstDatabase`!
+ // This gurantess that `CrateDefMap` is stable across reparses.
+ db: &impl DefDatabase,
krate: Crate,
) -> Arc<CrateDefMap> {
let _p = profile("crate_def_map_query");
use crate::{
Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias, MacroDef,
- DefDatabase, HirFileId, Name, Path, AstDatabase,
+ DefDatabase, HirFileId, Name, Path,
KnownName, AstId,
nameres::{
Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode,
either::Either,
};
-pub(super) fn collect_defs(
- db: &(impl DefDatabase + AstDatabase),
- mut def_map: CrateDefMap,
-) -> CrateDefMap {
+pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
// populate external prelude
for dep in def_map.krate.dependencies(db) {
log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate);
impl<'a, DB> DefCollector<&'a DB>
where
- DB: DefDatabase + AstDatabase,
+ DB: DefDatabase,
{
fn collect(&mut self) {
let crate_graph = self.db.crate_graph();
ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items }
.collect(raw_items.items());
} else {
- log::error!("Too deep macro expansion: {}", macro_call_id.debug_dump(self.db));
+ log::error!("Too deep macro expansion: {:?}", macro_call_id);
self.def_map.poison_macros.insert(macro_def_id);
}
impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>>
where
- DB: DefDatabase + AstDatabase,
+ DB: DefDatabase,
{
fn collect(&mut self, items: &[raw::RawItem]) {
for item in items {
}
fn resolve_submodule(
- db: &(impl DefDatabase + AstDatabase),
+ db: &impl DefDatabase,
file_id: HirFileId,
name: &Name,
is_root: bool,
use rustc_hash::FxHashSet;
fn do_collect_defs(
- db: &(impl DefDatabase + AstDatabase),
+ db: &impl DefDatabase,
def_map: CrateDefMap,
monitor: MacroStackMonitor,
) -> CrateDefMap {
ra_db::SourceDatabaseStorage,
LineIndexDatabaseStorage,
symbol_index::SymbolsDatabaseStorage,
+ hir::db::InternDatabaseStorage,
hir::db::AstDatabaseStorage,
hir::db::DefDatabaseStorage,
hir::db::HirDatabaseStorage