diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d353bc19f7aef..24245e93190fa 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -216,9 +216,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind { + let hir_id = self.lower_node_id(i.id); + let body = P(self.lower_mac_args(body)); if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) { - let hir_id = self.lower_node_id(i.id); - let body = P(self.lower_mac_args(body)); self.exported_macros.push(hir::MacroDef { ident, vis, @@ -228,6 +228,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ast: MacroDef { body, macro_rules }, }); } else { + self.non_exported_macros.push(hir::MacroDef { + ident, + vis, + attrs, + hir_id, + span: i.span, + ast: MacroDef { body, macro_rules }, + }); self.non_exported_macro_attrs.extend(attrs.iter().cloned()); } return None; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d93655e59050d..46ab483c8117f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -103,6 +103,7 @@ struct LoweringContext<'a, 'hir: 'a> { impl_items: BTreeMap>, bodies: BTreeMap>, exported_macros: Vec>, + non_exported_macros: Vec>, non_exported_macro_attrs: Vec, trait_impls: BTreeMap>, @@ -302,6 +303,7 @@ pub fn lower_crate<'a, 'hir>( trait_impls: BTreeMap::new(), modules: BTreeMap::new(), exported_macros: Vec::new(), + non_exported_macros: Vec::new(), non_exported_macro_attrs: Vec::new(), catch_scopes: Vec::new(), loop_scopes: Vec::new(), @@ -582,6 +584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::Crate { item: hir::CrateItem { module, attrs, span: c.span }, exported_macros: self.arena.alloc_from_iter(self.exported_macros), + non_exported_macros: self.arena.alloc_from_iter(self.non_exported_macros), non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), items: self.items, trait_items: self.trait_items, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4497c8c0eaaa8..5b7b0ecab9e14 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -599,6 +599,7 @@ pub struct CrateItem<'hir> { pub struct Crate<'hir> { pub item: CrateItem<'hir>, pub exported_macros: &'hir [MacroDef<'hir>], + pub non_exported_macros: &'hir [MacroDef<'hir>], // Attributes from non-exported macros, kept only for collecting the library feature list. pub non_exported_macro_attrs: &'hir [Attribute], diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 35615af0fc7df..367fe884b9422 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -463,6 +463,7 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) { visitor.visit_mod(&krate.item.module, krate.item.span, CRATE_HIR_ID); walk_list!(visitor, visit_attribute, krate.item.attrs); walk_list!(visitor, visit_macro_def, krate.exported_macros); + walk_list!(visitor, visit_macro_def, krate.non_exported_macros); } pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef<'v>) { diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs index 516c9b6752b97..bf7d0e1603667 100644 --- a/compiler/rustc_middle/src/hir/map/collector.rs +++ b/compiler/rustc_middle/src/hir/map/collector.rs @@ -108,6 +108,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { ref item, // These fields are handled separately: exported_macros: _, + non_exported_macros: _, non_exported_macro_attrs: _, items: _, trait_items: _, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e57717dab76cf..c2892f8bff7f9 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -74,6 +74,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { module .macros .extend(krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None))); + if self.cx.render_options.document_private { + // If `--document-private-items` is passed, also attach the crate's + // *non*-exported macros to the top-level module. + module + .macros + .extend(krate.non_exported_macros.iter().map(|def| self.visit_local_macro(def, None))); + } module.is_crate = true; self.cx.renderinfo.get_mut().exact_paths = self.exact_paths; diff --git a/src/test/rustdoc/non-exported-macros.rs b/src/test/rustdoc/non-exported-macros.rs new file mode 100644 index 0000000000000..df4d08ab337b4 --- /dev/null +++ b/src/test/rustdoc/non-exported-macros.rs @@ -0,0 +1,16 @@ +// compile-flags: --document-private-items + +fn foo_fn() {} + +pub fn pub_foo_fn() {} + +macro_rules! foo_macro { + () => { }; +} + +#[macro_export] +macro_rules! exported_foo_macro { + () => { }; +} + +// TODO: add `@has` checks