about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-03-08 23:51:48 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-03-08 23:51:48 +0100
commitc04b0f435b4d2b29147bcfc33cdd42639e68fc00 (patch)
tree7b798b10d13d7f0481e11a04ceeff23ccb945cb5
parentad54ee293982f65a4ea72f2eae3f14b52fe2284e (diff)
downloadrust-c04b0f435b4d2b29147bcfc33cdd42639e68fc00.tar.gz
rust-c04b0f435b4d2b29147bcfc33cdd42639e68fc00.zip
Move hir to new MacroId
-rw-r--r--crates/hir/src/attrs.rs34
-rw-r--r--crates/hir/src/from_id.rs4
-rw-r--r--crates/hir/src/has_source.rs27
-rw-r--r--crates/hir/src/lib.rs158
-rw-r--r--crates/hir/src/semantics.rs73
-rw-r--r--crates/hir/src/semantics/source_to_def.rs30
-rw-r--r--crates/hir/src/source_analyzer.rs16
-rw-r--r--crates/hir/src/symbols.rs19
8 files changed, 212 insertions, 149 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 59603c61123..0bd37934001 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<Namespace>,
-    ) -> Option<Either<ModuleDef, MacroDef>>;
+    ) -> Option<ModuleDef>;
 }
 
 #[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<Namespace>) -> Option<Either<ModuleDef, MacroDef>> {
+            fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
                 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<Documentation> {
                 $enum::$variant(self).docs(db)
             }
-            fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<Either<ModuleDef, MacroDef>> {
+            fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
                 $enum::$variant(self).resolve_doc_path(db, link, ns)
             }
         }
@@ -111,7 +110,7 @@ impl HasAttrs for AssocItem {
         db: &dyn HirDatabase,
         link: &str,
         ns: Option<Namespace>,
-    ) -> Option<Either<ModuleDef, MacroDef>> {
+    ) -> Option<ModuleDef> {
         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<Namespace>,
-) -> Option<Either<ModuleDefId, MacroDefId>> {
+) -> Option<ModuleDefId> {
     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 a0b7aa3da22..5ee7556481c 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<AdtId> for Adt {
@@ -112,6 +112,7 @@ impl From<ModuleDefId> 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<ModuleDef> 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 8683e14f2ad..037f51ec8e0 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<ast::Macro, ast::Fn>;
     fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
-        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 60e3548d495..76bbe80e1f7 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<Item = Either<ModuleDef, MacroDef>> {
+    ) -> impl Iterator<Item = Either<ModuleDef, Macro>> {
         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<MacroDef> {
-        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 })
+    pub fn as_proc_macro(self, _db: &dyn HirDatabase) -> Option<Macro> {
+        // 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, _)| 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<Module> {
-        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<Name> {
-        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<Name> {
+        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<MacroDef> for ItemInNs {
-    fn from(it: MacroDef) -> Self {
+impl From<Macro> for ItemInNs {
+    fn from(it: Macro) -> Self {
         Self::Macros(it)
     }
 }
@@ -1841,7 +1860,7 @@ impl ItemInNs {
     pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
         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<AttrsWithOwner> {
         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<Crate> {
         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<ItemInNs> 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 80205f7fbc4..6d6a86fc8ab 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<Vec<Option<MacroDef>>> {
+    pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<Option<Macro>>> {
         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<MacroDef> {
+    pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
         self.imp.resolve_macro_call(macro_call)
     }
 
-    pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<MacroDef> {
+    pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
         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<Vec<Option<MacroDef>>> {
-        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<Vec<Option<Macro>>> {
+        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<Vec<SyntaxNode>> {
@@ -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<MacroDef> {
+    fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
         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<MacroDef> {
+    fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
         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<PathResolution> {
@@ -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<MacroId> {
+    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 1d8c984d116..986ea0cf2a6 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<ast::Macro>) -> Option<MacroDefId> {
-        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<ast::Macro>) -> Option<MacroId> {
+        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<ast::Fn>) -> Option<MacroId> {
+        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<ChildContainer> {
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index c6462a2c78a..1789fc319a3 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<MacroDef> {
+    ) -> Option<Macro> {
         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<HirFileId> {
         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<MacroDef> {
+) -> Option<Macro> {
     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 857c9e0ed9f..11dccbe8a6d 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<L, T>(&mut self, id: L, kind: FileSymbolKind)
+    fn push_decl<L>(&mut self, id: L, kind: FileSymbolKind)
     where
-        L: Lookup<Data = ItemLoc<T>>,
-        T: ItemTreeNode,
-        <T as ItemTreeNode>::Source: HasName,
+        L: Lookup,
+        <L as Lookup>::Data: HasSource,
+        <<L as Lookup>::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)?;