1126: Swithc to native salsa interning r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-04-09 20:04:42 +00:00
commit b863272899
10 changed files with 110 additions and 219 deletions

View file

@ -9,7 +9,7 @@ use rustc_hash::FxHashMap;
use ra_db::{ use ra_db::{
CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa, CrateGraph, FileId, SourceRoot, SourceRootId, SourceDatabase, salsa,
}; };
use ra_hir::{db, HirInterner}; use ra_hir::db;
use ra_project_model::ProjectWorkspace; use ra_project_model::ProjectWorkspace;
use ra_vfs::{Vfs, VfsChange}; use ra_vfs::{Vfs, VfsChange};
use vfs_filter::IncludeRustFiles; use vfs_filter::IncludeRustFiles;
@ -20,7 +20,6 @@ type Result<T> = std::result::Result<T, failure::Error>;
#[derive(Debug)] #[derive(Debug)]
pub struct BatchDatabase { pub struct BatchDatabase {
runtime: salsa::Runtime<BatchDatabase>, runtime: salsa::Runtime<BatchDatabase>,
interner: Arc<HirInterner>,
} }
impl salsa::Database for BatchDatabase { impl salsa::Database for BatchDatabase {
@ -29,12 +28,6 @@ impl salsa::Database for BatchDatabase {
} }
} }
impl AsRef<HirInterner> for BatchDatabase {
fn as_ref(&self) -> &HirInterner {
&self.interner
}
}
fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
FileId(f.0.into()) FileId(f.0.into())
} }
@ -44,8 +37,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
impl BatchDatabase { impl BatchDatabase {
pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase { pub fn load(crate_graph: CrateGraph, vfs: &mut Vfs) -> BatchDatabase {
let mut db = let mut db = BatchDatabase { runtime: salsa::Runtime::default() };
BatchDatabase { runtime: salsa::Runtime::default(), interner: Default::default() };
db.set_crate_graph(Arc::new(crate_graph)); db.set_crate_graph(Arc::new(crate_graph));
// wait until Vfs has loaded all roots // wait until Vfs has loaded all roots

View file

@ -1,11 +1,8 @@
//! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api.
mod cancellation; mod cancellation;
mod input; mod input;
mod loc2id;
use std::{ use std::{panic, sync::Arc};
panic, sync::Arc,
};
use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc};
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
@ -16,7 +13,6 @@ pub use crate::{
input::{ input::{
FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition,
}, },
loc2id::LocationInterner,
}; };
pub trait CheckCanceled: panic::RefUnwindSafe { pub trait CheckCanceled: panic::RefUnwindSafe {

View file

@ -1,103 +0,0 @@
use std::{panic, hash::Hash};
use parking_lot::Mutex;
use rustc_hash::FxHashMap;
use ra_arena::{Arena, ArenaId};
/// There are two principle ways to refer to things:
/// - by their location (module in foo/bar/baz.rs at line 42)
/// - by their numeric id (module `ModuleId(42)`)
///
/// The first one is more powerful (you can actually find the thing in question
/// by id), but the second one is so much more compact.
///
/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
/// bidirectional mapping between positional and numeric ids, we can use compact
/// representation which still allows us to get the actual item.
#[derive(Debug)]
struct Loc2IdMap<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
id2loc: Arena<ID, LOC>,
loc2id: FxHashMap<LOC, ID>,
}
impl<LOC, ID> Default for Loc2IdMap<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
fn default() -> Self {
Loc2IdMap { id2loc: Arena::default(), loc2id: FxHashMap::default() }
}
}
impl<LOC, ID> Loc2IdMap<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
pub fn len(&self) -> usize {
self.id2loc.len()
}
pub fn loc2id(&mut self, loc: &LOC) -> ID {
match self.loc2id.get(loc) {
Some(id) => return id.clone(),
None => (),
}
let id = self.id2loc.alloc(loc.clone());
self.loc2id.insert(loc.clone(), id.clone());
id
}
pub fn id2loc(&self, id: ID) -> LOC {
self.id2loc[id].clone()
}
}
#[derive(Debug)]
pub struct LocationInterner<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
map: Mutex<Loc2IdMap<LOC, ID>>,
}
impl<LOC, ID> panic::RefUnwindSafe for LocationInterner<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
ID: panic::RefUnwindSafe,
LOC: panic::RefUnwindSafe,
{
}
impl<LOC, ID> Default for LocationInterner<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
fn default() -> Self {
LocationInterner { map: Default::default() }
}
}
impl<LOC, ID> LocationInterner<LOC, ID>
where
ID: ArenaId + Clone,
LOC: Clone + Eq + Hash,
{
pub fn len(&self) -> usize {
self.map.lock().len()
}
pub fn loc2id(&self, loc: &LOC) -> ID {
self.map.lock().loc2id(loc)
}
pub fn id2loc(&self, id: ID) -> LOC {
self.map.lock().id2loc(id)
}
}

View file

@ -1,10 +1,10 @@
use std::sync::Arc; use std::sync::Arc;
use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; use ra_syntax::{SyntaxNode, TreeArc, SourceFile, ast};
use ra_db::{SourceDatabase, salsa}; use ra_db::{SourceDatabase, salsa};
use crate::{ use crate::{
HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, HirInterner, HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, MacroCallLoc,
Function, FnSignature, ExprScopes, TypeAlias, Function, FnSignature, ExprScopes, TypeAlias,
Struct, Enum, StructField, Struct, Enum, StructField,
Const, ConstSignature, Static, Const, ConstSignature, Static,
@ -15,11 +15,29 @@ use crate::{
impl_block::{ModuleImplBlocks, ImplSourceMap}, impl_block::{ModuleImplBlocks, ImplSourceMap},
generics::{GenericParams, GenericDef}, generics::{GenericParams, GenericDef},
type_ref::TypeRef, type_ref::TypeRef,
traits::TraitData, Trait, ty::TraitRef traits::TraitData, Trait, ty::TraitRef,
ids
}; };
#[salsa::query_group(DefDatabaseStorage)] #[salsa::query_group(DefDatabaseStorage)]
pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { pub trait DefDatabase: 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;
#[salsa::invoke(crate::ids::macro_def_query)] #[salsa::invoke(crate::ids::macro_def_query)]
fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>;

View file

@ -294,9 +294,9 @@ pub struct ReferenceDescriptor {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ra_db::salsa::InternKey;
use ra_syntax::{SourceFile, algo::find_node_at_offset}; use ra_syntax::{SourceFile, algo::find_node_at_offset};
use test_utils::{extract_offset, assert_eq_text}; use test_utils::{extract_offset, assert_eq_text};
use ra_arena::ArenaId;
use crate::Function; use crate::Function;
use crate::expr::{ExprCollector}; use crate::expr::{ExprCollector};
@ -316,7 +316,8 @@ mod tests {
let file = SourceFile::parse(&code); let file = SourceFile::parse(&code);
let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); 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 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 (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def);
let scopes = ExprScopes::new(Arc::new(body)); let scopes = ExprScopes::new(Arc::new(body));
let scopes = let scopes =
@ -421,7 +422,8 @@ mod tests {
let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); 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 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 (body, source_map) = collect_fn_body_syntax(irrelevant_function, fn_def);
let scopes = ExprScopes::new(Arc::new(body)); let scopes = ExprScopes::new(Arc::new(body));
let scopes = let scopes =

View file

@ -3,40 +3,14 @@ use std::{
sync::Arc, sync::Arc,
}; };
use ra_db::{LocationInterner, FileId}; use ra_db::{FileId, salsa};
use ra_syntax::{TreeArc, SourceFile, AstNode, ast}; use ra_syntax::{TreeArc, SourceFile, AstNode, ast};
use ra_arena::{RawId, ArenaId, impl_arena_id};
use mbe::MacroRules; use mbe::MacroRules;
use crate::{ use crate::{
Module, DefDatabase, AstId, FileAstId, Module, DefDatabase, AstId, FileAstId,
}; };
#[derive(Debug, Default)]
pub struct HirInterner {
macros: LocationInterner<MacroCallLoc, MacroCallId>,
fns: LocationInterner<ItemLoc<ast::FnDef>, FunctionId>,
structs: LocationInterner<ItemLoc<ast::StructDef>, StructId>,
enums: LocationInterner<ItemLoc<ast::EnumDef>, EnumId>,
consts: LocationInterner<ItemLoc<ast::ConstDef>, ConstId>,
statics: LocationInterner<ItemLoc<ast::StaticDef>, StaticId>,
traits: LocationInterner<ItemLoc<ast::TraitDef>, TraitId>,
types: LocationInterner<ItemLoc<ast::TypeAliasDef>, 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 /// 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 /// can think of id as a pointer (but without a lifetime) or a file descriptor
/// (but for hir objects). /// (but for hir objects).
@ -135,11 +109,24 @@ pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<A
Some(Arc::new(rules)) Some(Arc::new(rules))
} }
macro_rules! impl_intern_key {
($name:ident) => {
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 /// `MacroCallId` identifies a particular macro invocation, like
/// `println!("Hello, {}", world)`. /// `println!("Hello, {}", world)`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroCallId(RawId); pub struct MacroCallId(salsa::InternId);
impl_arena_id!(MacroCallId); impl_intern_key!(MacroCallId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MacroCallLoc { pub struct MacroCallLoc {
@ -148,14 +135,14 @@ pub struct MacroCallLoc {
} }
impl MacroCallId { impl MacroCallId {
pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> MacroCallLoc { pub(crate) fn loc(self, db: &impl DefDatabase) -> MacroCallLoc {
db.as_ref().macros.id2loc(self) db.lookup_intern_macro(self)
} }
} }
impl MacroCallLoc { impl MacroCallLoc {
pub(crate) fn id(&self, db: &impl AsRef<HirInterner>) -> MacroCallId { pub(crate) fn id(self, db: &impl DefDatabase) -> MacroCallId {
db.as_ref().macros.loc2id(&self) db.intern_macro(self)
} }
} }
@ -204,8 +191,10 @@ impl<'a, DB: DefDatabase> LocationCtx<&'a DB> {
} }
} }
pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { pub(crate) trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; fn intern(db: &impl DefDatabase, loc: ItemLoc<N>) -> Self;
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<N>;
fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self {
let items = ctx.db.ast_id_map(ctx.file_id); let items = ctx.db.ast_id_map(ctx.file_id);
let item_id = items.ast_id(ast); let item_id = items.ast_id(ast);
@ -213,80 +202,100 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
} }
fn from_ast_id(ctx: LocationCtx<&impl 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) }; 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<N>) { fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) {
let int = Self::interner(db.as_ref()); let loc = self.lookup_intern(db);
let loc = int.id2loc(self);
let ast = loc.ast_id.to_node(db); let ast = loc.ast_id.to_node(db);
(loc.ast_id.file_id(), ast) (loc.ast_id.file_id(), ast)
} }
fn module(self, db: &impl DefDatabase) -> Module { fn module(self, db: &impl DefDatabase) -> Module {
let int = Self::interner(db.as_ref()); let loc = self.lookup_intern(db);
let loc = int.id2loc(self);
loc.module loc.module
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct FunctionId(RawId); pub struct FunctionId(salsa::InternId);
impl_arena_id!(FunctionId); impl_intern_key!(FunctionId);
impl AstItemDef<ast::FnDef> for FunctionId { impl AstItemDef<ast::FnDef> for FunctionId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::FnDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::FnDef>) -> Self {
&interner.fns db.intern_function(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::FnDef> {
db.lookup_intern_function(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct StructId(RawId); pub struct StructId(salsa::InternId);
impl_arena_id!(StructId); impl_intern_key!(StructId);
impl AstItemDef<ast::StructDef> for StructId { impl AstItemDef<ast::StructDef> for StructId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StructDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StructDef>) -> Self {
&interner.structs db.intern_struct(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StructDef> {
db.lookup_intern_struct(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct EnumId(RawId); pub struct EnumId(salsa::InternId);
impl_arena_id!(EnumId); impl_intern_key!(EnumId);
impl AstItemDef<ast::EnumDef> for EnumId { impl AstItemDef<ast::EnumDef> for EnumId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::EnumDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::EnumDef>) -> Self {
&interner.enums db.intern_enum(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::EnumDef> {
db.lookup_intern_enum(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct ConstId(RawId); pub struct ConstId(salsa::InternId);
impl_arena_id!(ConstId); impl_intern_key!(ConstId);
impl AstItemDef<ast::ConstDef> for ConstId { impl AstItemDef<ast::ConstDef> for ConstId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::ConstDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::ConstDef>) -> Self {
&interner.consts db.intern_const(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::ConstDef> {
db.lookup_intern_const(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct StaticId(RawId); pub struct StaticId(salsa::InternId);
impl_arena_id!(StaticId); impl_intern_key!(StaticId);
impl AstItemDef<ast::StaticDef> for StaticId { impl AstItemDef<ast::StaticDef> for StaticId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StaticDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::StaticDef>) -> Self {
&interner.statics db.intern_static(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::StaticDef> {
db.lookup_intern_static(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct TraitId(RawId); pub struct TraitId(salsa::InternId);
impl_arena_id!(TraitId); impl_intern_key!(TraitId);
impl AstItemDef<ast::TraitDef> for TraitId { impl AstItemDef<ast::TraitDef> for TraitId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TraitDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TraitDef>) -> Self {
&interner.traits db.intern_trait(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TraitDef> {
db.lookup_intern_trait(self)
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct TypeAliasId(RawId); pub struct TypeAliasId(salsa::InternId);
impl_arena_id!(TypeAliasId); impl_intern_key!(TypeAliasId);
impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { impl AstItemDef<ast::TypeAliasDef> for TypeAliasId {
fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TypeAliasDef>, Self> { fn intern(db: &impl DefDatabase, loc: ItemLoc<ast::TypeAliasDef>) -> Self {
&interner.types db.intern_type_alias(loc)
}
fn lookup_intern(self, db: &impl DefDatabase) -> ItemLoc<ast::TypeAliasDef> {
db.lookup_intern_type_alias(self)
} }
} }

View file

@ -55,7 +55,7 @@ pub use self::{
path::{Path, PathKind}, path::{Path, PathKind},
name::Name, name::Name,
source_id::{AstIdMap, ErasedFileAstId}, source_id::{AstIdMap, ErasedFileAstId},
ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc},
nameres::{PerNs, Namespace, ImportId, ImportSource}, nameres::{PerNs, Namespace, ImportId, ImportSource},
ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay},
impl_block::{ImplBlock, ImplItem}, impl_block::{ImplBlock, ImplItem},

View file

@ -9,7 +9,7 @@ use relative_path::RelativePathBuf;
use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::{db, HirInterner, diagnostics::DiagnosticSink}; use crate::{db, diagnostics::DiagnosticSink};
pub const WORKSPACE: SourceRootId = SourceRootId(0); pub const WORKSPACE: SourceRootId = SourceRootId(0);
@ -18,7 +18,6 @@ pub const WORKSPACE: SourceRootId = SourceRootId(0);
pub struct MockDatabase { pub struct MockDatabase {
events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>, events: Mutex<Option<Vec<salsa::Event<MockDatabase>>>>,
runtime: salsa::Runtime<MockDatabase>, runtime: salsa::Runtime<MockDatabase>,
interner: Arc<HirInterner>,
files: FxHashMap<String, FileId>, files: FxHashMap<String, FileId>,
} }
@ -195,7 +194,6 @@ impl Default for MockDatabase {
let mut db = MockDatabase { let mut db = MockDatabase {
events: Default::default(), events: Default::default(),
runtime: salsa::Runtime::default(), runtime: salsa::Runtime::default(),
interner: Default::default(),
files: FxHashMap::default(), files: FxHashMap::default(),
}; };
db.set_crate_graph(Default::default()); db.set_crate_graph(Default::default());
@ -208,19 +206,12 @@ impl salsa::ParallelDatabase for MockDatabase {
salsa::Snapshot::new(MockDatabase { salsa::Snapshot::new(MockDatabase {
events: Default::default(), events: Default::default(),
runtime: self.runtime.snapshot(self), runtime: self.runtime.snapshot(self),
interner: Arc::clone(&self.interner),
// only the root database can be used to get file_id by path. // only the root database can be used to get file_id by path.
files: FxHashMap::default(), files: FxHashMap::default(),
}) })
} }
} }
impl AsRef<HirInterner> for MockDatabase {
fn as_ref(&self) -> &HirInterner {
&self.interner
}
}
impl MockDatabase { impl MockDatabase {
pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<MockDatabase>> { pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<MockDatabase>> {
*self.events.lock() = Some(Vec::new()); *self.events.lock() = Some(Vec::new());

View file

@ -20,7 +20,6 @@ use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct RootDatabase { pub(crate) struct RootDatabase {
runtime: salsa::Runtime<RootDatabase>, runtime: salsa::Runtime<RootDatabase>,
interner: Arc<hir::HirInterner>,
pub(crate) last_gc: time::Instant, pub(crate) last_gc: time::Instant,
pub(crate) last_gc_check: time::Instant, pub(crate) last_gc_check: time::Instant,
} }
@ -38,7 +37,6 @@ impl Default for RootDatabase {
fn default() -> RootDatabase { fn default() -> RootDatabase {
let mut db = RootDatabase { let mut db = RootDatabase {
runtime: salsa::Runtime::default(), runtime: salsa::Runtime::default(),
interner: Default::default(),
last_gc: time::Instant::now(), last_gc: time::Instant::now(),
last_gc_check: time::Instant::now(), last_gc_check: time::Instant::now(),
}; };
@ -53,19 +51,12 @@ impl salsa::ParallelDatabase for RootDatabase {
fn snapshot(&self) -> salsa::Snapshot<RootDatabase> { fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
salsa::Snapshot::new(RootDatabase { salsa::Snapshot::new(RootDatabase {
runtime: self.runtime.snapshot(self), runtime: self.runtime.snapshot(self),
interner: Arc::clone(&self.interner),
last_gc: self.last_gc.clone(), last_gc: self.last_gc.clone(),
last_gc_check: self.last_gc_check.clone(), last_gc_check: self.last_gc_check.clone(),
}) })
} }
} }
impl AsRef<hir::HirInterner> for RootDatabase {
fn as_ref(&self) -> &hir::HirInterner {
&self.interner
}
}
#[salsa::query_group(LineIndexDatabaseStorage)] #[salsa::query_group(LineIndexDatabaseStorage)]
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled { pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;

View file

@ -23,16 +23,11 @@ pub(crate) fn status(db: &RootDatabase) -> String {
let files_stats = db.query(FileTextQuery).entries::<FilesStats>(); let files_stats = db.query(FileTextQuery).entries::<FilesStats>();
let syntax_tree_stats = syntax_tree_stats(db); let syntax_tree_stats = syntax_tree_stats(db);
let symbols_stats = db.query(LibrarySymbolsQuery).entries::<LibrarySymbolsStats>(); let symbols_stats = db.query(LibrarySymbolsQuery).entries::<LibrarySymbolsStats>();
let n_defs = {
let interner: &hir::HirInterner = db.as_ref();
interner.len()
};
format!( format!(
"{}\n{}\n{}\n{} defs\n\nmemory:\n{}\ngc {:?} seconds ago", "{}\n{}\n{}\n\n\nmemory:\n{}\ngc {:?} seconds ago",
files_stats, files_stats,
symbols_stats, symbols_stats,
syntax_tree_stats, syntax_tree_stats,
n_defs,
MemoryStats::current(), MemoryStats::current(),
db.last_gc.elapsed().as_secs(), db.last_gc.elapsed().as_secs(),
) )