@@ -74,50 +74,46 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
7474 // well (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by
7575 // moving them back to their correct locations.
7676 krate. exported_macros . iter ( ) . for_each ( |def| {
77- /// A return value of `None` signifies a fallback to the default behavior (locating
78- /// the macro at the root of the crate).
79- fn containing_mod_of_macro < ' module , ' hir > (
80- def : & ' _ rustc_hir:: MacroDef < ' _ > ,
81- tcx : TyCtxt < ' _ > ,
82- top_level_module : & ' module mut Module < ' hir > ,
83- ) -> Option < & ' module mut Module < ' hir > > {
84- // The `def` of a macro in `exported_macros` should correspond to either:
85- // - a `#[macro-export] macro_rules!` macro,
86- // - a built-in `derive` (or attribute) macro such as the ones in `::core`,
87- // - a `pub macro`.
88- // Only the last two need to be fixed, thus:
89- if def. ast . macro_rules {
90- return None ;
91- }
92- /* Because of #77828 we cannot do the simpler:
93- let macro_parent_module = tcx.def_path(tcx.parent_module(def.hir_id).to_def_id());
94- // and instead have to do: */
95- let macro_parent_module = tcx. def_path ( {
96- use rustc_middle:: ty:: DefIdTree ;
97- tcx. parent ( tcx. hir ( ) . local_def_id ( def. hir_id ) . to_def_id ( ) ) ?
98- } ) ;
99- // HACK: rustdoc has no way to lookup `doctree::Module`s by their HirId. Instead,
100- // lookup the module by its name, by looking at each path segment one at a time.
101- // WARNING: this will probably break in the presence of re-exports or shadowing.
102- let mut cur_mod = top_level_module;
103- for path_segment in macro_parent_module. data {
104- let path_segment = path_segment. to_string ( ) ;
105- cur_mod = cur_mod. mods . iter_mut ( ) . find ( |module| {
106- matches ! (
107- module. name, Some ( symbol)
108- if symbol. with( |mod_name| mod_name == path_segment)
109- )
110- } ) ?;
111- }
112- Some ( cur_mod)
77+ let visit_macro = || self . visit_local_macro ( def, None ) ;
78+ // The `def` of a macro in `exported_macros` should correspond to either:
79+ // - a `#[macro-export] macro_rules!` macro,
80+ // - a built-in `derive` (or attribute) macro such as the ones in `::core`,
81+ // - a `pub macro`.
82+ // Only the last two need to be fixed, thus:
83+ if def. ast . macro_rules {
84+ top_level_module. macros . push ( visit_macro ( ) ) ;
85+ return ;
11386 }
114-
115- if let Some ( module) = containing_mod_of_macro ( def, self . cx . tcx , & mut top_level_module) {
116- & mut module. macros
117- } else {
118- & mut top_level_module. macros
87+ let tcx = self . cx . tcx ;
88+ /* Because of #77828 we cannot do the simpler:
89+ let macro_parent_module = tcx.def_path(tcx.parent_module(def.hir_id).to_def_id());
90+ // and instead have to do: */
91+ let macro_parent_module = tcx. def_path ( {
92+ use rustc_middle:: ty:: DefIdTree ;
93+ tcx. parent ( tcx. hir ( ) . local_def_id ( def. hir_id ) . to_def_id ( ) ) . unwrap ( )
94+ } ) ;
95+ // HACK: rustdoc has no way to lookup `doctree::Module`s by their HirId. Instead,
96+ // lookup the module by its name, by looking at each path segment one at a time.
97+ let mut cur_mod = & mut top_level_module;
98+ for path_segment in macro_parent_module. data {
99+ let path_segment_ty_ns = match path_segment. data {
100+ rustc_hir:: definitions:: DefPathData :: TypeNs ( symbol) => symbol,
101+ _ => {
102+ // If the path segment is not from the type namespace
103+ // (_e.g._, it can be from a value namespace in the case of `f::` in:
104+ // `fn f() { pub macro m() {} }`
105+ // then the item is not accessible, and should thus act as if it didn't
106+ // exist (unless "associated macros" (inside an `impl`) were a thing…).
107+ return ;
108+ }
109+ } ;
110+ cur_mod = cur_mod
111+ . mods
112+ . iter_mut ( )
113+ . find ( |module| module. name == Some ( path_segment_ty_ns) )
114+ . unwrap ( ) ;
119115 }
120- . push ( self . visit_local_macro ( def , None ) ) ;
116+ cur_mod . macros . push ( visit_macro ( ) ) ;
121117 } ) ;
122118
123119 self . cx . renderinfo . get_mut ( ) . exact_paths = self . exact_paths ;
0 commit comments