From 5271e98f4e8cf2e74e9b01fc2494ea9e90b08194 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 6 Jun 2020 17:19:21 -0400 Subject: [PATCH 01/19] Use get_module instead of `module_map` for `resolve_str_path_error` --- src/librustc_resolve/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c3686ca4899bc..0f2559e4b192e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2998,7 +2998,7 @@ impl<'a> Resolver<'a> { .collect(), } }; - let module = self.module_map.get(&module_id).copied().unwrap_or(self.graph_root); + let module = self.get_module(module_id.to_def_id()); let parent_scope = &ParentScope::module(module); let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; Ok((path, res)) From 848a766e24b799d27e7ae7479cd1f8c07047a53e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 6 Jun 2020 13:09:05 -0400 Subject: [PATCH 02/19] Use the scope of the imported variable for resolution, not the current scope - Accept DefId in resolve_str_path_error This will probably break lots of internal invariants. --- src/librustc_resolve/lib.rs | 4 +- src/librustdoc/core.rs | 2 +- .../passes/collect_intra_doc_links.rs | 96 ++++++++++++++++++- 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0f2559e4b192e..686385e24ece8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2978,7 +2978,7 @@ impl<'a> Resolver<'a> { span: Span, path_str: &str, ns: Namespace, - module_id: LocalDefId, + module_id: DefId, ) -> Result<(ast::Path, Res), ()> { let path = if path_str.starts_with("::") { ast::Path { @@ -2998,7 +2998,7 @@ impl<'a> Resolver<'a> { .collect(), } }; - let module = self.get_module(module_id.to_def_id()); + let module = self.get_module(module_id); let parent_scope = &ParentScope::module(module); let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?; Ok((path, res)) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 00315675fafe3..6a52974534f8b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -430,7 +430,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt DUMMY_SP, extern_name, TypeNS, - LocalDefId { local_def_index: CRATE_DEF_INDEX }, + LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(), ) .unwrap_or_else(|()| { panic!("Unable to resolve external crate {}", extern_name) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f707c1a3e1a10..fce7096a1af76 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -62,7 +62,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { &self, path_str: &str, current_item: &Option, - module_id: LocalDefId, + module_id: DefId, ) -> Result<(Res, Option), ErrorKind> { let cx = self.cx; @@ -167,15 +167,103 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { disambiguator: Option<&str>, ns: Namespace, current_item: &Option, - parent_id: Option, + mut parent_id: Option, extra_fragment: &Option, item_opt: Option<&Item>, ) -> Result<(Res, Option), ErrorKind> { + use rustc_hir::{ItemKind, UseKind}; + let cx = self.cx; + // In case this is a re-export, try to resolve the docs relative to the original module. + // Since we don't document `use` statements, + // we don't have to consider the case where an item is documented in both the original module and the current module. + let mut module_id = None; + if let Some(item) = item_opt { + if let ItemEnum::ImportItem(import) = &item.inner { + if let Import::Simple(_, source) = import { + if let Some(def_id) = source.did { + use crate::rustc_middle::ty::DefIdTree; + + //let mut current_id = def_id; + if cx.tcx.def_kind(def_id) == DefKind::Mod { + module_id = Some(def_id); + debug!("found parent module {:?} for use statement", def_id); + //break; + } else { + debug!( + "not a module: {:?} (maybe an associated item?)", + cx.tcx.def_kind(def_id) + ); + } + + /* + // For associated items, the parent module might be multiple nodes above + while let Some(parent) = cx.tcx.parent(current_id) { + if cx.tcx.def_kind(parent) == DefKind::Mod { + parent_id = Some(parent); + debug!("found parent module {:?} for use statement", parent); + break; + } + current_id = parent; + } + */ + } else { + debug!("no def id found"); + } + } else { + debug!("glob imports not handled for intra-doc links"); + } + } + /* + if let Some(reexport) = item.reexport { + use crate::rustc_middle::ty::DefIdTree; + + let mut current_id = reexport; + // For associated items, the parent module might be multiple nodes above + while let Some(parent) = cx.tcx.parent(current_id) { + if cx.tcx.def_kind(parent) == DefKind::Mod { + parent_id = Some(parent); + debug!("found parent module {:?} for use statement", parent); + break; + } + current_id = parent; + } + } + */ + /* + if let ItemKind::Use(path, use_kind) = item.kind { + if use_kind == UseKind::Single { + match path.res { + Res::Def(def_kind, def_id) => { + use crate::rustc_middle::ty::DefIdTree; + + let mut current_id = def_id; + // For associated items, the parent module might be multiple nodes above + while let Some(parent) = cx.tcx.parent(current_id) { + if cx.tcx.def_kind(parent) == DefKind::Mod { + parent_id = Some(parent); + debug!("found parent module {:?} for use statement", parent); + break; + } + current_id = parent; + } + } + _ => debug!("use {:?} was not a definition, not treating as cross-crate", item.name), + } + } else { + debug!("don't know how to resolve multiple imports for {:?}, not treating as cross-crate", path); + } + } + */ + } + // In case we're in a module, try to resolve the relative path. - if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) { - let module_id = cx.tcx.hir().local_def_id(module_id); + if module_id.is_none() { + let id = parent_id.or(self.mod_ids.last().cloned()); + module_id = id.map(|id| cx.tcx.hir().local_def_id(id).to_def_id()); + } + if let Some(module_id) = module_id { let result = cx.enter_resolver(|resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) }); From 69bd13f233d2cf5ceaf358f69c8e0902f79be73c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 6 Jun 2020 23:06:21 -0400 Subject: [PATCH 03/19] Use DefId for modules --- .../passes/collect_intra_doc_links.rs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fce7096a1af76..3c2e3eabf9f24 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -167,7 +167,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { disambiguator: Option<&str>, ns: Namespace, current_item: &Option, - mut parent_id: Option, + mut parent_id: Option, extra_fragment: &Option, item_opt: Option<&Item>, ) -> Result<(Res, Option), ErrorKind> { @@ -178,8 +178,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // In case this is a re-export, try to resolve the docs relative to the original module. // Since we don't document `use` statements, // we don't have to consider the case where an item is documented in both the original module and the current module. + /* let mut module_id = None; if let Some(item) = item_opt { + debug!("resolving {:?} with item kind {:?}", path_str, item.inner); if let ItemEnum::ImportItem(import) = &item.inner { if let Import::Simple(_, source) = import { if let Some(def_id) = source.did { @@ -214,6 +216,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } else { debug!("glob imports not handled for intra-doc links"); } + } else { + //debug!("item.inner not an import ({:?})", item.inner); } /* if let Some(reexport) = item.reexport { @@ -257,13 +261,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } */ } + */ // In case we're in a module, try to resolve the relative path. - if module_id.is_none() { - let id = parent_id.or(self.mod_ids.last().cloned()); - module_id = id.map(|id| cx.tcx.hir().local_def_id(id).to_def_id()); + 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) = module_id { + if let Some(module_id) = parent_id { let result = cx.enter_resolver(|resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id) }); @@ -545,6 +550,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }; // FIXME: get the resolver to work with non-local resolve scopes. + use rustc_middle::ty::DefIdTree; + let parent_node = self.cx.tcx.parent(item.def_id); + /* let parent_node = self.cx.as_local_hir_id(item.def_id).and_then(|hir_id| { // FIXME: this fails hard for impls in non-module scope, but is necessary for the // current `resolve()` implementation. @@ -553,6 +561,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { _ => None, } }); + */ if parent_node.is_some() { debug!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); @@ -563,10 +572,10 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { if item.attrs.inner_docs { if item_hir_id.unwrap() != hir::CRATE_HIR_ID { item.name.clone() } else { None } } else { - match parent_node.or(self.mod_ids.last().cloned()) { - Some(parent) if parent != hir::CRATE_HIR_ID => { + match parent_node.or(self.mod_ids.last().map(|&local| self.cx.tcx.hir().local_def_id(local).to_def_id())) { + Some(parent) if !parent.is_top_level_module() => { // FIXME: can we pull the parent module's name from elsewhere? - Some(self.cx.tcx.hir().name(parent).to_string()) + Some(self.cx.tcx.item_name(parent).to_string()) } _ => None, } From c3d9a730b748a3c8bf673b88a265faad67ec7d9d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 13:05:01 -0400 Subject: [PATCH 04/19] Don't panic on fake IDs --- .../passes/collect_intra_doc_links.rs | 112 ++---------------- 1 file changed, 11 insertions(+), 101 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3c2e3eabf9f24..65b852f1d619c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -175,94 +175,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let cx = self.cx; - // In case this is a re-export, try to resolve the docs relative to the original module. - // Since we don't document `use` statements, - // we don't have to consider the case where an item is documented in both the original module and the current module. - /* - let mut module_id = None; - if let Some(item) = item_opt { - debug!("resolving {:?} with item kind {:?}", path_str, item.inner); - if let ItemEnum::ImportItem(import) = &item.inner { - if let Import::Simple(_, source) = import { - if let Some(def_id) = source.did { - use crate::rustc_middle::ty::DefIdTree; - - //let mut current_id = def_id; - if cx.tcx.def_kind(def_id) == DefKind::Mod { - module_id = Some(def_id); - debug!("found parent module {:?} for use statement", def_id); - //break; - } else { - debug!( - "not a module: {:?} (maybe an associated item?)", - cx.tcx.def_kind(def_id) - ); - } - - /* - // For associated items, the parent module might be multiple nodes above - while let Some(parent) = cx.tcx.parent(current_id) { - if cx.tcx.def_kind(parent) == DefKind::Mod { - parent_id = Some(parent); - debug!("found parent module {:?} for use statement", parent); - break; - } - current_id = parent; - } - */ - } else { - debug!("no def id found"); - } - } else { - debug!("glob imports not handled for intra-doc links"); - } - } else { - //debug!("item.inner not an import ({:?})", item.inner); - } - /* - if let Some(reexport) = item.reexport { - use crate::rustc_middle::ty::DefIdTree; - - let mut current_id = reexport; - // For associated items, the parent module might be multiple nodes above - while let Some(parent) = cx.tcx.parent(current_id) { - if cx.tcx.def_kind(parent) == DefKind::Mod { - parent_id = Some(parent); - debug!("found parent module {:?} for use statement", parent); - break; - } - current_id = parent; - } - } - */ - /* - if let ItemKind::Use(path, use_kind) = item.kind { - if use_kind == UseKind::Single { - match path.res { - Res::Def(def_kind, def_id) => { - use crate::rustc_middle::ty::DefIdTree; - - let mut current_id = def_id; - // For associated items, the parent module might be multiple nodes above - while let Some(parent) = cx.tcx.parent(current_id) { - if cx.tcx.def_kind(parent) == DefKind::Mod { - parent_id = Some(parent); - debug!("found parent module {:?} for use statement", parent); - break; - } - current_id = parent; - } - } - _ => debug!("use {:?} was not a definition, not treating as cross-crate", item.name), - } - } else { - debug!("don't know how to resolve multiple imports for {:?}, not treating as cross-crate", 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(); @@ -549,19 +461,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { None }; - // FIXME: get the resolver to work with non-local resolve scopes. use rustc_middle::ty::DefIdTree; - let parent_node = self.cx.tcx.parent(item.def_id); - /* - let parent_node = self.cx.as_local_hir_id(item.def_id).and_then(|hir_id| { - // FIXME: this fails hard for impls in non-module scope, but is necessary for the - // current `resolve()` implementation. - match self.cx.as_local_hir_id(self.cx.tcx.parent_module(hir_id).to_def_id()).unwrap() { - id if id != hir_id => Some(id), - _ => None, - } - }); - */ + let parent_node = if item.is_fake() { + // FIXME: is this correct? + None + } else { + self.cx.tcx.parent(item.def_id) + }; if parent_node.is_some() { debug!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); @@ -572,7 +478,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { if item.attrs.inner_docs { if item_hir_id.unwrap() != hir::CRATE_HIR_ID { item.name.clone() } else { None } } else { - match parent_node.or(self.mod_ids.last().map(|&local| self.cx.tcx.hir().local_def_id(local).to_def_id())) { + match parent_node.or(self + .mod_ids + .last() + .map(|&local| self.cx.tcx.hir().local_def_id(local).to_def_id())) + { Some(parent) if !parent.is_top_level_module() => { // FIXME: can we pull the parent module's name from elsewhere? Some(self.cx.tcx.item_name(parent).to_string()) From 20106d5a2fda0f2fef97ce253e5d78d4cf030289 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 13:45:02 -0400 Subject: [PATCH 05/19] unwrap() -> expect() --- src/librustc_resolve/build_reduced_graph.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 8db27babd058b..45253fc878222 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -111,12 +111,17 @@ impl<'a> Resolver<'a> { (self.cstore().crate_name_untracked(def_id.krate), None) } else { let def_key = self.cstore().def_key(def_id); - ( - // This unwrap is safe: crates must always have a name - def_key.disambiguated_data.data.get_opt_name().unwrap(), - // This unwrap is safe since we know this isn't the root - Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })), - ) + let name = def_key + .disambiguated_data + .data + .get_opt_name() + .expect("given a DefId that wasn't a module"); + // This unwrap is safe since we know this isn't the root + let parent = Some(self.get_module(DefId { + index: def_key.parent.expect("failed to get parent for module"), + ..def_id + })); + (name, parent) }; // Allocate and return a new module with the information we found From 24c3d85e66b0fd719d9ffa70ae5e56593cb9b644 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 17:08:26 -0400 Subject: [PATCH 06/19] Make sure that module_id is actually a module --- src/librustdoc/passes/collect_intra_doc_links.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 65b852f1d619c..487a4a5b0a229 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -466,7 +466,19 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // FIXME: is this correct? None } else { - self.cx.tcx.parent(item.def_id) + let mut current = item.def_id; + // The immediate parent might not always be a module. + // Find the first parent which is. + loop { + if let Some(parent) = self.cx.tcx.parent(current) { + if self.cx.tcx.def_kind(parent) == DefKind::Mod { + break Some(parent); + } + current = parent; + } else { + break None; + } + } }; if parent_node.is_some() { From 9542e23a7d915f50e84a048a5ed6aab34335ff52 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 21:16:54 -0400 Subject: [PATCH 07/19] Add tests for basic intra-doc links --- .../rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs | 5 +++++ src/test/rustdoc/intra-doc-crate/basic.rs | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs create mode 100644 src/test/rustdoc/intra-doc-crate/basic.rs diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs new file mode 100644 index 0000000000000..7f5609bcf5281 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs @@ -0,0 +1,5 @@ +#![crate_name = "a"] +pub struct Foo; + +/// Link to [Foo] +pub struct Bar; diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs new file mode 100644 index 0000000000000..dd32908714f4f --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -0,0 +1,6 @@ +// aux-build:intra-doc-basic.rs +// build-aux-docs +extern crate a; + +// @has 'basic/struct.Bar.html' '//a[@href="../a/struct.Foo.html"]' 'Foo' +pub use a::Bar; From 99f34d814e87e33e014433f791a13db3a3bd2273 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 21:17:56 -0400 Subject: [PATCH 08/19] Remove warnings --- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 487a4a5b0a229..52518bcb631f1 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -8,7 +8,7 @@ use rustc_hir::def::{ Namespace::{self, *}, PerNS, Res, }; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_middle::ty; use rustc_resolve::ParentScope; use rustc_session::lint; @@ -171,8 +171,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { extra_fragment: &Option, item_opt: Option<&Item>, ) -> Result<(Res, Option), ErrorKind> { - use rustc_hir::{ItemKind, UseKind}; - let cx = self.cx; // In case we're in a module, try to resolve the relative path. From e78d499637761efceebf6f9cb8ab317a31541ec7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 21:48:31 -0400 Subject: [PATCH 09/19] Add test for re-exports I had a hard time getting this to work without the `extern crate`, suggestions are welcome. --- .../rustdoc/intra-doc-crate/auxiliary/submodule.rs | 12 ++++++++++++ src/test/rustdoc/intra-doc-crate/basic.rs | 2 ++ src/test/rustdoc/intra-doc-crate/submodule.rs | 14 ++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs create mode 100644 src/test/rustdoc/intra-doc-crate/submodule.rs diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs new file mode 100644 index 0000000000000..dfc8685f38428 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs @@ -0,0 +1,12 @@ +#![crate_name = "bar"] + +pub trait Foo { + /// [`Bar`] [`Baz`] + fn foo(); +} + +pub trait Bar { +} + +pub trait Baz { +} diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs index dd32908714f4f..3fb72b2b497f3 100644 --- a/src/test/rustdoc/intra-doc-crate/basic.rs +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -1,5 +1,7 @@ // aux-build:intra-doc-basic.rs // build-aux-docs + +// from https://github.com/rust-lang/rust/issues/65983 extern crate a; // @has 'basic/struct.Bar.html' '//a[@href="../a/struct.Foo.html"]' 'Foo' diff --git a/src/test/rustdoc/intra-doc-crate/submodule.rs b/src/test/rustdoc/intra-doc-crate/submodule.rs new file mode 100644 index 0000000000000..5caa220b570f1 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/submodule.rs @@ -0,0 +1,14 @@ +// aux-build:submodule.rs +// edition:2018 +extern crate bar as bar_; + +// from https://github.com/rust-lang/rust/issues/60883 +pub mod bar { + pub use ::bar_::Bar; +} + +// NOTE: we re-exported both `Foo` and `Bar` here, +// NOTE: so they are inlined and therefore we link to the current module. +// @has 'submodule/trait.Foo.html' '//a[@href="../submodule/bar/trait.Bar.html"]' 'Bar' +// @has 'submodule/trait.Foo.html' '//a[@href="../submodule/trait.Baz.html"]' 'Baz' +pub use ::bar_::{Foo, Baz}; From 9eb63945eb02b67e3edf4a7214c3148bffa49ed2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 7 Jun 2020 22:11:03 -0400 Subject: [PATCH 10/19] Add test for documenting the re-export --- src/test/rustdoc/intra-doc-crate/additional_doc.rs | 8 ++++++++ .../rustdoc/intra-doc-crate/auxiliary/additional_doc.rs | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/rustdoc/intra-doc-crate/additional_doc.rs create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs new file mode 100644 index 0000000000000..d72548b0e2de5 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -0,0 +1,8 @@ +// aux-build:additional_doc.rs +// build-aux-docs +extern crate rand; + +// @has 'additional_doc/trait.Rng.html' '//a[@href="../additional_doc/trait.Rng.html"]' 'Rng' +// @has 'additional_doc/trait.Rng.html' '//a[@href="../rand/trait.RngCore.html"]' 'RngCore' +/// This is an [`Rng`]. +pub use rand::Rng; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs new file mode 100644 index 0000000000000..9d0a9882289e8 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -0,0 +1,5 @@ +#![crate_name = "rand"] + +pub trait RngCore {} +/// Rng extends [`RngCore`]. +pub trait Rng: RngCore {} From 71fe8f7cd8afa71892cb45046b11d0d3f53526a9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 9 Jun 2020 20:12:01 -0400 Subject: [PATCH 11/19] Add test for submodules in inner crate --- .../intra-doc-crate/auxiliary/submodule-inner.rs | 11 +++++++++++ .../auxiliary/{submodule.rs => submodule-outer.rs} | 0 src/test/rustdoc/intra-doc-crate/submodule-inner.rs | 6 ++++++ .../{submodule.rs => submodule-outer.rs} | 6 +++--- 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs rename src/test/rustdoc/intra-doc-crate/auxiliary/{submodule.rs => submodule-outer.rs} (100%) create mode 100644 src/test/rustdoc/intra-doc-crate/submodule-inner.rs rename src/test/rustdoc/intra-doc-crate/{submodule.rs => submodule-outer.rs} (56%) diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs new file mode 100644 index 0000000000000..2258bb1956ce1 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs @@ -0,0 +1,11 @@ +#![crate_name = "a"] + +pub mod bar { + pub struct Bar; +} + +pub mod foo { + use crate::bar; + /// link to [bar::Bar] + pub struct Foo; +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs similarity index 100% rename from src/test/rustdoc/intra-doc-crate/auxiliary/submodule.rs rename to src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs diff --git a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs new file mode 100644 index 0000000000000..ab508c8792d3d --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs @@ -0,0 +1,6 @@ +// aux-build:submodule-inner.rs +// build-aux-docs +extern crate a; + +// @has 'submodule_inner/struct.Foo.html' '//a[@href="../a/bar/struct.Bar.html"]' 'Bar' +pub use a::foo::Foo; diff --git a/src/test/rustdoc/intra-doc-crate/submodule.rs b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs similarity index 56% rename from src/test/rustdoc/intra-doc-crate/submodule.rs rename to src/test/rustdoc/intra-doc-crate/submodule-outer.rs index 5caa220b570f1..3ce92cacfc247 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs @@ -1,4 +1,4 @@ -// aux-build:submodule.rs +// aux-build:submodule-outer.rs // edition:2018 extern crate bar as bar_; @@ -9,6 +9,6 @@ pub mod bar { // NOTE: we re-exported both `Foo` and `Bar` here, // NOTE: so they are inlined and therefore we link to the current module. -// @has 'submodule/trait.Foo.html' '//a[@href="../submodule/bar/trait.Bar.html"]' 'Bar' -// @has 'submodule/trait.Foo.html' '//a[@href="../submodule/trait.Baz.html"]' 'Baz' +// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/bar/trait.Bar.html"]' 'Bar' +// @has 'submodule_outer/trait.Foo.html' '//a[@href="../submodule_outer/trait.Baz.html"]' 'Baz' pub use ::bar_::{Foo, Baz}; From 432b0431ab0f087a6511c1f8b71c3837cb62237e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 9 Jun 2020 21:00:06 -0400 Subject: [PATCH 12/19] Move import to top of function --- src/librustdoc/passes/collect_intra_doc_links.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 52518bcb631f1..3cbbb58353bba 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -448,6 +448,8 @@ fn is_derive_trait_collision(ns: &PerNS>) -> bool { impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { fn fold_item(&mut self, mut item: Item) -> Option { + use rustc_middle::ty::DefIdTree; + let item_hir_id = if item.is_mod() { if let Some(def_id) = item.def_id.as_local() { Some(self.cx.tcx.hir().as_local_hir_id(def_id)) @@ -459,7 +461,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { None }; - use rustc_middle::ty::DefIdTree; let parent_node = if item.is_fake() { // FIXME: is this correct? None From 769acbaca056aaa4b8ebbf5963806d1a3ee7a9f0 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 10 Jun 2020 08:56:44 -0400 Subject: [PATCH 13/19] #![deny(intra_doc_resolution_failure)] --- src/test/rustdoc/intra-doc-crate/additional_doc.rs | 2 ++ src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs | 1 + src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs | 2 ++ src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs | 1 + src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs | 1 + src/test/rustdoc/intra-doc-crate/basic.rs | 1 + src/test/rustdoc/intra-doc-crate/submodule-inner.rs | 2 ++ src/test/rustdoc/intra-doc-crate/submodule-outer.rs | 2 ++ 8 files changed, 12 insertions(+) diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs index d72548b0e2de5..95df8a781d29a 100644 --- a/src/test/rustdoc/intra-doc-crate/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -1,5 +1,7 @@ // aux-build:additional_doc.rs // build-aux-docs +#![deny(intra_doc_resolution_failure)] + extern crate rand; // @has 'additional_doc/trait.Rng.html' '//a[@href="../additional_doc/trait.Rng.html"]' 'Rng' diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs index 9d0a9882289e8..46aca95095fd2 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -1,4 +1,5 @@ #![crate_name = "rand"] +#![deny(intra_doc_resolution_failure)] pub trait RngCore {} /// Rng extends [`RngCore`]. diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs index 7f5609bcf5281..8c83633424fd9 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs @@ -1,4 +1,6 @@ #![crate_name = "a"] +#![deny(intra_doc_resolution_failure)] + pub struct Foo; /// Link to [Foo] diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs index 2258bb1956ce1..73073ebff1406 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs @@ -1,4 +1,5 @@ #![crate_name = "a"] +#![deny(intra_doc_resolution_failure)] pub mod bar { pub struct Bar; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs index dfc8685f38428..c045d6488f46d 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs @@ -1,4 +1,5 @@ #![crate_name = "bar"] +#![deny(intra_doc_resolution_failure)] pub trait Foo { /// [`Bar`] [`Baz`] diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs index 3fb72b2b497f3..6b6757b94e36a 100644 --- a/src/test/rustdoc/intra-doc-crate/basic.rs +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -1,5 +1,6 @@ // aux-build:intra-doc-basic.rs // build-aux-docs +#![deny(intra_doc_resolution_failure)] // from https://github.com/rust-lang/rust/issues/65983 extern crate a; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs index ab508c8792d3d..e83d258c1df35 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs @@ -1,5 +1,7 @@ // aux-build:submodule-inner.rs // build-aux-docs +#![deny(intra_doc_resolution_failure)] + extern crate a; // @has 'submodule_inner/struct.Foo.html' '//a[@href="../a/bar/struct.Bar.html"]' 'Bar' diff --git a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs index 3ce92cacfc247..ccf226e1dfd03 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs @@ -1,5 +1,7 @@ // aux-build:submodule-outer.rs // edition:2018 +#![deny(intra_doc_resolution_failure)] + extern crate bar as bar_; // from https://github.com/rust-lang/rust/issues/60883 From 5f49f55eb4fc73dc89ab80c124b9eb158e51f57b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 10 Jun 2020 10:30:33 -0400 Subject: [PATCH 14/19] rand -> my_rand This fixes a failure in stage2 rustdoc tests. --- src/test/rustdoc/intra-doc-crate/additional_doc.rs | 6 +++--- .../rustdoc/intra-doc-crate/auxiliary/additional_doc.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs index 95df8a781d29a..dc1d85c9941f9 100644 --- a/src/test/rustdoc/intra-doc-crate/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -2,9 +2,9 @@ // build-aux-docs #![deny(intra_doc_resolution_failure)] -extern crate rand; +extern crate my_rand; // @has 'additional_doc/trait.Rng.html' '//a[@href="../additional_doc/trait.Rng.html"]' 'Rng' -// @has 'additional_doc/trait.Rng.html' '//a[@href="../rand/trait.RngCore.html"]' 'RngCore' +// @has 'additional_doc/trait.Rng.html' '//a[@href="../my_rand/trait.RngCore.html"]' 'RngCore' /// This is an [`Rng`]. -pub use rand::Rng; +pub use my_rand::Rng; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs index 46aca95095fd2..353689a6d0db2 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -1,4 +1,4 @@ -#![crate_name = "rand"] +#![crate_name = "my_rand"] #![deny(intra_doc_resolution_failure)] pub trait RngCore {} From e63e5cdab02659beec0fd4a50d4b2556b7d6500d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 11 Jun 2020 22:58:09 -0400 Subject: [PATCH 15/19] Support intra-doc links on macro re-exports This includes both `macro_rules!` and proc-macros. --- .../passes/collect_intra_doc_links.rs | 18 ++++++++--------- .../intra-doc-crate/auxiliary/macro_inner.rs | 10 ++++++++++ .../intra-doc-crate/auxiliary/proc_macro.rs | 20 +++++++++++++++++++ src/test/rustdoc/intra-doc-crate/macro.rs | 12 +++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs create mode 100644 src/test/rustdoc/intra-doc-crate/macro.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3cbbb58353bba..fa0cbea1d8062 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } /// Resolves a string as a macro. - fn macro_resolve(&self, path_str: &str, parent_id: Option) -> Option { + fn macro_resolve(&self, path_str: &str, parent_id: Option) -> Option { let cx = self.cx; let path = ast::Path::from_ident(Ident::from_str(path_str)); 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)) { return Some(res.map_id(|_| panic!("unexpected id"))); } - if let Some(module_id) = parent_id.or(self.mod_ids.last().cloned()) { - let module_id = cx.tcx.hir().local_def_id(module_id); + if let Some(module_id) = parent_id { if let Ok((_, res)) = 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>, ns: Namespace, current_item: &Option, - mut parent_id: Option, + parent_id: Option, extra_fragment: &Option, item_opt: Option<&Item>, ) -> Result<(Res, Option), ErrorKind> { let cx = self.cx; // 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 { let result = cx.enter_resolver(|resolver| { 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 // for outer comments we explicitly try and resolve against the // parent_node first. - let base_node = - if item.is_mod() && item.attrs.inner_docs { None } else { parent_node }; + let base_node = if item.is_mod() && item.attrs.inner_docs { + 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 if path_str.starts_with("Self::") { diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs new file mode 100644 index 0000000000000..e54539f0bc5df --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs @@ -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 { + () => {} +} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs new file mode 100644 index 0000000000000..0d5a954075df2 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/proc_macro.rs @@ -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 +} diff --git a/src/test/rustdoc/intra-doc-crate/macro.rs b/src/test/rustdoc/intra-doc-crate/macro.rs new file mode 100644 index 0000000000000..5c8cec128dfa0 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/macro.rs @@ -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; From 82b3b0705bfe67ab1565505ae1422f9302e12b6e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 11 Jul 2020 13:28:05 -0400 Subject: [PATCH 16/19] Support intra-doc links on trait and module re-exports Trait implementations are treated the same as modules for the purposes of intra-doc links. --- .../passes/collect_intra_doc_links.rs | 28 +++++-------------- .../intra-doc-crate/auxiliary/module.rs | 7 +++++ .../intra-doc-crate/auxiliary/traits.rs | 16 +++++++++++ src/test/rustdoc/intra-doc-crate/module.rs | 8 ++++++ src/test/rustdoc/intra-doc-crate/traits.rs | 15 ++++++++++ 5 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/module.rs create mode 100644 src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs create mode 100644 src/test/rustdoc/intra-doc-crate/module.rs create mode 100644 src/test/rustdoc/intra-doc-crate/traits.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fa0cbea1d8062..76b731f62f3db 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -50,7 +50,8 @@ enum ErrorKind { struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, - mod_ids: Vec, + // NOTE: this may not necessarily be a module in the current crate + mod_ids: Vec, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { @@ -445,17 +446,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { fn fold_item(&mut self, mut item: Item) -> Option { use rustc_middle::ty::DefIdTree; - let item_hir_id = if item.is_mod() { - if let Some(def_id) = item.def_id.as_local() { - Some(self.cx.tcx.hir().as_local_hir_id(def_id)) - } else { - debug!("attempting to fold on a non-local item: {:?}", item); - return self.fold_item_recur(item); - } - } else { - None - }; - let parent_node = if item.is_fake() { // FIXME: is this correct? None @@ -482,13 +472,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let current_item = match item.inner { ModuleItem(..) => { if item.attrs.inner_docs { - if item_hir_id.unwrap() != hir::CRATE_HIR_ID { item.name.clone() } else { None } + if item.def_id.is_top_level_module() { item.name.clone() } else { None } } else { - match parent_node.or(self - .mod_ids - .last() - .map(|&local| self.cx.tcx.hir().local_def_id(local).to_def_id())) - { + match parent_node.or(self.mod_ids.last().copied()) { Some(parent) if !parent.is_top_level_module() => { // FIXME: can we pull the parent module's name from elsewhere? Some(self.cx.tcx.item_name(parent).to_string()) @@ -508,7 +494,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }; if item.is_mod() && item.attrs.inner_docs { - self.mod_ids.push(item_hir_id.unwrap()); + self.mod_ids.push(item.def_id); } let cx = self.cx; @@ -655,7 +641,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { // for outer comments we explicitly try and resolve against the // parent_node first. let base_node = if item.is_mod() && item.attrs.inner_docs { - self.mod_ids.last().map(|&id| self.cx.tcx.hir().local_def_id(id).to_def_id()) + self.mod_ids.last().copied() } else { parent_node }; @@ -842,7 +828,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { } if item.is_mod() && !item.attrs.inner_docs { - self.mod_ids.push(item_hir_id.unwrap()); + self.mod_ids.push(item.def_id); } if item.is_mod() { diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs new file mode 100644 index 0000000000000..5d63d7e37b64d --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/module.rs @@ -0,0 +1,7 @@ +#![crate_name = "module_inner"] +#![deny(intra_doc_link_resolution_failure)] +/// [SomeType] links to [bar] +pub struct SomeType; +pub trait SomeTrait {} +/// [bar] links to [SomeTrait] and also [SomeType] +pub mod bar {} diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs new file mode 100644 index 0000000000000..5c3360dc5fdb3 --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs @@ -0,0 +1,16 @@ +#![crate_name = "inner"] +/// this is a trait +pub trait SomeTrait { + /// this is a method for [SomeTrait] + fn foo(); +} + +pub mod bar { + use super::SomeTrait; + + pub struct BarStruct; + + impl SomeTrait for BarStruct { + fn foo() {} + } +} diff --git a/src/test/rustdoc/intra-doc-crate/module.rs b/src/test/rustdoc/intra-doc-crate/module.rs new file mode 100644 index 0000000000000..67fa7293f37fb --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/module.rs @@ -0,0 +1,8 @@ +// outer.rs +// aux-build: module.rs +// build-aux-docs +#![deny(intra_doc_link_resolution_failure)] +extern crate module_inner; +// @has 'module/bar/index.html' '//a[@href="../../module_inner/trait.SomeTrait.html"]' 'SomeTrait' +// @has 'module/bar/index.html' '//a[@href="../../module_inner/struct.SomeType.html"]' 'SomeType' +pub use module_inner::bar; diff --git a/src/test/rustdoc/intra-doc-crate/traits.rs b/src/test/rustdoc/intra-doc-crate/traits.rs new file mode 100644 index 0000000000000..0672c76435b9a --- /dev/null +++ b/src/test/rustdoc/intra-doc-crate/traits.rs @@ -0,0 +1,15 @@ +// aux-build:traits.rs +// build-aux-docs +// ignore-tidy-line-length +#![deny(intra_doc_link_resolution_failure)] + +extern crate inner; +use inner::SomeTrait; + +pub struct SomeStruct; + + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' +impl SomeTrait for SomeStruct { + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' + fn foo() {} +} From 0ad1dcd6a04759a20b72debae5b114751fe6c7ff Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 12 Jul 2020 12:39:11 -0400 Subject: [PATCH 17/19] Add more debugging --- src/librustdoc/passes/collect_intra_doc_links.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 76b731f62f3db..b1db1328392e7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -466,7 +466,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }; if parent_node.is_some() { - debug!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); + trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); } let current_item = match item.inner { @@ -487,7 +487,10 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { for_.def_id().map(|did| self.cx.tcx.item_name(did).to_string()) } // we don't display docs on `extern crate` items anyway, so don't process them. - ExternCrateItem(..) => return self.fold_item_recur(item), + ExternCrateItem(..) => { + debug!("ignoring extern crate item {:?}", item.def_id); + return self.fold_item_recur(item); + } ImportItem(Import::Simple(ref name, ..)) => Some(name.clone()), MacroItem(..) => None, _ => item.name.clone(), @@ -499,6 +502,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let cx = self.cx; let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); + trace!("got documentation '{}'", dox); look_for_tests(&cx, &dox, &item, true); @@ -540,6 +544,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { }); for (ori_link, link_range) in markdown_links(&dox) { + trace!("considering link '{}'", ori_link); + // Bail early for real links. if ori_link.contains('/') { continue; @@ -866,6 +872,7 @@ fn build_diagnostic( Some(hir_id) => hir_id, None => { // If non-local, no need to check anything. + info!("ignoring warning from parent crate: {}", err_msg); return; } }; From 8387e3825fa077b2c2e6d75d65592cb6c19361c1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 14 Jul 2020 20:04:41 -0400 Subject: [PATCH 18/19] Add (broken and ignored) test for #73829 --- src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs | 2 +- src/test/rustdoc/intra-doc-crate/traits.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs index 5c3360dc5fdb3..c16e39d56f3d0 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/traits.rs @@ -1,7 +1,7 @@ #![crate_name = "inner"] /// this is a trait pub trait SomeTrait { - /// this is a method for [SomeTrait] + /// this is a method for [a trait][SomeTrait] fn foo(); } diff --git a/src/test/rustdoc/intra-doc-crate/traits.rs b/src/test/rustdoc/intra-doc-crate/traits.rs index 0672c76435b9a..617331236902d 100644 --- a/src/test/rustdoc/intra-doc-crate/traits.rs +++ b/src/test/rustdoc/intra-doc-crate/traits.rs @@ -1,3 +1,5 @@ +// ignore-test +// ^ this is https://github.com/rust-lang/rust/issues/73829 // aux-build:traits.rs // build-aux-docs // ignore-tidy-line-length @@ -10,6 +12,6 @@ pub struct SomeStruct; // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' impl SomeTrait for SomeStruct { - // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'a trait' fn foo() {} } From c46e0386c5c3dcd448975cfa551b93045b013ce4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 16 Jul 2020 18:25:53 -0400 Subject: [PATCH 19/19] Fix invalid lint intra_doc_resolution_failure is not a lint. --- src/test/rustdoc-ui/intra-links-private.rs | 2 +- src/test/rustdoc/intra-doc-crate/additional_doc.rs | 2 +- src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs | 2 +- src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs | 2 +- src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs | 2 +- src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs | 2 +- src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs | 2 +- src/test/rustdoc/intra-doc-crate/basic.rs | 2 +- src/test/rustdoc/intra-doc-crate/macro.rs | 2 +- src/test/rustdoc/intra-doc-crate/submodule-inner.rs | 2 +- src/test/rustdoc/intra-doc-crate/submodule-outer.rs | 2 +- src/test/rustdoc/intra-link-prim-precedence.rs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/rustdoc-ui/intra-links-private.rs b/src/test/rustdoc-ui/intra-links-private.rs index b7906aba5b1a9..86cf9fed3dab4 100644 --- a/src/test/rustdoc-ui/intra-links-private.rs +++ b/src/test/rustdoc-ui/intra-links-private.rs @@ -1,7 +1,7 @@ // check-pass // revisions: public private // [private]compile-flags: --document-private-items -#![cfg_attr(private, deny(intra_doc_resolution_failure))] +#![cfg_attr(private, deny(intra_doc_link_resolution_failure))] /// docs [DontDocMe] //[public]~^ WARNING `[DontDocMe]` public documentation for `DocMe` links to a private item diff --git a/src/test/rustdoc/intra-doc-crate/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/additional_doc.rs index dc1d85c9941f9..adfa7f5754eb9 100644 --- a/src/test/rustdoc/intra-doc-crate/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/additional_doc.rs @@ -1,6 +1,6 @@ // aux-build:additional_doc.rs // build-aux-docs -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] extern crate my_rand; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs index 353689a6d0db2..8b8793e75ed59 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/additional_doc.rs @@ -1,5 +1,5 @@ #![crate_name = "my_rand"] -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub trait RngCore {} /// Rng extends [`RngCore`]. diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs index 8c83633424fd9..2ee5835a7df84 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/intra-doc-basic.rs @@ -1,5 +1,5 @@ #![crate_name = "a"] -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub struct Foo; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs index e54539f0bc5df..abd41fec13016 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/macro_inner.rs @@ -1,5 +1,5 @@ #![crate_name = "macro_inner"] -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub struct Foo; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs index 73073ebff1406..3a22d13e673ac 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-inner.rs @@ -1,5 +1,5 @@ #![crate_name = "a"] -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub mod bar { pub struct Bar; diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs index c045d6488f46d..b8ca4e44e1f16 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/submodule-outer.rs @@ -1,5 +1,5 @@ #![crate_name = "bar"] -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub trait Foo { /// [`Bar`] [`Baz`] diff --git a/src/test/rustdoc/intra-doc-crate/basic.rs b/src/test/rustdoc/intra-doc-crate/basic.rs index 6b6757b94e36a..a245a0f84539c 100644 --- a/src/test/rustdoc/intra-doc-crate/basic.rs +++ b/src/test/rustdoc/intra-doc-crate/basic.rs @@ -1,6 +1,6 @@ // aux-build:intra-doc-basic.rs // build-aux-docs -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] // from https://github.com/rust-lang/rust/issues/65983 extern crate a; diff --git a/src/test/rustdoc/intra-doc-crate/macro.rs b/src/test/rustdoc/intra-doc-crate/macro.rs index 5c8cec128dfa0..72fd57b6b0c7f 100644 --- a/src/test/rustdoc/intra-doc-crate/macro.rs +++ b/src/test/rustdoc/intra-doc-crate/macro.rs @@ -2,7 +2,7 @@ // aux-build:macro_inner.rs // aux-build:proc_macro.rs // build-aux-docs -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] extern crate macro_inner; extern crate proc_macro_inner; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs index e83d258c1df35..b4b615bf9edad 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-inner.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-inner.rs @@ -1,6 +1,6 @@ // aux-build:submodule-inner.rs // build-aux-docs -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] extern crate a; diff --git a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs index ccf226e1dfd03..6b30ef8b3dec8 100644 --- a/src/test/rustdoc/intra-doc-crate/submodule-outer.rs +++ b/src/test/rustdoc/intra-doc-crate/submodule-outer.rs @@ -1,6 +1,6 @@ // aux-build:submodule-outer.rs // edition:2018 -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] extern crate bar as bar_; diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs index ca83d5e2281a7..d7ebb73b3be7d 100644 --- a/src/test/rustdoc/intra-link-prim-precedence.rs +++ b/src/test/rustdoc/intra-link-prim-precedence.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -#![deny(intra_doc_resolution_failure)] +#![deny(intra_doc_link_resolution_failure)] pub mod char {}