From c04b0f435b4d2b29147bcfc33cdd42639e68fc00 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 8 Mar 2022 23:51:48 +0100 Subject: [PATCH] Move hir to new MacroId --- crates/hir/src/attrs.rs | 34 +++-- crates/hir/src/from_id.rs | 4 +- crates/hir/src/has_source.rs | 27 +++- crates/hir/src/lib.rs | 156 ++++++++++++---------- crates/hir/src/semantics.rs | 73 +++++++--- crates/hir/src/semantics/source_to_def.rs | 30 ++--- crates/hir/src/source_analyzer.rs | 16 ++- crates/hir/src/symbols.rs | 19 ++- 8 files changed, 211 insertions(+), 148 deletions(-) diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 59603c6112..0bd3793400 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -1,6 +1,5 @@ //! Attributes & documentation for hir types. -use either::Either; use hir_def::{ attr::{AttrsWithOwner, Documentation}, item_scope::ItemInNs, @@ -9,13 +8,13 @@ use hir_def::{ resolver::HasResolver, AttrDefId, GenericParamId, ModuleDefId, }; -use hir_expand::{hygiene::Hygiene, MacroDefId}; +use hir_expand::hygiene::Hygiene; use hir_ty::db::HirDatabase; use syntax::{ast, AstNode}; use crate::{ Adt, AssocItem, Const, ConstParam, Enum, Field, Function, GenericParam, Impl, LifetimeParam, - MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant, + Macro, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant, }; pub trait HasAttrs { @@ -26,7 +25,7 @@ pub trait HasAttrs { db: &dyn HirDatabase, link: &str, ns: Option, - ) -> Option>; + ) -> Option; } #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] @@ -47,9 +46,9 @@ macro_rules! impl_has_attrs { let def = AttrDefId::$def_id(self.into()); db.attrs(def).docs() } - fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option) -> Option> { + fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option) -> Option { let def = AttrDefId::$def_id(self.into()); - resolve_doc_path(db, def, link, ns).map(|it| it.map_left(ModuleDef::from).map_right(MacroDef::from)) + resolve_doc_path(db, def, link, ns).map(ModuleDef::from) } } )*}; @@ -62,7 +61,7 @@ impl_has_attrs![ (Const, ConstId), (Trait, TraitId), (TypeAlias, TypeAliasId), - (MacroDef, MacroDefId), + (Macro, MacroId), (Function, FunctionId), (Adt, AdtId), (Module, ModuleId), @@ -79,7 +78,7 @@ macro_rules! impl_has_attrs_enum { fn docs(self, db: &dyn HirDatabase) -> Option { $enum::$variant(self).docs(db) } - fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option) -> Option> { + fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option) -> Option { $enum::$variant(self).resolve_doc_path(db, link, ns) } } @@ -111,7 +110,7 @@ impl HasAttrs for AssocItem { db: &dyn HirDatabase, link: &str, ns: Option, - ) -> Option> { + ) -> Option { match self { AssocItem::Function(it) => it.resolve_doc_path(db, link, ns), AssocItem::Const(it) => it.resolve_doc_path(db, link, ns), @@ -125,7 +124,7 @@ fn resolve_doc_path( def: AttrDefId, link: &str, ns: Option, -) -> Option> { +) -> Option { let resolver = match def { AttrDefId::ModuleId(it) => it.resolver(db.upcast()), AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()), @@ -138,14 +137,13 @@ fn resolve_doc_path( AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()), AttrDefId::ImplId(it) => it.resolver(db.upcast()), AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()), + AttrDefId::MacroId(it) => it.resolver(db.upcast()), AttrDefId::GenericParamId(it) => match it { GenericParamId::TypeParamId(it) => it.parent(), GenericParamId::ConstParamId(it) => it.parent(), GenericParamId::LifetimeParamId(it) => it.parent, } .resolver(db.upcast()), - // FIXME - AttrDefId::MacroDefId(_) => return None, }; let modpath = { @@ -167,13 +165,13 @@ fn resolve_doc_path( resolved }; match ns { - Some(Namespace::Types) => resolved.take_types().map(Either::Left), - Some(Namespace::Values) => resolved.take_values().map(Either::Left), - Some(Namespace::Macros) => resolved.take_macros().map(Either::Right), + Some(Namespace::Types) => resolved.take_types(), + Some(Namespace::Values) => resolved.take_values(), + Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId), None => resolved.iter_items().next().map(|it| match it { - ItemInNs::Types(it) => Either::Left(it), - ItemInNs::Values(it) => Either::Left(it), - ItemInNs::Macros(it) => Either::Right(it), + ItemInNs::Types(it) => it, + ItemInNs::Values(it) => it, + ItemInNs::Macros(it) => ModuleDefId::MacroId(it), }), } } diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index a0b7aa3da2..5ee7556481 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -45,7 +45,7 @@ from_id![ (hir_def::TypeParamId, crate::TypeParam), (hir_def::ConstParamId, crate::ConstParam), (hir_def::LifetimeParamId, crate::LifetimeParam), - (hir_expand::MacroDefId, crate::MacroDef) + (hir_def::MacroId, crate::Macro) ]; impl From for Adt { @@ -112,6 +112,7 @@ impl From for ModuleDef { ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), ModuleDefId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()), ModuleDefId::BuiltinType(it) => ModuleDef::BuiltinType(it.into()), + ModuleDefId::MacroId(it) => ModuleDef::Macro(it.into()), } } } @@ -128,6 +129,7 @@ impl From for ModuleDefId { ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()), ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it.into()), + ModuleDef::Macro(it) => ModuleDefId::MacroId(it.into()), } } } diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 8683e14f2a..037f51ec8e 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -4,13 +4,13 @@ use either::Either; use hir_def::{ nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource as _}, - Lookup, VariantId, + Lookup, MacroId, VariantId, }; use hir_expand::InFile; use syntax::ast; use crate::{ - db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef, + db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, Macro, Module, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, }; @@ -123,13 +123,26 @@ impl HasSource for TypeAlias { Some(self.id.lookup(db.upcast()).source(db.upcast())) } } -impl HasSource for MacroDef { +impl HasSource for Macro { type Ast = Either; fn source(self, db: &dyn HirDatabase) -> Option> { - Some(self.id.ast_id().either( - |id| id.with_value(Either::Left(id.to_node(db.upcast()))), - |id| id.with_value(Either::Right(id.to_node(db.upcast()))), - )) + match self.id { + MacroId::Macro2Id(it) => Some( + it.lookup(db.upcast()) + .source(db.upcast()) + .map(ast::Macro::MacroDef) + .map(Either::Left), + ), + MacroId::MacroRulesId(it) => Some( + it.lookup(db.upcast()) + .source(db.upcast()) + .map(ast::Macro::MacroRules) + .map(Either::Left), + ), + MacroId::ProcMacroId(it) => { + Some(it.lookup(db.upcast()).source(db.upcast()).map(Either::Right)) + } + } } } impl HasSource for Impl { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 60e3548d49..76bbe80e1f 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -49,10 +49,10 @@ use hir_def::{ src::HasSource as _, AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, - LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, UnionId, + LocalEnumVariantId, LocalFieldId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, + TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, }; -use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; +use hir_expand::{name::name, MacroCallKind}; use hir_ty::{ autoderef, consteval::{eval_const, ComputedExpr, ConstEvalCtx, ConstEvalError, ConstExt}, @@ -207,7 +207,7 @@ impl Crate { self, db: &dyn DefDatabase, query: import_map::Query, - ) -> impl Iterator> { + ) -> impl Iterator> { let _p = profile::span("query_external_importables"); import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| { match ItemInNs::from(item) { @@ -272,6 +272,7 @@ pub enum ModuleDef { Trait(Trait), TypeAlias(TypeAlias), BuiltinType(BuiltinType), + Macro(Macro), } impl_from!( Module, @@ -282,7 +283,8 @@ impl_from!( Static, Trait, TypeAlias, - BuiltinType + BuiltinType, + Macro for ModuleDef ); @@ -307,6 +309,7 @@ impl ModuleDef { ModuleDef::Static(it) => Some(it.module(db)), ModuleDef::Trait(it) => Some(it.module(db)), ModuleDef::TypeAlias(it) => Some(it.module(db)), + ModuleDef::Macro(it) => Some(it.module(db)), ModuleDef::BuiltinType(_) => None, } } @@ -337,6 +340,7 @@ impl ModuleDef { ModuleDef::Variant(it) => it.name(db), ModuleDef::TypeAlias(it) => it.name(db), ModuleDef::Static(it) => it.name(db), + ModuleDef::Macro(it) => it.name(db)?, ModuleDef::BuiltinType(it) => it.name(), }; Some(name) @@ -390,6 +394,7 @@ impl ModuleDef { | ModuleDef::Variant(_) | ModuleDef::Trait(_) | ModuleDef::TypeAlias(_) + | ModuleDef::Macro(_) | ModuleDef::BuiltinType(_) => None, } } @@ -404,6 +409,7 @@ impl ModuleDef { ModuleDef::Static(it) => it.attrs(db), ModuleDef::Trait(it) => it.attrs(db), ModuleDef::TypeAlias(it) => it.attrs(db), + ModuleDef::Macro(it) => it.attrs(db), ModuleDef::BuiltinType(_) => return None, }) } @@ -420,6 +426,8 @@ impl HasVisibility for ModuleDef { ModuleDef::Trait(it) => it.visibility(db), ModuleDef::TypeAlias(it) => it.visibility(db), ModuleDef::Variant(it) => it.visibility(db), + // FIXME + ModuleDef::Macro(_) => Visibility::Public, ModuleDef::BuiltinType(_) => Visibility::Public, } } @@ -1376,25 +1384,27 @@ impl Function { db.function_data(self.id).has_body() } - pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option { - let function_data = db.function_data(self.id); - let attrs = &function_data.attrs; - if !(attrs.is_proc_macro() - || attrs.is_proc_macro_attribute() - || attrs.is_proc_macro_derive()) - { - return None; - } - let loc = self.id.lookup(db.upcast()); - let krate = loc.krate(db); - let def_map = db.crate_def_map(krate.into()); - let ast_id = - InFile::new(loc.id.file_id(), loc.id.item_tree(db.upcast())[loc.id.value].ast_id); + pub fn as_proc_macro(self, _db: &dyn HirDatabase) -> Option { + // let function_data = db.function_data(self.id); + // let attrs = &function_data.attrs; + // if !(attrs.is_proc_macro() + // || attrs.is_proc_macro_attribute() + // || attrs.is_proc_macro_derive()) + // { + // return None; + // } + // let loc = self.id.lookup(db.upcast()); + // let krate = loc.krate(db); + // let def_map = db.crate_def_map(krate.into()); + // let ast_id = + // InFile::new(loc.id.file_id(), loc.id.item_tree(db.upcast())[loc.id.value].ast_id); - let mut exported_proc_macros = def_map.exported_proc_macros(); - exported_proc_macros - .find(|&(id, _)| matches!(id.kind, MacroDefKind::ProcMacro(_, _, id) if id == ast_id)) - .map(|(id, _)| MacroDef { id }) + // let mut exported_proc_macros = def_map.exported_proc_macros(); + // exported_proc_macros + // .find(|&(id, _)| matches!(id.kind, MacroDefKind::ProcMacro(_, _, id) if id == ast_id)) + // .map(|(id, _)| Macro { id }) + // FIXME + None } /// A textual representation of the HIR of this function for debugging purposes. @@ -1747,61 +1757,70 @@ pub enum MacroKind { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct MacroDef { - pub(crate) id: MacroDefId, +pub struct Macro { + pub(crate) id: MacroId, } -impl MacroDef { - /// FIXME: right now, this just returns the root module of the crate that - /// defines this macro. The reasons for this is that macros are expanded - /// early, in `hir_expand`, where modules simply do not exist yet. - pub fn module(self, db: &dyn HirDatabase) -> Option { - let krate = self.id.krate; - let def_map = db.crate_def_map(krate); - let module_id = def_map.root(); - Some(Module { id: def_map.module_id(module_id) }) +impl Macro { + pub fn module(self, db: &dyn HirDatabase) -> Module { + Module { id: self.id.module(db.upcast()) } } - /// XXX: this parses the file - pub fn name(self, db: &dyn HirDatabase) -> Option { - match self.source(db)?.value { - Either::Left(it) => it.name().map(|it| it.as_name()), - Either::Right(_) => { - let krate = self.id.krate; - let def_map = db.crate_def_map(krate); - let (_, name) = def_map.exported_proc_macros().find(|&(id, _)| id == self.id)?; - Some(name) - } + pub fn name(self, _db: &dyn HirDatabase) -> Option { + match self.id { + MacroId::Macro2Id(_id) => todo!(), + MacroId::MacroRulesId(_id) => todo!(), + MacroId::ProcMacroId(_id) => todo!(), } } - pub fn kind(&self) -> MacroKind { - match self.id.kind { - MacroDefKind::Declarative(_) => MacroKind::Declarative, - MacroDefKind::BuiltIn(_, _) | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn, - MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive, - MacroDefKind::BuiltInAttr(_, _) => MacroKind::Attr, - MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::CustomDerive, _) => { - MacroKind::Derive - } - MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::Attr, _) => MacroKind::Attr, - MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro, + pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind { + match self.id { + MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander { + hir_def::MacroExpander::Declarative => MacroKind::Declarative, + hir_def::MacroExpander::BuiltIn(_) => MacroKind::BuiltIn, + hir_def::MacroExpander::BuiltInAttr(_) => MacroKind::Attr, + hir_def::MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + hir_def::MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, + }, + MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander { + hir_def::MacroExpander::Declarative => MacroKind::Declarative, + hir_def::MacroExpander::BuiltIn(_) => MacroKind::BuiltIn, + hir_def::MacroExpander::BuiltInAttr(_) => MacroKind::Attr, + hir_def::MacroExpander::BuiltInDerive(_) => MacroKind::Derive, + hir_def::MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn, + }, + MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind { + base_db::ProcMacroKind::CustomDerive => MacroKind::Derive, + base_db::ProcMacroKind::FuncLike => MacroKind::ProcMacro, + base_db::ProcMacroKind::Attr => MacroKind::Attr, + }, } } - pub fn is_fn_like(&self) -> bool { - match self.kind() { + pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool { + match self.kind(db) { MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true, MacroKind::Attr | MacroKind::Derive => false, } } - pub fn is_builtin_derive(&self) -> bool { - matches!(self.id.kind, MacroDefKind::BuiltInAttr(exp, _) if exp.is_derive()) + pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool { + match self.id { + MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander { + hir_def::MacroExpander::BuiltInDerive(_) => true, + _ => false, + }, + MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander { + hir_def::MacroExpander::BuiltInDerive(_) => true, + _ => false, + }, + MacroId::ProcMacroId(_) => false, + } } - pub fn is_attr(&self) -> bool { - matches!(self.kind(), MacroKind::Attr) + pub fn is_attr(&self, db: &dyn HirDatabase) -> bool { + matches!(self.kind(db), MacroKind::Attr) } } @@ -1809,11 +1828,11 @@ impl MacroDef { pub enum ItemInNs { Types(ModuleDef), Values(ModuleDef), - Macros(MacroDef), + Macros(Macro), } -impl From for ItemInNs { - fn from(it: MacroDef) -> Self { +impl From for ItemInNs { + fn from(it: Macro) -> Self { Self::Macros(it) } } @@ -1841,7 +1860,7 @@ impl ItemInNs { pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()), - ItemInNs::Macros(id) => id.module(db).map(|m| m.krate()), + ItemInNs::Macros(id) => Some(id.module(db).krate()), } } @@ -3224,7 +3243,6 @@ impl Callable { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ScopeDef { ModuleDef(ModuleDef), - MacroDef(MacroDef), GenericParam(GenericParam), ImplSelfType(Impl), AdtSelfType(Adt), @@ -3255,7 +3273,7 @@ impl ScopeDef { }; if let Some(macro_def_id) = def.take_macros() { - items.push(ScopeDef::MacroDef(macro_def_id.into())); + items.push(ScopeDef::ModuleDef(ModuleDef::Macro(macro_def_id.into()))); } if items.is_empty() { @@ -3268,7 +3286,6 @@ impl ScopeDef { pub fn attrs(&self, db: &dyn HirDatabase) -> Option { match self { ScopeDef::ModuleDef(it) => it.attrs(db), - ScopeDef::MacroDef(it) => Some(it.attrs(db)), ScopeDef::GenericParam(it) => Some(it.attrs(db)), ScopeDef::ImplSelfType(_) | ScopeDef::AdtSelfType(_) @@ -3281,7 +3298,6 @@ impl ScopeDef { pub fn krate(&self, db: &dyn HirDatabase) -> Option { match self { ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()), - ScopeDef::MacroDef(it) => it.module(db).map(|m| m.krate()), ScopeDef::GenericParam(it) => Some(it.module(db).krate()), ScopeDef::ImplSelfType(_) => None, ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()), @@ -3297,7 +3313,7 @@ impl From for ScopeDef { match item { ItemInNs::Types(id) => ScopeDef::ModuleDef(id), ItemInNs::Values(id) => ScopeDef::ModuleDef(id), - ItemInNs::Macros(id) => ScopeDef::MacroDef(id), + ItemInNs::Macros(id) => ScopeDef::ModuleDef(ModuleDef::Macro(id)), } } } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 80205f7fbc..6d6a86fc8a 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -6,11 +6,12 @@ use std::{cell::RefCell, fmt, iter}; use base_db::{FileId, FileRange}; use hir_def::{ - body, + body, macro_id_to_def_id, resolver::{self, HasResolver, Resolver, TypeNs}, - AsMacroCall, FunctionId, TraitId, VariantId, + AsMacroCall, FunctionId, MacroId, TraitId, VariantId, }; use hir_expand::{ + db::AstDatabase, name::{known, AsName}, ExpansionInfo, MacroCallId, }; @@ -29,7 +30,7 @@ use crate::{ semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{resolve_hir_path, SourceAnalyzer}, Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource, - HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, + HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path, ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef, }; @@ -44,7 +45,6 @@ pub enum PathResolution { /// A const parameter ConstParam(ConstParam), SelfType(Impl), - Macro(MacroDef), AssocItem(AssocItem), BuiltinAttr(BuiltinAttr), ToolModule(ToolModule), @@ -60,6 +60,7 @@ impl PathResolution { PathResolution::Def( ModuleDef::Const(_) | ModuleDef::Variant(_) + | ModuleDef::Macro(_) | ModuleDef::Function(_) | ModuleDef::Module(_) | ModuleDef::Static(_) @@ -71,7 +72,6 @@ impl PathResolution { PathResolution::BuiltinAttr(_) | PathResolution::ToolModule(_) | PathResolution::Local(_) - | PathResolution::Macro(_) | PathResolution::ConstParam(_) => None, PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())), PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())), @@ -151,7 +151,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.expand_attr_macro(item) } - pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option>> { + pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option>> { self.imp.resolve_derive_macro(derive) } @@ -331,11 +331,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.resolve_record_pat_field(field) } - pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { + pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { self.imp.resolve_macro_call(macro_call) } - pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option { + pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option { self.imp.resolve_attr_macro_call(item) } @@ -443,13 +443,18 @@ impl<'db> SemanticsImpl<'db> { Some(node) } - fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option>> { - let res = self - .derive_macro_calls(attr)? - .into_iter() - .map(|call| Some(MacroDef { id: self.db.lookup_intern_macro_call(call?).def })) - .collect(); - Some(res) + fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option>> { + let calls = self.derive_macro_calls(attr)?; + self.with_ctx(|ctx| { + Some( + calls + .into_iter() + .map(|call| { + macro_call_to_macro_id(ctx, self.db.upcast(), call?).map(|id| Macro { id }) + }) + .collect(), + ) + }) } fn expand_derive_macro(&self, attr: &ast::Attr) -> Option> { @@ -500,7 +505,9 @@ impl<'db> SemanticsImpl<'db> { let macro_call = InFile::new(file_id, actual_macro_call); let krate = resolver.krate()?; let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { - resolver.resolve_path_as_macro(self.db.upcast(), &path) + resolver + .resolve_path_as_macro(self.db.upcast(), &path) + .map(|it| macro_id_to_def_id(self.db.upcast(), it)) })?; hir_expand::db::expand_speculative( self.db.upcast(), @@ -895,16 +902,19 @@ impl<'db> SemanticsImpl<'db> { self.analyze(field.syntax()).resolve_record_pat_field(self.db, field) } - fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { + fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { let sa = self.analyze(macro_call.syntax()); let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call); sa.resolve_macro_call(self.db, macro_call) } - fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option { + fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option { let item_in_file = self.wrap_node_infile(item.clone()); - let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(item_in_file))?; - Some(MacroDef { id: self.db.lookup_intern_macro_call(macro_call_id).def }) + let id = self.with_ctx(|ctx| { + let macro_call_id = ctx.item_to_macro_call(item_in_file)?; + macro_call_to_macro_id(ctx, self.db.upcast(), macro_call_id) + })?; + Some(Macro { id }) } fn resolve_path(&self, path: &ast::Path) -> Option { @@ -1152,6 +1162,26 @@ impl<'db> SemanticsImpl<'db> { } } +fn macro_call_to_macro_id( + ctx: &mut SourceToDefCtx, + db: &dyn AstDatabase, + macro_call_id: MacroCallId, +) -> Option { + let loc = db.lookup_intern_macro_call(macro_call_id); + match loc.def.kind { + hir_expand::MacroDefKind::Declarative(it) + | hir_expand::MacroDefKind::BuiltIn(_, it) + | hir_expand::MacroDefKind::BuiltInAttr(_, it) + | hir_expand::MacroDefKind::BuiltInDerive(_, it) + | hir_expand::MacroDefKind::BuiltInEager(_, it) => { + ctx.macro_to_def(InFile::new(it.file_id, it.to_node(db))) + } + hir_expand::MacroDefKind::ProcMacro(_, _, it) => { + ctx.proc_macro_to_def(InFile::new(it.file_id, it.to_node(db))) + } + } +} + pub trait ToDef: AstNode + Clone { type Def; @@ -1188,7 +1218,7 @@ to_def_impls![ (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), (crate::ConstParam, ast::ConstParam, const_param_to_def), (crate::GenericParam, ast::GenericParam, generic_param_to_def), - (crate::MacroDef, ast::Macro, macro_to_def), + (crate::Macro, ast::Macro, macro_to_def), (crate::Local, ast::IdentPat, bind_pat_to_def), (crate::Local, ast::SelfParam, self_param_to_def), (crate::Label, ast::Label, label_to_def), @@ -1250,7 +1280,6 @@ impl<'a> SemanticsScope<'a> { for entry in entries { let def = match entry { resolver::ScopeDef::ModuleDef(it) => ScopeDef::ModuleDef(it.into()), - resolver::ScopeDef::MacroDef(it) => ScopeDef::MacroDef(it.into()), resolver::ScopeDef::Unknown => ScopeDef::Unknown, resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 1d8c984d11..986ea0cf2a 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -93,10 +93,10 @@ use hir_def::{ expr::{LabelId, PatId}, keys::{self, Key}, AdtId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, - GenericDefId, GenericParamId, ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId, - TypeAliasId, TypeParamId, UnionId, VariantId, + GenericDefId, GenericParamId, ImplId, LifetimeParamId, MacroId, ModuleId, StaticId, StructId, + TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, }; -use hir_expand::{name::AsName, AstId, HirFileId, MacroCallId, MacroDefId, MacroDefKind}; +use hir_expand::{name::AsName, HirFileId, MacroCallId}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use stdx::impl_from; @@ -317,20 +317,18 @@ impl SourceToDefCtx<'_, '_> { } } - pub(super) fn macro_to_def(&mut self, src: InFile) -> Option { - let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src.value)); - if let Some(&makro) = makro { - return Some(makro); - } + pub(super) fn macro_to_def(&mut self, src: InFile) -> Option { + self.dyn_map(src.as_ref()).and_then(|it| match &src.value { + ast::Macro::MacroRules(value) => { + it[keys::MACRO_RULES].get(value).copied().map(MacroId::from) + } + ast::Macro::MacroDef(value) => it[keys::MACRO2].get(value).copied().map(MacroId::from), + }) + } - // Not all macros are recorded in the dyn map, only the ones behaving like items, so fall back - // for the non-item like definitions. - let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); - let ast_id = AstId::new(src.file_id, file_ast_id.upcast()); - let kind = MacroDefKind::Declarative(ast_id); - let file_id = src.file_id.original_file(self.db.upcast()); - let krate = self.file_to_def(file_id).get(0).copied()?.krate(); - Some(MacroDefId { krate, kind, local_inner: false }) + pub(super) fn proc_macro_to_def(&mut self, src: InFile) -> Option { + self.dyn_map(src.as_ref()) + .and_then(|it| it[keys::PROC_MACRO].get(&src.value).copied().map(MacroId::from)) } pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option { diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index c6462a2c78..1789fc319a 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -17,6 +17,7 @@ use hir_def::{ Body, BodySourceMap, }, expr::{ExprId, Pat, PatId}, + macro_id_to_def_id, path::{ModPath, Path, PathKind}, resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, AsMacroCall, DefWithBodyId, FieldId, FunctionId, LocalFieldId, ModuleDefId, VariantId, @@ -33,8 +34,7 @@ use syntax::{ use crate::{ db::HirDatabase, semantics::PathResolution, Adt, BuiltinAttr, BuiltinType, Const, Field, - Function, Local, MacroDef, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias, - Variant, + Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias, Variant, }; use base_db::CrateId; @@ -248,7 +248,7 @@ impl SourceAnalyzer { &self, db: &dyn HirDatabase, macro_call: InFile<&ast::MacroCall>, - ) -> Option { + ) -> Option { let ctx = body::LowerCtx::new(db.upcast(), macro_call.file_id); let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?; self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(|it| it.into()) @@ -371,7 +371,7 @@ impl SourceAnalyzer { return builtin.map(PathResolution::BuiltinAttr); } return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) { - Some(m) => Some(PathResolution::Macro(m)), + Some(m) => Some(PathResolution::Def(ModuleDef::Macro(m))), // this labels any path that starts with a tool module as the tool itself, this is technically wrong // but there is no benefit in differentiating these two cases for the time being None => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| { @@ -453,7 +453,9 @@ impl SourceAnalyzer { ) -> Option { let krate = self.resolver.krate()?; let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| { - self.resolver.resolve_path_as_macro(db.upcast(), &path) + self.resolver + .resolve_path_as_macro(db.upcast(), &path) + .map(|it| macro_id_to_def_id(db.upcast(), it)) })?; Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64) } @@ -571,7 +573,7 @@ pub(crate) fn resolve_hir_path_as_macro( db: &dyn HirDatabase, resolver: &Resolver, path: &Path, -) -> Option { +) -> Option { resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(Into::into) } @@ -666,7 +668,7 @@ fn resolve_hir_path_( let macros = || { resolver .resolve_path_as_macro(db.upcast(), path.mod_path()) - .map(|def| PathResolution::Macro(def.into())) + .map(|def| PathResolution::Def(ModuleDef::Macro(def.into()))) }; if prefer_value_ns { values().or_else(types) } else { types().or_else(values) } diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index 857c9e0ed9..11dccbe8a6 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -4,13 +4,13 @@ use base_db::FileRange; use either::Either; use hir_def::{ item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId, - ImplId, ItemContainerId, ItemLoc, Lookup, ModuleDefId, ModuleId, TraitId, + ImplId, ItemContainerId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, }; use hir_expand::{HirFileId, InFile}; use hir_ty::db::HirDatabase; use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr}; -use crate::{HasSource as _, MacroDef, Module, Semantics}; +use crate::{HasSource as _, Macro, Module, Semantics}; /// The actual data that is stored in the index. It should be as compact as /// possible. @@ -157,6 +157,11 @@ impl<'a> SymbolCollector<'a> { ModuleDefId::TypeAliasId(id) => { self.push_decl_assoc(id, FileSymbolKind::TypeAlias); } + ModuleDefId::MacroId(id) => match id { + MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro), + MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro), + }, // Don't index these. ModuleDefId::BuiltinType(_) => {} ModuleDefId::EnumVariantId(_) => {} @@ -283,11 +288,11 @@ impl<'a> SymbolCollector<'a> { }) } - fn push_decl(&mut self, id: L, kind: FileSymbolKind) + fn push_decl(&mut self, id: L, kind: FileSymbolKind) where - L: Lookup>, - T: ItemTreeNode, - ::Source: HasName, + L: Lookup, + ::Data: HasSource, + <::Data as HasSource>::Value: HasName, { self.push_file_symbol(|s| { let loc = id.lookup(s.db.upcast()); @@ -328,7 +333,7 @@ impl<'a> SymbolCollector<'a> { }) } - fn push_decl_macro(&mut self, macro_def: MacroDef) { + fn push_decl_macro(&mut self, macro_def: Macro) { self.push_file_symbol(|s| { let name = macro_def.name(s.db)?.as_text()?; let source = macro_def.source(s.db)?;