From 6e2369938a6f5214680dcc0f4bb58cdb20dc1015 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 26 Jun 2019 21:50:42 +0300 Subject: make sure that CrateDefMap is independent from syntax --- crates/ra_hir/src/db.rs | 60 +++++++++++++++++++--------------- crates/ra_hir/src/ids.rs | 18 +++++----- crates/ra_hir/src/lib.rs | 2 +- crates/ra_hir/src/mock.rs | 1 + crates/ra_hir/src/nameres.rs | 4 ++- crates/ra_hir/src/nameres/collector.rs | 17 ++++------ crates/ra_ide_api/src/db.rs | 1 + 7 files changed, 55 insertions(+), 48 deletions(-) diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9840905c..8f4de1c85 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -20,13 +20,41 @@ use crate::{ 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) -> ids::FunctionId; + #[salsa::interned] + fn intern_struct(&self, loc: ids::ItemLoc) -> ids::StructId; + #[salsa::interned] + fn intern_enum(&self, loc: ids::ItemLoc) -> ids::EnumId; + #[salsa::interned] + fn intern_const(&self, loc: ids::ItemLoc) -> ids::ConstId; + #[salsa::interned] + fn intern_static(&self, loc: ids::ItemLoc) -> ids::StaticId; + #[salsa::interned] + fn intern_trait(&self, loc: ids::ItemLoc) -> ids::TraitId; + #[salsa::interned] + fn intern_type_alias(&self, loc: ids::ItemLoc) -> 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; #[salsa::transparent] @@ -40,7 +68,6 @@ pub trait AstDatabase: SourceDatabase { #[salsa::invoke(crate::ids::macro_def_query)] fn macro_def(&self, macro_id: MacroDefId) -> Option>; - #[salsa::invoke(crate::ids::macro_arg_query)] fn macro_arg(&self, macro_call: ids::MacroCallId) -> Option>; @@ -51,28 +78,7 @@ pub trait AstDatabase: SourceDatabase { // 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) -> ids::FunctionId; - #[salsa::interned] - fn intern_struct(&self, loc: ids::ItemLoc) -> ids::StructId; - #[salsa::interned] - fn intern_enum(&self, loc: ids::ItemLoc) -> ids::EnumId; - #[salsa::interned] - fn intern_const(&self, loc: ids::ItemLoc) -> ids::ConstId; - #[salsa::interned] - fn intern_static(&self, loc: ids::ItemLoc) -> ids::StaticId; - #[salsa::interned] - fn intern_trait(&self, loc: ids::ItemLoc) -> ids::TraitId; - #[salsa::interned] - fn intern_type_alias(&self, loc: ids::ItemLoc) -> 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; diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 033af1632..b7215ac03 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -9,7 +9,7 @@ use ra_prof::profile; 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 @@ -37,7 +37,7 @@ pub struct HirFileId(HirFileIdRepr); 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) => { @@ -187,7 +187,7 @@ pub struct MacroCallLoc { } 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) } @@ -198,7 +198,7 @@ impl MacroCallId { } impl MacroCallLoc { - pub(crate) fn id(self, db: &impl AstDatabase) -> MacroCallId { + pub(crate) fn id(self, db: &impl InternDatabase) -> MacroCallId { db.intern_macro(self) } } @@ -235,10 +235,13 @@ pub(crate) struct LocationCtx { 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(self, ast: &N) -> DEF where N: AstNode, @@ -257,10 +260,7 @@ pub(crate) trait AstItemDef: salsa::InternKey + Clone { 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, - ) -> Self { + fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId) -> Self { let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; Self::intern(ctx.db, loc) } diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index f07a36926..5afd846f5 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -47,7 +47,7 @@ mod code_model; mod marks; use crate::{ - db::{AstDatabase, DefDatabase, HirDatabase}, + db::{InternDatabase, AstDatabase, DefDatabase, HirDatabase}, name::{AsName, KnownName}, source_id::{FileAstId, AstId}, resolve::Resolver, diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 5d38ac76c..c57dfbf01 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -15,6 +15,7 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); #[salsa::database( ra_db::SourceDatabaseStorage, + db::InternDatabaseStorage, db::AstDatabaseStorage, db::DefDatabaseStorage, db::HirDatabaseStorage diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 3532faf01..f4ca454e4 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -231,7 +231,9 @@ fn or(left: ItemOrMacro, right: ItemOrMacro) -> ItemOrMacro { 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 { let _p = profile("crate_def_map_query"); diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index b74dc33b1..ef4d1ed70 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -7,7 +7,7 @@ use ra_syntax::ast; 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, @@ -19,10 +19,7 @@ use crate::{ 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); @@ -95,7 +92,7 @@ struct DefCollector { impl<'a, DB> DefCollector<&'a DB> where - DB: DefDatabase + AstDatabase, + DB: DefDatabase, { fn collect(&mut self) { let crate_graph = self.db.crate_graph(); @@ -465,7 +462,7 @@ where 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); } @@ -487,7 +484,7 @@ struct ModCollector<'a, D> { impl ModCollector<'_, &'_ mut DefCollector<&'_ DB>> where - DB: DefDatabase + AstDatabase, + DB: DefDatabase, { fn collect(&mut self, items: &[raw::RawItem]) { for item in items { @@ -632,7 +629,7 @@ fn is_macro_rules(path: &Path) -> bool { } fn resolve_submodule( - db: &(impl DefDatabase + AstDatabase), + db: &impl DefDatabase, file_id: HirFileId, name: &Name, is_root: bool, @@ -675,7 +672,7 @@ mod tests { use rustc_hash::FxHashSet; fn do_collect_defs( - db: &(impl DefDatabase + AstDatabase), + db: &impl DefDatabase, def_map: CrateDefMap, monitor: MacroStackMonitor, ) -> CrateDefMap { diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 82b061419..cb7d30c43 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs @@ -14,6 +14,7 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; ra_db::SourceDatabaseStorage, LineIndexDatabaseStorage, symbol_index::SymbolsDatabaseStorage, + hir::db::InternDatabaseStorage, hir::db::AstDatabaseStorage, hir::db::DefDatabaseStorage, hir::db::HirDatabaseStorage -- cgit v1.2.3