Skip to content

Commit

Permalink
Rollup merge of rust-lang#133180 - GuillaumeGomez:jump-to-def-links-g…
Browse files Browse the repository at this point in the history
…enerics, r=notriddle

[rustdoc] Fix items with generics not having their jump to def link generated

Because the span originally included the generics, during the highlighting, it was not retrieved and therefore its jump to def link was not generated.

r? ``@notriddle``
  • Loading branch information
fmease authored Nov 19, 2024
2 parents 2226541 + 8b0f8cb commit f66e174
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/librustdoc/html/render/span_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(crate) enum LinkFromSrc {
/// It returns the `krate`, the source code files and the `span` correspondence map.
///
/// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't
/// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
/// need the `span` context later on, only their position, so instead of keeping a whole `Span`, we
/// only keep the `lo` and `hi`.
pub(crate) fn collect_spans_and_sources(
tcx: TyCtxt<'_>,
Expand All @@ -45,9 +45,9 @@ pub(crate) fn collect_spans_and_sources(
include_sources: bool,
generate_link_to_definition: bool,
) -> (FxIndexMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) {
let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };

if include_sources {
let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };

if generate_link_to_definition {
tcx.hir().walk_toplevel_module(&mut visitor);
}
Expand Down Expand Up @@ -76,7 +76,22 @@ impl<'tcx> SpanMapVisitor<'tcx> {
} else {
LinkFromSrc::External(def_id)
};
self.matches.insert(path.span, link);
// In case the path ends with generics, we remove them from the span.
let span = path
.segments
.last()
.map(|last| {
// In `use` statements, the included item is not in the path segments.
// However, it doesn't matter because you can't have generics on `use`
// statements.
if path.span.contains(last.ident.span) {
path.span.with_hi(last.ident.span.hi())
} else {
path.span
}
})
.unwrap_or(path.span);
self.matches.insert(span, link);
}
Res::Local(_) => {
if let Some(span) = self.tcx.hir().res_span(path.res) {
Expand Down
14 changes: 14 additions & 0 deletions tests/rustdoc/link-on-path-with-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This test ensures that paths with generics still get their link to their definition
// correctly generated.

//@ compile-flags: -Zunstable-options --generate-link-to-definition
#![crate_name = "foo"]

//@ has 'src/foo/link-on-path-with-generics.rs.html'

pub struct Soyo<T>(T);
pub struct Saya;

//@ has - '//pre[@class="rust"]//a[@href="#9"]' 'Soyo'
//@ has - '//pre[@class="rust"]//a[@href="#10"]' 'Saya'
pub fn bar<T>(s: Soyo<T>, x: Saya) {}

0 comments on commit f66e174

Please sign in to comment.