From 255f107cacb8927e72798313d69fa83d2e752a20 Mon Sep 17 00:00:00 2001 From: Daniel Henry-Mantilla Date: Tue, 5 Jan 2021 15:07:40 +0100 Subject: [PATCH] Fix ICE on `pub macro`s defined within a non-module type namespace. --- src/librustdoc/visit_ast.rs | 18 +++++++++++++----- src/test/rustdoc/macro_pub_in_module.rs | 8 ++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 1e78a0140481..2dc9c7bc758c 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -93,6 +93,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }); // 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. + // Once #80415 is merged, this whole `for` loop research can be replaced by that. let mut cur_mod = &mut top_level_module; for path_segment in macro_parent_module.data { let path_segment_ty_ns = match path_segment.data { @@ -106,11 +107,18 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue 'exported_macros; } }; - cur_mod = cur_mod - .mods - .iter_mut() - .find(|module| module.name == Some(path_segment_ty_ns)) - .unwrap(); + // The obtained name in the type namespace may belong to something that is not + // a `mod`ule (_e.g._, it could be an `enum` with a `pub macro` defined within + // the block used for a discriminant. + if let Some(child_mod) = + cur_mod.mods.iter_mut().find(|module| module.name == Some(path_segment_ty_ns)) + { + cur_mod = child_mod; + } else { + // If the macro's parent def path is not exclusively made of module + // components, then it is not accessible (c.f. previous `continue`). + continue 'exported_macros; + } } cur_mod.macros.push((def, None)); } diff --git a/src/test/rustdoc/macro_pub_in_module.rs b/src/test/rustdoc/macro_pub_in_module.rs index 59e69625455d..4fd85d689940 100644 --- a/src/test/rustdoc/macro_pub_in_module.rs +++ b/src/test/rustdoc/macro_pub_in_module.rs @@ -72,3 +72,11 @@ const __: () = { pub mod __ { // @!has krate/__/macro.in_both_const_and_mod.html } + +enum Enum { + Crazy = { + // @!has krate/macro.this_is_getting_weird.html; + pub macro this_is_getting_weird() {} + 42 + }, +}