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.rs | 71 |
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 { |