Support intra-doc links on macro re-exports
This includes both `macro_rules!` and proc-macros.
This commit is contained in:
parent
5f49f55eb4
commit
e63e5cdab0
@ -124,7 +124,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves a string as a macro.
|
/// Resolves a string as a macro.
|
||||||
fn macro_resolve(&self, path_str: &str, parent_id: Option<hir::HirId>) -> Option<Res> {
|
fn macro_resolve(&self, path_str: &str, parent_id: Option<DefId>) -> Option<Res> {
|
||||||
let cx = self.cx;
|
let cx = self.cx;
|
||||||
let path = ast::Path::from_ident(Ident::from_str(path_str));
|
let path = ast::Path::from_ident(Ident::from_str(path_str));
|
||||||
cx.enter_resolver(|resolver| {
|
cx.enter_resolver(|resolver| {
|
||||||
@ -142,8 +142,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
|
if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
|
||||||
return Some(res.map_id(|_| panic!("unexpected id")));
|
return Some(res.map_id(|_| panic!("unexpected id")));
|
||||||
}
|
}
|
||||||
if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) {
|
if let Some(module_id) = parent_id {
|
||||||
let module_id = cx.tcx.hir().local_def_id(module_id);
|
|
||||||
if let Ok((_, res)) =
|
if let Ok((_, res)) =
|
||||||
resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
|
resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
|
||||||
{
|
{
|
||||||
@ -167,17 +166,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
disambiguator: Option<&str>,
|
disambiguator: Option<&str>,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
current_item: &Option<String>,
|
current_item: &Option<String>,
|
||||||
mut parent_id: Option<DefId>,
|
parent_id: Option<DefId>,
|
||||||
extra_fragment: &Option<String>,
|
extra_fragment: &Option<String>,
|
||||||
item_opt: Option<&Item>,
|
item_opt: Option<&Item>,
|
||||||
) -> Result<(Res, Option<String>), ErrorKind> {
|
) -> Result<(Res, Option<String>), ErrorKind> {
|
||||||
let cx = self.cx;
|
let cx = self.cx;
|
||||||
|
|
||||||
// In case we're in a module, try to resolve the relative path.
|
// In case we're in a module, try to resolve the relative path.
|
||||||
if parent_id.is_none() {
|
|
||||||
let id = self.mod_ids.last().cloned();
|
|
||||||
parent_id = id.map(|id| cx.tcx.hir().local_def_id(id).to_def_id());
|
|
||||||
}
|
|
||||||
if let Some(module_id) = parent_id {
|
if let Some(module_id) = parent_id {
|
||||||
let result = cx.enter_resolver(|resolver| {
|
let result = cx.enter_resolver(|resolver| {
|
||||||
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
|
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
|
||||||
@ -659,8 +654,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||||||
// we've already pushed this node onto the resolution stack but
|
// we've already pushed this node onto the resolution stack but
|
||||||
// for outer comments we explicitly try and resolve against the
|
// for outer comments we explicitly try and resolve against the
|
||||||
// parent_node first.
|
// parent_node first.
|
||||||
let base_node =
|
let base_node = if item.is_mod() && item.attrs.inner_docs {
|
||||||
if item.is_mod() && item.attrs.inner_docs { None } else { parent_node };
|
self.mod_ids.last().map(|&id| self.cx.tcx.hir().local_def_id(id).to_def_id())
|
||||||
|
} else {
|
||||||
|
parent_node
|
||||||
|
};
|
||||||
|
|
||||||
// replace `Self` with suitable item's parent name
|
// replace `Self` with suitable item's parent name
|
||||||
if path_str.starts_with("Self::") {
|
if path_str.starts_with("Self::") {
|
||||||
|
10
src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs
Normal file
10
src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#![crate_name = "macro_inner"]
|
||||||
|
#![deny(intra_doc_resolution_failure)]
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
/// See also [`Foo`]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! my_macro {
|
||||||
|
() => {}
|
||||||
|
}
|
20
src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs
Normal file
20
src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// force-host
|
||||||
|
// no-prefer-dynamic
|
||||||
|
// compile-flags: --crate-type proc-macro
|
||||||
|
#![crate_type="proc-macro"]
|
||||||
|
#![crate_name="proc_macro_inner"]
|
||||||
|
|
||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
|
/// Links to [`OtherDerive`]
|
||||||
|
#[proc_macro_derive(DeriveA)]
|
||||||
|
pub fn a_derive(input: TokenStream) -> TokenStream {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(OtherDerive)]
|
||||||
|
pub fn other_derive(input: TokenStream) -> TokenStream {
|
||||||
|
input
|
||||||
|
}
|
12
src/test/rustdoc/intra-doc-crate/macro.rs
Normal file
12
src/test/rustdoc/intra-doc-crate/macro.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// ignore-tidy-linelength
|
||||||
|
// aux-build:macro_inner.rs
|
||||||
|
// aux-build:proc_macro.rs
|
||||||
|
// build-aux-docs
|
||||||
|
#![deny(intra_doc_resolution_failure)]
|
||||||
|
extern crate macro_inner;
|
||||||
|
extern crate proc_macro_inner;
|
||||||
|
|
||||||
|
// @has 'macro/macro.my_macro.html' '//a[@href="../macro_inner/struct.Foo.html"]' 'Foo'
|
||||||
|
pub use macro_inner::my_macro;
|
||||||
|
// @has 'macro/derive.DeriveA.html' '//a[@href="../proc_macro_inner/derive.OtherDerive.html"]' 'OtherDerive'
|
||||||
|
pub use proc_macro_inner::DeriveA;
|
Loading…
x
Reference in New Issue
Block a user