8080: Change ItemTree API to accomodate creating an ItemTree per block expression r=jonas-schievink a=jonas-schievink

...which won't go through salsa because the AST is already cached anyways

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2021-03-18 00:57:48 +00:00 committed by GitHub
commit d704750ba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 92 additions and 52 deletions

View File

@ -3,10 +3,10 @@
pub use hir_def::db::{
AttrsQuery, BlockDefMapQuery, BodyQuery, BodyWithSourceMapQuery, ConstDataQuery,
CrateDefMapQueryQuery, CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, EnumDataQuery,
ExprScopesQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery, ImportMapQuery,
InternConstQuery, InternDatabase, InternDatabaseStorage, InternEnumQuery, InternFunctionQuery,
InternImplQuery, InternStaticQuery, InternStructQuery, InternTraitQuery, InternTypeAliasQuery,
InternUnionQuery, ItemTreeQuery, LangItemQuery, StaticDataQuery, StructDataQuery,
ExprScopesQuery, FileItemTreeQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery,
ImportMapQuery, InternConstQuery, InternDatabase, InternDatabaseStorage, InternEnumQuery,
InternFunctionQuery, InternImplQuery, InternStaticQuery, InternStructQuery, InternTraitQuery,
InternTypeAliasQuery, InternUnionQuery, LangItemQuery, StaticDataQuery, StructDataQuery,
TraitDataQuery, TypeAliasDataQuery, UnionDataQuery,
};
pub use hir_expand::db::{

View File

@ -574,7 +574,7 @@ impl<'db> SemanticsImpl<'db> {
}
fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
let file_id = self.db.lookup_intern_trait(def.id).id.file_id;
let file_id = self.db.lookup_intern_trait(def.id).id.file_id();
let resolver = def.id.resolver(self.db.upcast());
SemanticsScope { db: self.db, file_id, resolver }
}

View File

@ -94,7 +94,7 @@ impl StructData {
pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
let loc = id.lookup(db);
let krate = loc.container.krate;
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
@ -110,7 +110,7 @@ impl StructData {
pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
let loc = id.lookup(db);
let krate = loc.container.krate;
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
@ -130,7 +130,7 @@ impl EnumData {
pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
let loc = e.lookup(db);
let krate = loc.container.krate;
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
let enum_ = &item_tree[loc.id.value];

View File

@ -530,7 +530,7 @@ where
}
fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let mod_item = N::id_to_mod_item(id.value);
tree.raw_attrs(mod_item.into()).clone()
}

View File

@ -38,7 +38,7 @@ impl FunctionData {
let krate = loc.container.module(db).krate;
let crate_graph = db.crate_graph();
let cfg_options = &crate_graph[krate].cfg_options;
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let func = &item_tree[loc.id.value];
let enabled_params = func
@ -89,7 +89,7 @@ impl TypeAliasData {
typ: TypeAliasId,
) -> Arc<TypeAliasData> {
let loc = typ.lookup(db);
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let typ = &item_tree[loc.id.value];
Arc::new(TypeAliasData {
@ -115,23 +115,23 @@ pub struct TraitData {
impl TraitData {
pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> {
let tr_loc = tr.lookup(db);
let item_tree = db.item_tree(tr_loc.id.file_id);
let item_tree = tr_loc.id.item_tree(db);
let tr_def = &item_tree[tr_loc.id.value];
let name = tr_def.name.clone();
let is_auto = tr_def.is_auto;
let is_unsafe = tr_def.is_unsafe;
let module_id = tr_loc.container;
let container = AssocContainerId::TraitId(tr);
let mut expander = Expander::new(db, tr_loc.id.file_id, module_id);
let visibility = item_tree[tr_def.visibility].clone();
let bounds = tr_def.bounds.clone();
let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id);
let items = collect_items(
db,
module_id,
&mut expander,
tr_def.items.iter().copied(),
tr_loc.id.file_id,
tr_loc.id.file_id(),
container,
100,
);
@ -167,21 +167,21 @@ impl ImplData {
let _p = profile::span("impl_data_query");
let impl_loc = id.lookup(db);
let item_tree = db.item_tree(impl_loc.id.file_id);
let item_tree = impl_loc.id.item_tree(db);
let impl_def = &item_tree[impl_loc.id.value];
let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone());
let target_type = item_tree[impl_def.target_type].clone();
let is_negative = impl_def.is_negative;
let module_id = impl_loc.container;
let container = AssocContainerId::ImplId(id);
let mut expander = Expander::new(db, impl_loc.id.file_id, module_id);
let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
let items = collect_items(
db,
module_id,
&mut expander,
impl_def.items.iter().copied(),
impl_loc.id.file_id,
impl_loc.id.file_id(),
container,
100,
);
@ -202,7 +202,7 @@ pub struct ConstData {
impl ConstData {
pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> {
let loc = konst.lookup(db);
let item_tree = db.item_tree(loc.id.file_id);
let item_tree = loc.id.item_tree(db);
let konst = &item_tree[loc.id.value];
Arc::new(ConstData {
@ -225,7 +225,7 @@ pub struct StaticData {
impl StaticData {
pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> {
let node = konst.lookup(db);
let item_tree = db.item_tree(node.id.file_id);
let item_tree = node.id.item_tree(db);
let statik = &item_tree[node.id.value];
Arc::new(StaticData {
@ -251,7 +251,7 @@ fn collect_items(
return Vec::new();
}
let item_tree = db.item_tree(file_id);
let item_tree = db.file_item_tree(file_id);
let crate_graph = db.crate_graph();
let cfg_options = &crate_graph[module.krate].cfg_options;
@ -292,7 +292,7 @@ fn collect_items(
if let Ok(res) = res {
if let Some((mark, mac)) = res.value {
let src: InFile<ast::MacroItems> = expander.to_source(mac);
let item_tree = db.item_tree(src.file_id);
let item_tree = db.file_item_tree(src.file_id);
let iter =
item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
items.extend(collect_items(

View File

@ -48,8 +48,8 @@ pub trait InternDatabase: SourceDatabase {
#[salsa::query_group(DefDatabaseStorage)]
pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
#[salsa::invoke(ItemTree::item_tree_query)]
fn item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
#[salsa::invoke(ItemTree::file_item_tree_query)]
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
#[salsa::invoke(crate_def_map_wait)]
#[salsa::transparent]

View File

@ -97,43 +97,43 @@ impl GenericParams {
let generics = match def {
GenericDefId::FunctionId(id) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::AdtId(AdtId::StructId(id)) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::AdtId(AdtId::EnumId(id)) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::AdtId(AdtId::UnionId(id)) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::TraitId(id) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::TypeAliasId(id) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}
GenericDefId::ImplId(id) => {
let id = id.lookup(db).id;
let tree = db.item_tree(id.file_id);
let tree = id.item_tree(db);
let item = &tree[id.value];
tree[item.generic_params].clone()
}

View File

@ -76,7 +76,7 @@ pub struct ItemTree {
}
impl ItemTree {
pub(crate) fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id));
let syntax = if let Some(node) = db.parse_or_expand(file_id) {
if node.kind() == SyntaxKind::ERROR {
@ -401,7 +401,47 @@ impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
}
}
pub type ItemTreeId<N> = InFile<FileItemTreeId<N>>;
#[derive(Debug)]
pub struct ItemTreeId<N: ItemTreeNode> {
file: HirFileId,
pub value: FileItemTreeId<N>,
}
impl<N: ItemTreeNode> ItemTreeId<N> {
pub fn new(file: HirFileId, idx: FileItemTreeId<N>) -> Self {
Self { file, value: idx }
}
pub fn file_id(self) -> HirFileId {
self.file
}
pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
db.file_item_tree(self.file)
}
}
impl<N: ItemTreeNode> Copy for ItemTreeId<N> {}
impl<N: ItemTreeNode> Clone for ItemTreeId<N> {
fn clone(&self) -> Self {
*self
}
}
impl<N: ItemTreeNode> PartialEq for ItemTreeId<N> {
fn eq(&self, other: &Self) -> bool {
self.file == other.file && self.value == other.value
}
}
impl<N: ItemTreeNode> Eq for ItemTreeId<N> {}
impl<N: ItemTreeNode> Hash for ItemTreeId<N> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.file.hash(state);
self.value.hash(state);
}
}
macro_rules! mod_items {
( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {

View File

@ -213,7 +213,7 @@ impl DefMap {
) -> Option<Arc<DefMap>> {
let block: BlockLoc = db.lookup_intern_block(block_id);
let item_tree = db.item_tree(block.ast_id.file_id);
let item_tree = db.file_item_tree(block.ast_id.file_id);
if item_tree.inner_items_of_block(block.ast_id.value).is_empty() {
return None;
}

View File

@ -242,7 +242,7 @@ struct DefCollector<'a> {
impl DefCollector<'_> {
fn seed_with_top_level(&mut self) {
let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
let item_tree = self.db.item_tree(file_id.into());
let item_tree = self.db.file_item_tree(file_id.into());
let module_id = self.def_map.root;
self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
if item_tree
@ -263,7 +263,7 @@ impl DefCollector<'_> {
}
fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) {
let item_tree = self.db.item_tree(block.file_id);
let item_tree = self.db.file_item_tree(block.file_id);
let module_id = self.def_map.root;
self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block };
if item_tree
@ -895,7 +895,7 @@ impl DefCollector<'_> {
}
// Then, fetch and process the item tree. This will reuse the expansion result from above.
let item_tree = self.db.item_tree(file_id);
let item_tree = self.db.file_item_tree(file_id);
let mod_dir = self.mod_dirs[&module_id].clone();
ModCollector {
def_collector: &mut *self,
@ -951,21 +951,21 @@ impl DefCollector<'_> {
let mut diagnosed_extern_crates = FxHashSet::default();
for directive in &self.unresolved_imports {
if let ImportSource::ExternCrate(krate) = directive.import.source {
let item_tree = self.db.item_tree(krate.file_id);
let item_tree = krate.item_tree(self.db);
let extern_crate = &item_tree[krate.value];
diagnosed_extern_crates.insert(extern_crate.name.clone());
self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
directive.module_id,
InFile::new(krate.file_id, extern_crate.ast_id),
InFile::new(krate.file_id(), extern_crate.ast_id),
));
}
}
for directive in &self.unresolved_imports {
if let ImportSource::Import(import) = &directive.import.source {
let item_tree = self.db.item_tree(import.file_id);
let item_tree = import.item_tree(self.db);
let import_data = &item_tree[import.value];
match (import_data.path.segments().first(), &import_data.path.kind) {
@ -979,7 +979,7 @@ impl DefCollector<'_> {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
directive.module_id,
InFile::new(import.file_id, import_data.ast_id),
InFile::new(import.file_id(), import_data.ast_id),
import_data.index,
));
}
@ -1055,7 +1055,7 @@ impl ModCollector<'_, '_> {
self.def_collector.db,
krate,
&self.item_tree,
InFile::new(self.file_id, import_id),
ItemTreeId::new(self.file_id, import_id),
),
status: PartialResolvedImport::Unresolved,
})
@ -1067,7 +1067,7 @@ impl ModCollector<'_, '_> {
self.def_collector.db,
krate,
&self.item_tree,
InFile::new(self.file_id, import_id),
ItemTreeId::new(self.file_id, import_id),
),
status: PartialResolvedImport::Unresolved,
})
@ -1299,7 +1299,7 @@ impl ModCollector<'_, '_> {
Some((file_id, is_mod_rs)),
&self.item_tree[module.visibility],
);
let item_tree = db.item_tree(file_id.into());
let item_tree = db.file_item_tree(file_id.into());
ModCollector {
def_collector: &mut *self.def_collector,
macro_depth: self.macro_depth,

View File

@ -14,12 +14,12 @@ impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
type Value = N::Source;
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
let tree = db.item_tree(self.id.file_id);
let ast_id_map = db.ast_id_map(self.id.file_id);
let root = db.parse_or_expand(self.id.file_id).unwrap();
let tree = self.id.item_tree(db);
let ast_id_map = db.ast_id_map(self.id.file_id());
let root = db.parse_or_expand(self.id.file_id()).unwrap();
let node = &tree[self.id.value];
InFile::new(self.id.file_id, ast_id_map.get(node.ast_id()).to_node(&root))
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
}
}
@ -27,12 +27,12 @@ impl<N: ItemTreeNode> HasSource for ItemLoc<N> {
type Value = N::Source;
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
let tree = db.item_tree(self.id.file_id);
let ast_id_map = db.ast_id_map(self.id.file_id);
let root = db.parse_or_expand(self.id.file_id).unwrap();
let tree = self.id.item_tree(db);
let ast_id_map = db.ast_id_map(self.id.file_id());
let root = db.parse_or_expand(self.id.file_id()).unwrap();
let node = &tree[self.id.value];
InFile::new(self.id.file_id, ast_id_map.get(node.ast_id()).to_node(&root))
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
}
}

View File

@ -148,7 +148,7 @@ impl RootDatabase {
hir::db::HygieneFrameQuery
// DefDatabase
hir::db::ItemTreeQuery
hir::db::FileItemTreeQuery
hir::db::BlockDefMapQuery
hir::db::CrateDefMapQueryQuery
hir::db::StructDataQuery