Skip to content

Fix ICE in rustdoc when impl is nested in a func#147911

Closed
GoldsteinE wants to merge 1 commit into
rust-lang:mainfrom
GoldsteinE:fix/rustdoc-ice-147882
Closed

Fix ICE in rustdoc when impl is nested in a func#147911
GoldsteinE wants to merge 1 commit into
rust-lang:mainfrom
GoldsteinE:fix/rustdoc-ice-147882

Conversation

@GoldsteinE
Copy link
Copy Markdown
Contributor

@GoldsteinE GoldsteinE commented Oct 20, 2025

For cases like

fn foo() {
    impl<E> Trait for Bar<E>
    where E: Baz {}
}

hir_enclosing_body_owner() in rustdoc considered fn foo() to be the “enclosing body” of E, which caused to to produce HirIds for E with owner set to fn foo() instead of the impl. This instead treats E as having no enclosing body.

r? @GuillaumeGomez as the author of this logic, I’m not 100% I understood it correctly.

Fixes #147882.
Fixes #147057.

@rustbot rustbot added 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. labels Oct 20, 2025
@GoldsteinE GoldsteinE force-pushed the fix/rustdoc-ice-147882 branch from 206b202 to fed595d Compare October 20, 2025 15:24
@GuillaumeGomez
Copy link
Copy Markdown
Member

I'll side step here and let @fmease review this as they're the expert of this topic.

r? fmease

@rustbot rustbot assigned fmease and unassigned GuillaumeGomez Oct 20, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Oct 20, 2025

fmease is currently at their maximum review capacity.
They may take a while to respond.

@fmease
Copy link
Copy Markdown
Member

fmease commented Oct 20, 2025

Haven't looked at the impl yet; I guess this also fixes #147057 cuz #147882 is likely a dupe of the former?

@GoldsteinE
Copy link
Copy Markdown
Contributor Author

I’ve checked this, and yes, it fixes #147057. Updated the top post accordingly.

@GoldsteinE GoldsteinE force-pushed the fix/rustdoc-ice-147882 branch from fed595d to aec6f97 Compare October 20, 2025 16:14
Copy link
Copy Markdown
Member

@camelid camelid left a comment

Choose a reason for hiding this comment

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

Thanks for looking into this! I suspect a more principled fix would be to get rid of this function and use tcx.typeck(tcx.hir_get_parent_item(hir_id).def_id) at its call-sites instead of tcx.typeck_body(<result of this func>). Could you try that instead and see if that works?

View changes since this review

@rustbot rustbot 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-review Status: Awaiting review from the assignee but also interested parties. labels Nov 9, 2025
@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Nov 9, 2025

For context: I recently had a conversation with @fmease, and they mentioned they're planning to refactor or revise this part of the code, which they had approved in the review. So, I think we should wait for their input on this matter

@fmease
Copy link
Copy Markdown
Member

fmease commented Nov 9, 2025

@camelid, typeck also only works on things with bodies. But I agree that a more principled approach should be chosen, I just didn't have the time to investigate what would be best in order to propose something here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please move this test to tests/rustdoc/jump-to-def/

@fmease
Copy link
Copy Markdown
Member

fmease commented Nov 9, 2025

@camelid, typeck also only works on things with bodies. But I agree that a more principled should be chosen, I just didn't have the time to investigate what would be best in order to propose something here.

In general, we currently can't obtain the resolution (DefId) of arbitrary type-relative things given the HIR alone. Namely of ones located in non-bodies / item signatures / places where we don't perform type inference. For bodies we have typeck but for non-bodies we would only have HIR ty lowering (which we certainly don't want to do again) or ditching the HIR and going through the rustc_middle::ty::Ty provided by type_of (which is lossy as long as we don't have lazy type aliases by default).

It's been a while since I looked at this part of the code but yeah for now it's okay to ignore TypeRelative QPaths "in ItemCtxts" … which this PR + other parts of the code kinda do but I'm certain it can be expressed a lot more robustly and nicely.

Also CC this beautiful table I've created: #135771 (comment).

@camelid
Copy link
Copy Markdown
Member

camelid commented Nov 9, 2025

@camelid, typeck also only works on things with bodies. But I agree that a more principled should be chosen, I just didn't have the time to investigate what would be best in order to propose something here.

In general, we currently can't obtain the resolution (DefId) of arbitrary type-relative things given the HIR alone. Namely of ones located in non-bodies / item signatures / places where we don't perform type inference. For bodies we have typeck but for non-bodies we would only have HIR ty lowering (which we certainly don't want to do again) or ditching the HIR and going through the rustc_middle::ty::Ty provided by type_of (which is lossy as long as we don't have lazy type aliases by default).

It's been a while since I looked at this part of the code but yeah for now it's okay to ignore TypeRelative QPaths "in ItemCtxts" … which this PR + other parts of the code kinda do but I'm certain it can be expressed a lot more robustly and nicely.

Also CC this beautiful table I've created: #135771 (comment).

Ah, right, I forgot about this annoyance.... Do you know what we currently do to resolve QPaths in the rest of rustdoc (not jump-to-def)? E.g. when rendering types that are trait assoc items etc.

@theemathas
Copy link
Copy Markdown
Contributor

Does this also fix #149089 and #150153?

@Dylan-DPC
Copy link
Copy Markdown
Member

@GoldsteinE any updates on this? thanks

@fmease
Copy link
Copy Markdown
Member

fmease commented May 10, 2026

(not the author) I'm currently working on an alternative fix.

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%)
...|...|...|...|...|...|...|...
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 13, 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. Fixes rust-lang#156418.
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%)
...|...|...|...|...|...|...|...
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 13, 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. Fixes rust-lang#156418.
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%)
...|...|...|...|...|...|...|...
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 13, 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. Fixes rust-lang#156418.
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-timer added a commit that referenced this pull request May 14, 2026
Rollup merge of #156413 - fmease:rustdoc-ltd-improvs, r=GuillaumeGomez

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 #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?...](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
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 14, 2026

☔ The latest upstream changes (presumably #156559) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez
Copy link
Copy Markdown
Member

Superseeded by #156413 so closing. Thanks a lot @GoldsteinE!

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Development

Successfully merging this pull request may close these issues.

Internal compiler error when building docs for serde_with@3.14.1 on nightly rustdoc: ICE: [trying to look up a HirId in the wrong context]

8 participants