Skip to content

Commit 4eda3f7

Browse files
committed
intra-doc macro resolution should also handle proc macros
1 parent feb3536 commit 4eda3f7

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

+39-24
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,42 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
122122
}
123123
}
124124

125+
/// Resolves a string as a macro.
126+
fn macro_resolve(&self, path_str: &str, parent_id: Option<hir::HirId>) -> Option<Res> {
127+
let cx = self.cx;
128+
let path = ast::Path::from_ident(Ident::from_str(path_str));
129+
cx.enter_resolver(|resolver| {
130+
if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
131+
&path,
132+
None,
133+
&ParentScope::module(resolver.graph_root()),
134+
false,
135+
false,
136+
) {
137+
if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
138+
return Some(res.map_id(|_| panic!("unexpected id")));
139+
}
140+
}
141+
if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
142+
return Some(res.map_id(|_| panic!("unexpected id")));
143+
}
144+
if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) {
145+
let module_id = cx.tcx.hir().local_def_id(module_id);
146+
if let Ok((_, res)) =
147+
resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
148+
{
149+
// don't resolve builtins like `#[derive]`
150+
if let Res::Def(..) = res {
151+
let res = res.map_id(|_| panic!("unexpected node_id"));
152+
return Some(res);
153+
}
154+
}
155+
} else {
156+
debug!("attempting to resolve item without parent module: {}", path_str);
157+
}
158+
None
159+
})
160+
}
125161
/// Resolves a string as a path within a particular namespace. Also returns an optional
126162
/// URL fragment in the case of variants and methods.
127163
fn resolve(
@@ -615,7 +651,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
615651
None => {
616652
// Try everything!
617653
let candidates = PerNS {
618-
macro_ns: macro_resolve(cx, path_str)
654+
macro_ns: self
655+
.macro_resolve(path_str, base_node)
619656
.map(|res| (res, extra_fragment.clone())),
620657
type_ns: match self.resolve(
621658
path_str,
@@ -684,7 +721,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
684721
}
685722
}
686723
Some(MacroNS) => {
687-
if let Some(res) = macro_resolve(cx, path_str) {
724+
if let Some(res) = self.macro_resolve(path_str, base_node) {
688725
(res, extra_fragment)
689726
} else {
690727
resolution_failure(cx, &item, path_str, &dox, link_range);
@@ -727,28 +764,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
727764
}
728765
}
729766

730-
/// Resolves a string as a macro.
731-
fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
732-
let path = ast::Path::from_ident(Ident::from_str(path_str));
733-
cx.enter_resolver(|resolver| {
734-
if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
735-
&path,
736-
None,
737-
&ParentScope::module(resolver.graph_root()),
738-
false,
739-
false,
740-
) {
741-
if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
742-
return Some(res.map_id(|_| panic!("unexpected id")));
743-
}
744-
}
745-
if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
746-
return Some(res.map_id(|_| panic!("unexpected id")));
747-
}
748-
None
749-
})
750-
}
751-
752767
fn build_diagnostic(
753768
cx: &DocContext<'_>,
754769
item: &Item,

0 commit comments

Comments
 (0)