Implement suggestions from code review.

This commit is contained in:
Daniel Henry-Mantilla 2020-10-13 20:25:19 +02:00
parent 0bee80210d
commit 7d03870882
2 changed files with 35 additions and 25 deletions

View File

@ -70,35 +70,36 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
); );
top_level_module.is_crate = true; top_level_module.is_crate = true;
// Attach the crate's exported macros to the top-level module. // Attach the crate's exported macros to the top-level module.
// In the case of macros 2.0 (`pub macro`), and for built-in `derive`s as well // In the case of macros 2.0 (`pub macro`), and for built-in `derive`s or attributes as
// (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by // well (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by
// moving them back to their correct locations. // moving them back to their correct locations.
krate.exported_macros.iter().for_each(|def| { krate.exported_macros.iter().for_each(|def| {
macro_rules! try_some {($($body:tt)*) => ({ /// A return value of `None` signifies a fallback to the default behavior (locating
fn fn_once<R, F: FnOnce() -> R> (f: F) -> F { f } /// the macro at the root of the crate).
fn_once(|| Some({ $($body)* }))() fn containing_mod_of_macro<'module, 'hir>(
})} def: &'_ rustc_hir::MacroDef<'_>,
// In the case of dummy items, some of the following operations may fail. We propagate tcx: TyCtxt<'_>,
// that within a `?`-capturing block, so as to fallback to the basic behavior. top_level_module: &'module mut Module<'hir>,
let containing_module_of_def = try_some! { ) -> Option<&'module mut Module<'hir>> {
// The `def` of a macro in `exported_macros` should correspond to either: // The `def` of a macro in `exported_macros` should correspond to either:
// - a `#[macro-export] macro_rules!` macro, // - a `#[macro-export] macro_rules!` macro,
// - a built-in `derive` macro such as the ones in `::core`, // - a built-in `derive` (or attribute) macro such as the ones in `::core`,
// - a `pub macro`. // - a `pub macro`.
// Only the last two need to be fixed, thus: // Only the last two need to be fixed, thus:
if def.ast.macro_rules { if def.ast.macro_rules {
return None; return None;
} }
let macro_parent_module = self.cx.tcx.def_path({
use rustc_middle::ty::DefIdTree;
self.cx
.tcx
/* Because of #77828 we cannot do the simpler: /* Because of #77828 we cannot do the simpler:
.parent_module(def.hir_id).to_def_id() let macro_parent_module = tcx.def_path(tcx.parent_module(def.hir_id).to_def_id());
// and instead have to do: */ // and instead have to do: */
.parent(self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id())? let macro_parent_module = tcx.def_path({
use rustc_middle::ty::DefIdTree;
tcx.parent(tcx.hir().local_def_id(def.hir_id).to_def_id())?
}); });
let mut cur_mod = &mut top_level_module; // HACK: rustdoc has no way to lookup `doctree::Module`s by their HirId. Instead,
// lookup the module by its name, by looking at each path segment one at a time.
// WARNING: this will probably break in the presence of re-exports or shadowing.
let mut cur_mod = top_level_module;
for path_segment in macro_parent_module.data { for path_segment in macro_parent_module.data {
let path_segment = path_segment.to_string(); let path_segment = path_segment.to_string();
cur_mod = cur_mod.mods.iter_mut().find(|module| { cur_mod = cur_mod.mods.iter_mut().find(|module| {
@ -108,9 +109,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
) )
})?; })?;
} }
cur_mod Some(cur_mod)
}; }
if let Some(module) = containing_module_of_def {
if let Some(module) = containing_mod_of_macro(def, self.cx.tcx, &mut top_level_module) {
&mut module.macros &mut module.macros
} else { } else {
&mut top_level_module.macros &mut top_level_module.macros

View File

@ -1,9 +1,17 @@
//! See issue #74355 //! See issue #74355
#![feature(decl_macro, no_core, rustc_attrs)]
#![crate_name = "krate"] #![crate_name = "krate"]
#![feature(decl_macro)] #![no_core]
// @has krate/some_module/macro.my_macro.html pub mod inner {
pub mod some_module { // @has krate/inner/macro.my_macro.html
//
pub macro my_macro() {} pub macro my_macro() {}
// @has krate/inner/macro.test.html
#[rustc_builtin_macro]
pub macro test($item:item) {}
// @has krate/inner/macro.Clone.html
#[rustc_builtin_macro]
pub macro Clone($item:item) {}
} }