Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/db.rs')
-rw-r--r--crates/hir-def/src/db.rs71
1 files changed, 59 insertions, 12 deletions
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index ad29900876..4e1d598623 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -1,21 +1,23 @@
//! Defines database & queries for name resolution.
use base_db::{Crate, RootQueryDb, SourceDatabase};
+use either::Either;
use hir_expand::{
EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind,
db::ExpandDatabase,
};
+use intern::sym;
use la_arena::ArenaMap;
+use syntax::{AstPtr, ast};
use triomphe::Arc;
use crate::{
- AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, CrateRootModuleId, DefWithBodyId,
- EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId,
- ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, HasModule, ImplId, ImplLoc,
- InternedModuleId, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
- MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId,
- StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc,
- VariantId,
- attrs::AttrFlags,
+ AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc,
+ EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc,
+ FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc,
+ MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId,
+ ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
+ TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
+ attr::{Attrs, AttrsWithOwner},
expr_store::{
Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes,
},
@@ -28,6 +30,7 @@ use crate::{
ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
StructSignature, TraitSignature, TypeAliasSignature, UnionSignature,
},
+ tt,
visibility::{self, Visibility},
};
@@ -235,11 +238,28 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
def: GenericDefId,
) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>);
- // FIXME: Get rid of this, call `AttrFlags::lang_item()` directly.
+ // region:attrs
+
+ #[salsa::invoke(Attrs::fields_attrs_query)]
+ fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>;
+
+ // should this really be a query?
+ #[salsa::invoke(crate::attr::fields_attrs_source_map)]
+ fn fields_attrs_source_map(
+ &self,
+ def: VariantId,
+ ) -> Arc<ArenaMap<LocalFieldId, AstPtr<Either<ast::TupleField, ast::RecordField>>>>;
+
+ // FIXME: Make this a non-interned query.
+ #[salsa::invoke_interned(AttrsWithOwner::attrs_query)]
+ fn attrs(&self, def: AttrDefId) -> Attrs;
+
#[salsa::transparent]
#[salsa::invoke(lang_item::lang_attr)]
fn lang_attr(&self, def: AttrDefId) -> Option<LangItem>;
+ // endregion:attrs
+
#[salsa::invoke(ImportMap::import_map_query)]
fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
@@ -283,9 +303,36 @@ fn include_macro_invoc(
}
fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool {
- let root_module = CrateRootModuleId::from(crate_id).module(db);
- let attrs = AttrFlags::query(db, AttrDefId::ModuleId(InternedModuleId::new(db, root_module)));
- attrs.contains(AttrFlags::IS_NO_STD)
+ let file = crate_id.data(db).root_file_id(db);
+ let item_tree = db.file_item_tree(file.into());
+ let attrs = item_tree.top_level_raw_attrs();
+ for attr in &**attrs {
+ match attr.path().as_ident() {
+ Some(ident) if *ident == sym::no_std => return true,
+ Some(ident) if *ident == sym::cfg_attr => {}
+ _ => continue,
+ }
+
+ // This is a `cfg_attr`; check if it could possibly expand to `no_std`.
+ // Syntax is: `#[cfg_attr(condition(cfg, style), attr0, attr1, <...>)]`
+ let tt = match attr.token_tree_value() {
+ Some(tt) => tt.token_trees(),
+ None => continue,
+ };
+
+ let segments =
+ tt.split(|tt| matches!(tt, tt::TtElement::Leaf(tt::Leaf::Punct(p)) if p.char == ','));
+ for output in segments.skip(1) {
+ match output.flat_tokens() {
+ [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::no_std => {
+ return true;
+ }
+ _ => {}
+ }
+ }
+ }
+
+ false
}
fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {