diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs
index 82cfca4f17101..872fcb0f581d0 100644
--- a/compiler/rustc_middle/src/hir/map/collector.rs
+++ b/compiler/rustc_middle/src/hir/map/collector.rs
@@ -529,13 +529,22 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_macro_def(&mut self, macro_def: &'hir MacroDef<'hir>) {
-        self.with_dep_node_owner(macro_def.hir_id.owner, macro_def, |this, hash| {
-            this.insert_with_hash(
-                macro_def.span,
-                macro_def.hir_id,
-                Node::MacroDef(macro_def),
-                hash,
-            );
+        // Exported macros are visited directly from the crate root,
+        // so they do not have `parent_node` set.
+        // Find the correct enclosing module from their DefKey.
+        let def_key = self.definitions.def_key(macro_def.hir_id.owner);
+        let parent = def_key.parent.map_or(hir::CRATE_HIR_ID, |local_def_index| {
+            self.definitions.local_def_id_to_hir_id(LocalDefId { local_def_index })
+        });
+        self.with_parent(parent, |this| {
+            this.with_dep_node_owner(macro_def.hir_id.owner, macro_def, |this, hash| {
+                this.insert_with_hash(
+                    macro_def.span,
+                    macro_def.hir_id,
+                    Node::MacroDef(macro_def),
+                    hash,
+                );
+            })
         });
     }
 
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 09d5b10210312..c2e99224d8b36 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -31,7 +31,7 @@ pub struct Entry<'hir> {
 impl<'hir> Entry<'hir> {
     fn parent_node(self) -> Option<HirId> {
         match self.node {
-            Node::Crate(_) | Node::MacroDef(_) => None,
+            Node::Crate(_) => None,
             _ => Some(self.parent),
         }
     }
diff --git a/src/test/rustdoc/macros.rs b/src/test/rustdoc/macros.rs
index fb4f02ad16052..ae0cf7a14789d 100644
--- a/src/test/rustdoc/macros.rs
+++ b/src/test/rustdoc/macros.rs
@@ -8,3 +8,17 @@ macro_rules! my_macro {
     ($a:tt) => ();
     ($e:expr) => {};
 }
+
+// Check that exported macro defined in a module are shown at crate root.
+// @has macros/macro.my_sub_macro.html //pre 'macro_rules! my_sub_macro {'
+// @has - //pre '() => { ... };'
+// @has - //pre '($a:tt) => { ... };'
+// @has - //pre '($e:expr) => { ... };'
+mod sub {
+    #[macro_export]
+    macro_rules! my_sub_macro {
+        () => {};
+        ($a:tt) => {};
+        ($e:expr) => {};
+    }
+}