From 6b993a97602da5ddee4033d4d76a68471f8d1ee1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 9 Apr 2019 22:51:22 +0300 Subject: migrate to salsas interning --- crates/ra_batch/src/lib.rs | 12 +--- crates/ra_hir/src/db.rs | 26 +++++-- crates/ra_hir/src/expr/scope.rs | 8 ++- crates/ra_hir/src/ids.rs | 145 +++++++++++++++++++++------------------- crates/ra_hir/src/lib.rs | 2 +- crates/ra_hir/src/mock.rs | 11 +-- crates/ra_ide_api/src/db.rs | 9 --- crates/ra_ide_api/src/status.rs | 7 +- 8 files changed, 109 insertions(+), 111 deletions(-) diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index 5bb47afb2..0cafe617d 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -9,7 +9,7 @@ use rustc_hash::FxHashMap; use ra_db::{ CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, }; -use ra_hir::{db, HirInterner}; +use ra_hir::db; use ra_project_model::ProjectWorkspace; use ra_vfs::{Vfs, VfsChange}; use vfs_filter::IncludeRustFiles; @@ -20,7 +20,6 @@ type Result = std::result::Result; #[derive(Debug)] pub struct BatchDatabase { runtime: salsa::Runtime, - interner: Arc, } impl salsa::Database for BatchDatabase { @@ -29,12 +28,6 @@ impl salsa::Database for BatchDatabase { } } -impl AsRef for BatchDatabase { - fn as_ref(&self) -> &HirInterner { - &self.interner - } -} - fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { FileId(f.0.into()) } @@ -44,8 +37,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { impl BatchDatabase { pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { - let mut db = - BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() }; + let mut db = BatchDatabase { runtime: salsa::Runtime::default() }; db.set_crate_graph(Arc::new(crate_graph)); // wait until Vfs has loaded all roots diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index be8a8c98b..e23e2bb2b 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -1,10 +1,10 @@ use std::sync::Arc; -use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; +use ra_syntax::{SyntaxNode, TreeArc, SourceFile, ast}; use ra_db::{SourceDatabase, salsa}; use crate::{ - HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, HirInterner, + HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, MacroCallLoc, Function, FnSignature, ExprScopes, TypeAlias, Struct, Enum, StructField, Const, ConstSignature, Static, @@ -15,11 +15,29 @@ use crate::{ impl_block::{ModuleImplBlocks, ImplSourceMap}, generics::{GenericParams, GenericDef}, type_ref::TypeRef, - traits::TraitData, Trait, ty::TraitRef + traits::TraitData, Trait, ty::TraitRef, + ids }; #[salsa::query_group(DefDatabaseStorage)] -pub trait DefDatabase: SourceDatabase + AsRef { +pub trait DefDatabase: 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; + #[salsa::invoke(crate::ids::macro_def_query)] fn macro_def(&self, macro_id: MacroDefId) -> Option>; diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index 48283907b..f1e6e0f02 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs @@ -294,9 +294,9 @@ pub struct ReferenceDescriptor { #[cfg(test)] mod tests { + use ra_db::salsa::InternKey; use ra_syntax::{SourceFile, algo::find_node_at_offset}; use test_utils::{extract_offset, assert_eq_text}; - use ra_arena::ArenaId; use crate::Function; use crate::expr::{ExprCollector}; @@ -316,7 +316,8 @@ mod tests { let file = SourceFile::parse(&code); let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); - let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; + let irrelevant_function = + Function { id: crate::ids::FunctionId::from_intern_id(0u32.into()) }; let (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def); let scopes = ExprScopes::new(Arc::new(body)); let scopes = @@ -421,7 +422,8 @@ mod tests { let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); - let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; + let irrelevant_function = + Function { id: crate::ids::FunctionId::from_intern_id(0u32.into()) }; let (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def); let scopes = ExprScopes::new(Arc::new(body)); let scopes = diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index eb9939df7..141c9072f 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -3,40 +3,14 @@ use std::{ sync::Arc, }; -use ra_db::{LocationInterner, FileId}; +use ra_db::{FileId, salsa}; use ra_syntax::{TreeArc, SourceFile, AstNode, ast}; -use ra_arena::{RawId, ArenaId, impl_arena_id}; use mbe::MacroRules; use crate::{ Module, DefDatabase, AstId, FileAstId, }; -#[derive(Debug, Default)] -pub struct HirInterner { - macros: LocationInterner, - fns: LocationInterner, FunctionId>, - structs: LocationInterner, StructId>, - enums: LocationInterner, EnumId>, - consts: LocationInterner, ConstId>, - statics: LocationInterner, StaticId>, - traits: LocationInterner, TraitId>, - types: LocationInterner, TypeAliasId>, -} - -impl HirInterner { - pub fn len(&self) -> usize { - self.macros.len() - + self.fns.len() - + self.structs.len() - + self.enums.len() - + self.consts.len() - + self.statics.len() - + self.traits.len() - + self.types.len() - } -} - /// hir makes heavy use of ids: integer (u32) handlers to various things. You /// can think of id as a pointer (but without a lifetime) or a file descriptor /// (but for hir objects). @@ -135,11 +109,24 @@ pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option { + impl salsa::InternKey for $name { + fn from_intern_id(v: salsa::InternId) -> Self { + $name(v) + } + fn as_intern_id(&self) -> salsa::InternId { + self.0 + } + } + }; +} + /// `MacroCallId` identifies a particular macro invocation, like /// `println!("Hello, {}", world)`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct MacroCallId(RawId); -impl_arena_id!(MacroCallId); +pub struct MacroCallId(salsa::InternId); +impl_intern_key!(MacroCallId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroCallLoc { @@ -148,14 +135,14 @@ pub struct MacroCallLoc { } impl MacroCallId { - pub(crate) fn loc(self, db: &impl AsRef) -> MacroCallLoc { - db.as_ref().macros.id2loc(self) + pub(crate) fn loc(self, db: &impl DefDatabase) -> MacroCallLoc { + db.lookup_intern_macro(self) } } impl MacroCallLoc { - pub(crate) fn id(&self, db: &impl AsRef) -> MacroCallId { - db.as_ref().macros.loc2id(&self) + pub(crate) fn id(self, db: &impl DefDatabase) -> MacroCallId { + db.intern_macro(self) } } @@ -204,8 +191,10 @@ impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { } } -pub(crate) trait AstItemDef: ArenaId + Clone { - fn interner(interner: &HirInterner) -> &LocationInterner, Self>; +pub(crate) trait AstItemDef: salsa::InternKey + Clone { + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self; + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc; + fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { let items = ctx.db.ast_id_map(ctx.file_id); let item_id = items.ast_id(ast); @@ -213,80 +202,100 @@ pub(crate) trait AstItemDef: ArenaId + Clone { } 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::interner(ctx.db.as_ref()).loc2id(&loc) + Self::intern(ctx.db, loc) } fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc) { - let int = Self::interner(db.as_ref()); - let loc = int.id2loc(self); + let loc = self.lookup_intern(db); let ast = loc.ast_id.to_node(db); (loc.ast_id.file_id(), ast) } fn module(self, db: &impl DefDatabase) -> Module { - let int = Self::interner(db.as_ref()); - let loc = int.id2loc(self); + let loc = self.lookup_intern(db); loc.module } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct FunctionId(RawId); -impl_arena_id!(FunctionId); +pub struct FunctionId(salsa::InternId); +impl_intern_key!(FunctionId); + impl AstItemDef for FunctionId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.fns + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_function(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_function(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct StructId(RawId); -impl_arena_id!(StructId); +pub struct StructId(salsa::InternId); +impl_intern_key!(StructId); impl AstItemDef for StructId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.structs + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_struct(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_struct(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct EnumId(RawId); -impl_arena_id!(EnumId); +pub struct EnumId(salsa::InternId); +impl_intern_key!(EnumId); impl AstItemDef for EnumId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.enums + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_enum(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_enum(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct ConstId(RawId); -impl_arena_id!(ConstId); +pub struct ConstId(salsa::InternId); +impl_intern_key!(ConstId); impl AstItemDef for ConstId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.consts + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_const(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_const(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct StaticId(RawId); -impl_arena_id!(StaticId); +pub struct StaticId(salsa::InternId); +impl_intern_key!(StaticId); impl AstItemDef for StaticId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.statics + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_static(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_static(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct TraitId(RawId); -impl_arena_id!(TraitId); +pub struct TraitId(salsa::InternId); +impl_intern_key!(TraitId); impl AstItemDef for TraitId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.traits + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_trait(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_trait(self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct TypeAliasId(RawId); -impl_arena_id!(TypeAliasId); +pub struct TypeAliasId(salsa::InternId); +impl_intern_key!(TypeAliasId); impl AstItemDef for TypeAliasId { - fn interner(interner: &HirInterner) -> &LocationInterner, Self> { - &interner.types + fn intern(db: &impl DefDatabase, loc: ItemLoc) -> Self { + db.intern_type_alias(loc) + } + fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc { + db.lookup_intern_type_alias(self) } } diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index c19450f39..4d337d2e3 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -55,7 +55,7 @@ pub use self::{ path::{Path, PathKind}, name::Name, source_id::{AstIdMap, ErasedFileAstId}, - ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, + ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc}, nameres::{PerNs, Namespace, ImportId, ImportSource}, ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, impl_block::{ImplBlock, ImplItem}, diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index aeab6b180..fa5882dea 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -9,7 +9,7 @@ use relative_path::RelativePathBuf; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; use rustc_hash::FxHashMap; -use crate::{db, HirInterner, diagnostics::DiagnosticSink}; +use crate::{db, diagnostics::DiagnosticSink}; pub const WORKSPACE: SourceRootId = SourceRootId(0); @@ -18,7 +18,6 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0); pub struct MockDatabase { events: Mutex>>>, runtime: salsa::Runtime, - interner: Arc, files: FxHashMap, } @@ -195,7 +194,6 @@ impl Default for MockDatabase { let mut db = MockDatabase { events: Default::default(), runtime: salsa::Runtime::default(), - interner: Default::default(), files: FxHashMap::default(), }; db.set_crate_graph(Default::default()); @@ -208,19 +206,12 @@ impl salsa::ParallelDatabase for MockDatabase { salsa::Snapshot::new(MockDatabase { events: Default::default(), runtime: self.runtime.snapshot(self), - interner: Arc::clone(&self.interner), // only the root database can be used to get file_id by path. files: FxHashMap::default(), }) } } -impl AsRef for MockDatabase { - fn as_ref(&self) -> &HirInterner { - &self.interner - } -} - impl MockDatabase { pub fn log(&self, f: impl FnOnce()) -> Vec> { *self.events.lock() = Some(Vec::new()); diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index ea4255d35..33d3903bb 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs @@ -20,7 +20,6 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}}; #[derive(Debug)] pub(crate) struct RootDatabase { runtime: salsa::Runtime, - interner: Arc, pub(crate) last_gc: time::Instant, pub(crate) last_gc_check: time::Instant, } @@ -38,7 +37,6 @@ impl Default for RootDatabase { fn default() -> RootDatabase { let mut db = RootDatabase { runtime: salsa::Runtime::default(), - interner: Default::default(), last_gc: time::Instant::now(), last_gc_check: time::Instant::now(), }; @@ -53,19 +51,12 @@ impl salsa::ParallelDatabase for RootDatabase { fn snapshot(&self) -> salsa::Snapshot { salsa::Snapshot::new(RootDatabase { runtime: self.runtime.snapshot(self), - interner: Arc::clone(&self.interner), last_gc: self.last_gc.clone(), last_gc_check: self.last_gc_check.clone(), }) } } -impl AsRef for RootDatabase { - fn as_ref(&self) -> &hir::HirInterner { - &self.interner - } -} - #[salsa::query_group(LineIndexDatabaseStorage)] pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled { fn line_index(&self, file_id: FileId) -> Arc; diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index e0fc1c123..d99a4e750 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs @@ -23,16 +23,11 @@ pub(crate) fn status(db: &RootDatabase) -> String { let files_stats = db.query(FileTextQuery).entries::(); let syntax_tree_stats = syntax_tree_stats(db); let symbols_stats = db.query(LibrarySymbolsQuery).entries::(); - let n_defs = { - let interner: &hir::HirInterner = db.as_ref(); - interner.len() - }; format!( - "{}\n{}\n{}\n{} defs\n\nmemory:\n{}\ngc {:?} seconds ago", + "{}\n{}\n{}\n\n\nmemory:\n{}\ngc {:?} seconds ago", files_stats, symbols_stats, syntax_tree_stats, - n_defs, MemoryStats::current(), db.last_gc.elapsed().as_secs(), ) -- cgit v1.2.3