From 1abb7faddb406d5b40ecca39a6395957ccf9c778 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 13 Apr 2021 22:51:56 +0200 Subject: [PATCH] Generate links for modules as well --- src/librustdoc/html/render/span_map.rs | 29 +++++++++++++++---- .../rustdoc/check-source-code-urls-to-def.rs | 9 +++--- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 2895b4abfb2..6100f45e998 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId}; +use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Mod, Node}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -20,14 +20,14 @@ crate fn collect_spans_and_sources( krate: clean::Crate, src_root: &std::path::Path, include_sources: bool, - _generate_link_to_definition: bool, + generate_link_to_definition: bool, ) -> (clean::Crate, FxHashMap, FxHashMap<(u32, u32), LinkFromSrc>) { let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() }; if include_sources { - // if generate_link_to_definition { - intravisit::walk_crate(&mut visitor, tcx.hir().krate()); - // } + if generate_link_to_definition { + intravisit::walk_crate(&mut visitor, tcx.hir().krate()); + } let (krate, sources) = sources::collect_local_sources(tcx, src_root, krate); (krate, sources, visitor.matches) } else { @@ -94,6 +94,25 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> { intravisit::walk_path(self, path); } + fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) { + // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another + // file, we want to link to it. Otherwise no need to create a link. + if !span.overlaps(m.inner) { + // Now that we confirmed it's a file import, we want to get the span for the module + // name only and not all the "mod foo;". + if let Some(node) = self.tcx.hir().find(id) { + match node { + Node::Item(item) => { + self.matches + .insert(span_to_tuple(item.ident.span), LinkFromSrc::Local(m.inner)); + } + _ => {} + } + } + } + intravisit::walk_mod(self, m, id); + } + fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) { match expr.kind { ExprKind::MethodCall(segment, method_span, _, _) => { diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs index 32973ba3faf..5caef29fede 100644 --- a/src/test/rustdoc/check-source-code-urls-to-def.rs +++ b/src/test/rustdoc/check-source-code-urls-to-def.rs @@ -2,11 +2,12 @@ #![crate_name = "foo"] +// @has 'src/foo/check-source-code-urls-to-def.rs.html' + +// @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#1-17"]' 'bar' #[path = "auxiliary/source-code-bar.rs"] pub mod bar; -// @has 'src/foo/check-source-code-urls-to-def.rs.html' - // @count - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#5-7"]' 4 use bar::Bar; // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#13-17"]' 'self' @@ -22,13 +23,13 @@ impl Foo { fn babar() {} // @has - '//a[@href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html"]' 'String' -// @count - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#16"]' 5 +// @count - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#17"]' 5 pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar) { let x = 12; let y: Foo = Foo; let z: Bar = bar::Bar { field: Foo }; babar(); - // @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#19"]' 'hello' + // @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#20"]' 'hello' y.hello(); }