//! Defines database & queries for name resolution.
use std::sync::Arc;
-use arena::map::ArenaMap;
use base_db::{salsa, CrateId, SourceDatabase, Upcast};
+use either::Either;
use hir_expand::{db::AstDatabase, HirFileId};
-use syntax::SmolStr;
+use la_arena::ArenaMap;
+use syntax::{ast, AstPtr, SmolStr};
use crate::{
adt::{EnumData, StructData},
- attr::Attrs,
+ attr::{Attrs, AttrsWithOwner},
body::{scope::ExprScopes, Body, BodySourceMap},
data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
generics::GenericParams,
import_map::ImportMap,
+ intern::Interned,
item_tree::ItemTree,
lang_item::{LangItemTarget, LangItems},
- nameres::CrateDefMap,
- AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
- GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, StaticLoc, StructId,
- StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
+ nameres::DefMap,
+ visibility::{self, Visibility},
+ AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
+ ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
+ LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
+ TypeAliasLoc, UnionId, UnionLoc, VariantId,
};
#[salsa::query_group(InternDatabaseStorage)]
fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId;
#[salsa::interned]
fn intern_impl(&self, loc: ImplLoc) -> ImplId;
+ #[salsa::interned]
+ fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId;
+ #[salsa::interned]
+ fn intern_block(&self, loc: BlockLoc) -> BlockId;
}
#[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::input]
+ fn enable_proc_attr_macros(&self) -> bool;
+
+ #[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]
- fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
-
- #[salsa::invoke(CrateDefMap::crate_def_map_query)]
- fn crate_def_map_query(&self, krate: CrateId) -> Arc<CrateDefMap>;
+ fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
+
+ #[salsa::invoke(DefMap::crate_def_map_query)]
+ fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>;
+
+ /// Computes the block-level `DefMap`, returning `None` when `block` doesn't contain any inner
+ /// items directly.
+ ///
+ /// For example:
+ ///
+ /// ```
+ /// fn f() { // (0)
+ /// { // (1)
+ /// fn inner() {}
+ /// }
+ /// }
+ /// ```
+ ///
+ /// The `block_def_map` for block 0 would return `None`, while `block_def_map` of block 1 would
+ /// return a `DefMap` containing `inner`.
+ #[salsa::invoke(DefMap::block_def_map_query)]
+ fn block_def_map(&self, block: BlockId) -> Option<Arc<DefMap>>;
#[salsa::invoke(StructData::struct_data_query)]
fn struct_data(&self, id: StructId) -> Arc<StructData>;
fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>;
#[salsa::invoke(GenericParams::generic_params_query)]
- fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
+ fn generic_params(&self, def: GenericDefId) -> Interned<GenericParams>;
#[salsa::invoke(Attrs::variants_attrs_query)]
fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>;
#[salsa::invoke(Attrs::fields_attrs_query)]
fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>;
- #[salsa::invoke(Attrs::attrs_query)]
- fn attrs(&self, def: AttrDefId) -> Attrs;
+ #[salsa::invoke(crate::attr::variants_attrs_source_map)]
+ fn variants_attrs_source_map(
+ &self,
+ def: EnumId,
+ ) -> Arc<ArenaMap<LocalEnumVariantId, AstPtr<ast::Variant>>>;
+
+ #[salsa::invoke(crate::attr::fields_attrs_source_map)]
+ fn fields_attrs_source_map(
+ &self,
+ def: VariantId,
+ ) -> Arc<ArenaMap<LocalFieldId, Either<AstPtr<ast::TupleField>, AstPtr<ast::RecordField>>>>;
+
+ #[salsa::invoke(AttrsWithOwner::attrs_query)]
+ fn attrs(&self, def: AttrDefId) -> AttrsWithOwner;
#[salsa::invoke(LangItems::crate_lang_items_query)]
fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
#[salsa::invoke(ImportMap::import_map_query)]
fn import_map(&self, krate: CrateId) -> Arc<ImportMap>;
+
+ #[salsa::invoke(visibility::field_visibilities_query)]
+ fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>;
+
+ #[salsa::invoke(visibility::function_visibility_query)]
+ fn function_visibility(&self, def: FunctionId) -> Visibility;
+
+ #[salsa::transparent]
+ fn crate_limits(&self, crate_id: CrateId) -> CrateLimits;
}
-fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
+fn crate_def_map_wait(db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
let _p = profile::span("crate_def_map:wait");
db.crate_def_map_query(krate)
}
+
+pub struct CrateLimits {
+ /// The maximum depth for potentially infinitely-recursive compile-time operations like macro expansion or auto-dereference.
+ pub recursion_limit: u32,
+}
+
+fn crate_limits(db: &dyn DefDatabase, crate_id: CrateId) -> CrateLimits {
+ let def_map = db.crate_def_map(crate_id);
+
+ CrateLimits {
+ // 128 is the default in rustc.
+ recursion_limit: def_map.recursion_limit().unwrap_or(128),
+ }
+}