Skip to content

rustdoc: Correctness & perf improvements to link-to-definition#156413

Open
fmease wants to merge 6 commits into
rust-lang:mainfrom
fmease:rustdoc-ltd-improvs
Open

rustdoc: Correctness & perf improvements to link-to-definition#156413
fmease wants to merge 6 commits into
rust-lang:mainfrom
fmease:rustdoc-ltd-improvs

Conversation

@fmease
Copy link
Copy Markdown
Member

@fmease fmease commented May 10, 2026

Rewrite the way we resolve type-dependent paths (incl. method calls) in SpanMapVisitor. Instead of trying to (re)find the enclosing body owner each time we encounter such a node, potentially calling typeck_body several times per body, keep track of the "active" BodyId in the visitor and cache the corresponding TypeckResults. The "active" BodyId is updated in visit_nested_body (add) and in visit_item (remove).

This fixes a class of ICEs where we tried to look up the definition of type-relative paths located in non-body items nested in bodies, in the overarching body which is never correct. rustdoc@main has a hack to fix this issue for paths specifically found in assoc types in impls.

Fixes #147882. Fixes #147057. Fixes #155327. Fixes #149089. Fixes #150153. Fixes #156418.
Supersedes #147911.


--generate-link-to-definition is not enabled by default, so we can't perf this as is. Instead, I'm benching them against PR #156348 in PR #156355 using the same parent commit for the try-builds. For context, LTD is extremely costly as the perf run for the baseline PR shows: #156348 (comment).

"Absolute results": #156355 (comment).
"Relative results": https://perf.rust-lang.org/compare.html?....

Excerpt of the relative results:

Primary:

Benchmark Profile Scenario Backend Target % Change Significance Threshold Significance Factor
nalgebra-0.33.0 doc full llvm x64 -5.82% 0.20% 29.09x
diesel-2.2.10 doc full llvm x64 -3.41% 0.20% 17.05x
image-0.25.6 doc full llvm x64 -2.03% 0.20% 10.16x
regex-automata-0.4.8 doc full llvm x64 -1.94% 0.20% 9.71x
cargo-0.87.1 doc full llvm x64 -1.64% 0.20% 8.21x
clap_derive-4.5.32 doc full llvm x64 -1.63% 0.20% 8.14x
cranelift-codegen-0.119.0 doc full llvm x64 -1.48% 0.20% 7.41x
syn-2.0.101 doc full llvm x64 -1.07% 0.20% 5.35x
ripgrep-14.1.1 doc full llvm x64 -0.96% 0.20% 4.78x
stm32f4-0.15.1 doc full llvm x64 -0.80% 0.20% 4.01x
serde-1.0.219 doc full llvm x64 -0.67% 0.20% 3.33x
hyper-1.6.0 doc full llvm x64 -0.66% 0.20% 3.30x
eza-0.21.2 doc full llvm x64 -0.55% 0.20% 2.74x
unicode-normalization-0.1.24 doc full llvm x64 -0.49% 0.20% 2.45x
serde_derive-1.0.219 doc full llvm x64 -0.45% 0.20% 2.26x
typenum-1.18.0 doc full llvm x64 -0.42% 0.20% 2.08x
bitmaps-3.2.1 doc full llvm x64 -0.32% 0.20% 1.61x

Secondary:

Benchmark Profile Scenario Backend Target % Change Significance Threshold Significance Factor
deep-vector doc full llvm x64 -23.96% 0.20% 119.78x
large-workspace doc full llvm x64 -2.16% 0.20% 10.81x
deeply-nested-multi doc full llvm x64 -1.35% 0.20% 6.75x
serde-1.0.219-threads4 doc full llvm x64 -0.67% 0.20% 3.33x
wg-grammar doc full llvm x64 -0.32% 0.20% 1.62x
tt-muncher opt full llvm x64 -0.31% 0.20% 1.56x

nalgebra-0.33.0:

Query/Function Time (%) Time (s) Time delta Executions Executions delta Hits Hits delta
Totals 109.57% 2.185 -0.138 (-5.9%) 1614146 -5602 (-0.3%) 16983840 -1436455 (-7.8%)
typeck_root 15.75% 0.344 -0.105 (-23.4%) 1704 -954 (-35.9%) 393 -6758 (-94.5%)
... ... ... ... ... ... ... ...

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels May 10, 2026
@fmease fmease force-pushed the rustdoc-ltd-improvs branch from 710fac1 to 359b42c Compare May 10, 2026 19:02
Comment thread src/librustdoc/html/render/span_map.rs Outdated
@GuillaumeGomez
Copy link
Copy Markdown
Member

Thanks! Please ping me once ready for review. :)

@rust-log-analyzer

This comment has been minimized.

@fmease fmease force-pushed the rustdoc-ltd-improvs branch 4 times, most recently from 73d1fc8 to 79a5881 Compare May 12, 2026 20:05
@fmease fmease changed the title [WIP] rustdoc: Correctness & perf improvements to link-to-definition rustdoc: Correctness & perf improvements to link-to-definition May 12, 2026
@fmease fmease marked this pull request as ready for review May 12, 2026 20:18
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 12, 2026
@@ -653,6 +653,15 @@ add the `--scrape-tests` flag.
This flag enables the generation of links in the source code pages which allow the reader
to jump to a type definition.

Copy link
Copy Markdown
Member Author

@fmease fmease May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just documenting pre-existing behavior.

View changes since the review

type X;
}

pub struct F<T: C>(pub T::X);
Copy link
Copy Markdown
Member Author

@fmease fmease May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test file is no longer necessary. You added this regression test for an ICE I reported during review (#135771 (comment)) but now assoc-items.rs tests this case among myriads of others (see "tag" Item, AssocTy, TypeRelative).

View changes since the review

Copy link
Copy Markdown
Member Author

@fmease fmease May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

superseded by tests/rustdoc-ui/generate-link-to-definition/items-nested-in-bodies.rs

View changes since the review

@fmease
Copy link
Copy Markdown
Member Author

fmease commented May 12, 2026

@GuillaumeGomez, ready for review. Best reviewed commit by commit. See the PR description for details about the perf improvements.

Copy link
Copy Markdown
Member Author

@fmease fmease May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really horrible diff, I'm sorry. I fully replaced this file, better look at the source directly.

View changes since the review

Comment on lines -29 to -31
// These two links must not change and in particular must contain `/derive.`!
//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug'
//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq'
Copy link
Copy Markdown
Member Author

@fmease fmease May 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already gets tested here:

//@ has - '//a[@href="{{channel}}/core/fmt/macros/derive.Debug.html"]' 'Debug'
//@ has - '//a[@href="{{channel}}/core/cmp/derive.PartialEq.html"]' 'PartialEq'

View changes since the review

@GuillaumeGomez
Copy link
Copy Markdown
Member

This is a much smaller change than I expected. Looks all good to me, thanks! Feel free to r+ if the PR is ready. =D

@fmease
Copy link
Copy Markdown
Member Author

fmease commented May 12, 2026

It's ready :) @bors r=GuillaumeGomez rollup (unstable, gated behind flag, perf change not observable)

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 12, 2026

📌 Commit 79a5881 has been approved by GuillaumeGomez

It is now in the queue for this repository.

🌲 The tree is currently closed for pull requests below priority 1000. This pull request will be tested once the tree is reopened.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 12, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 12, 2026
…laumeGomez

rustdoc: Correctness & perf improvements to link-to-definition

Rewrite the way we resolve type-dependent paths (incl. method calls) in `SpanMapVisitor`. Instead of trying to (re)find the enclosing body owner each time we encounter such a node, potentially calling `typeck_body` several times per body, keep track of the "active" `BodyId` in the visitor and cache the corresponding `TypeckResults`. The "active" `BodyId` is updated in `visit_nested_body` (add) and in `visit_item` (remove).

This fixes a class of ICEs where we tried to look up the definition of type-relative paths located in non-body items nested in bodies, in the overarching body which is never correct. rustdoc@main has a hack to fix this issue for paths specifically found in assoc types in impls.

Fixes rust-lang#147882. Fixes rust-lang#147057. Fixes rust-lang#155327. Fixes rust-lang#149089. Fixes rust-lang#150153.
Supersedes rust-lang#147911.

---

`--generate-link-to-definition` is not enabled by default, so we can't perf this as is. Instead, I'm benching them against PR rust-lang#156348 in PR rust-lang#156355 using the same parent commit for the try-builds. For context, LTD is *extremely* costly as the perf run for the baseline PR shows: rust-lang#156348 (comment).

"Absolute results": rust-lang#156355 (comment).
"Relative results": [https://perf.rust-lang.org/compare.html?...](https://perf.rust-lang.org/compare.html?start=68c2bff6cb08a87e59246064a6a9f37098e22c3f&end=78d15de5525370011388c8f63847e873c4de14ed&stat=instructions%3Au).

Excerpt of the relative results:

Primary:

Benchmark | Profile | Scenario | Backend | Target | % Change | Significance Threshold | Significance Factor
---|---|---|---|---|---|---|---
nalgebra-0.33.0 | doc | full | llvm | x64 | -5.82% | 0.20% | 29.09x
diesel-2.2.10 | doc | full | llvm | x64 | -3.41% | 0.20% | 17.05x
image-0.25.6 | doc | full | llvm | x64 | -2.03% | 0.20% | 10.16x
regex-automata-0.4.8 | doc | full | llvm | x64 | -1.94% | 0.20% | 9.71x
cargo-0.87.1 | doc | full | llvm | x64 | -1.64% | 0.20% | 8.21x
clap_derive-4.5.32 | doc | full | llvm | x64 | -1.63% | 0.20% | 8.14x
cranelift-codegen-0.119.0 | doc | full | llvm | x64 | -1.48% | 0.20% | 7.41x
syn-2.0.101 | doc | full | llvm | x64 | -1.07% | 0.20% | 5.35x
ripgrep-14.1.1 | doc | full | llvm | x64 | -0.96% | 0.20% | 4.78x
stm32f4-0.15.1 | doc | full | llvm | x64 | -0.80% | 0.20% | 4.01x
serde-1.0.219 | doc | full | llvm | x64 | -0.67% | 0.20% | 3.33x
hyper-1.6.0 | doc | full | llvm | x64 | -0.66% | 0.20% | 3.30x
eza-0.21.2 | doc | full | llvm | x64 | -0.55% | 0.20% | 2.74x
unicode-normalization-0.1.24 | doc | full | llvm | x64 | -0.49% | 0.20% | 2.45x
serde_derive-1.0.219 | doc | full | llvm | x64 | -0.45% | 0.20% | 2.26x
typenum-1.18.0 | doc | full | llvm | x64 | -0.42% | 0.20% | 2.08x
bitmaps-3.2.1 | doc | full | llvm | x64 | -0.32% | 0.20% | 1.61x

Secondary:

Benchmark | Profile | Scenario | Backend | Target | % Change | Significance Threshold | Significance Factor
---|---|---|---|---|---|---|---
deep-vector | doc | full | llvm | x64 | -23.96% | 0.20% | 119.78x
large-workspace | doc | full | llvm | x64 | -2.16% | 0.20% | 10.81x
deeply-nested-multi | doc | full | llvm | x64 | -1.35% | 0.20% | 6.75x
serde-1.0.219-threads4 | doc | full | llvm | x64 | -0.67% | 0.20% | 3.33x
wg-grammar | doc | full | llvm | x64 | -0.32% | 0.20% | 1.62x
tt-muncher | opt | full | llvm | x64 | -0.31% | 0.20% | 1.56x

nalgebra-0.33.0:

Query/Function | Time (%) | Time (s) | Time delta | Executions | Executions delta | Hits | Hits delta
---|---|---|---|---|---|---|---
Totals | 109.57% | 2.185 | -0.138 (-5.9%) | 1614146 | -5602 (-0.3%) | 16983840 | -1436455 (-7.8%)
typeck_root | 15.75% | 0.344 | -0.105 (-23.4%) | 1704 | -954 (-35.9%) | 393 | -6758 (-94.5%)
...|...|...|...|...|...|...|...
rust-bors Bot pushed a commit that referenced this pull request May 12, 2026
…uwer

Rollup of 3 pull requests

Successful merges:

 - #156504 (bootstrap: remap windows-style OUT_DIR paths)
 - #156325 (Don't treat const param default as projection)
 - #156413 (rustdoc: Correctness & perf improvements to link-to-definition)
@fmease
Copy link
Copy Markdown
Member Author

fmease commented May 13, 2026

Apparently I need to fix #156418 here, so we can document std again; it's more trigger-happy now that we call typeck fewer times.

@fmease
Copy link
Copy Markdown
Member Author

fmease commented May 13, 2026

@bors r-

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 13, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 13, 2026

This pull request was unapproved.

This PR was contained in a rollup (#156514), which was unapproved.

View changes since this unapproval

fmease added 5 commits May 13, 2026 03:51
…e it always is

`rustc_resolve` doesn't resolve type-relative paths since that's the job
of HIR ty lowering and HIR typeck. `segment.res` comes from
`rustc_resolve` and is thus always `Res::Err`.
So just try to obtain the `TypeckResults` immediately since they contain
the actual resolution as deduced by HIR typeck.
Don't unnecessarily try to obtain the type-dependent definition of callees
in `visit_expr`, just let `visit_qpath` handle callees.
This means that for callees that are

* `Resolved` paths (the majority of callees) we don't try to `typeck` the
  enclosing body which should improve perf if the body doesn't contain
  any type-dependent definitions.
* actually `TypeRelative` paths we don't resolve them twice (with
  slightly different spans)
@fmease fmease force-pushed the rustdoc-ltd-improvs branch from 79a5881 to 96b43c6 Compare May 13, 2026 01:51
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 13, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 13, 2026

⚠️ A new commit 96b43c65c708566e679761ec3a874cef6d50c3b0 was pushed.

This PR was contained in a rollup (#156514), which was closed.

@fmease fmease force-pushed the rustdoc-ltd-improvs branch from 96b43c6 to e205784 Compare May 13, 2026 01:56
@fmease fmease added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

4 participants