Skip to content

rustdoc_json: improve handling of generic args #142502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

nnethercote
Copy link
Contributor

This PR fixes some inconsistencies and inefficiencies in how generic args are handled by rustdoc-json-types.

r? @aDotInTheVoid

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend 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. labels Jun 14, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 14, 2025

rustdoc-json-types is a public (although nightly-only) API. If possible, consider changing src/librustdoc/json/conversions.rs; otherwise, make sure you bump the FORMAT_VERSION constant.

cc @CraftSpider, @aDotInTheVoid, @Enselic, @obi1kenobi

@nnethercote
Copy link
Contributor Author

Local measurements indicate some sub-1% instruction count improvements, and some max-rss improvements of up to 2%.

@bors
Copy link
Collaborator

bors commented Jun 15, 2025

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

@nnethercote nnethercote force-pushed the rustdoc-json-GenericArgs branch from f232c4e to 27eee69 Compare June 15, 2025 04:17
Copy link
Member

@aDotInTheVoid aDotInTheVoid left a comment

Choose a reason for hiding this comment

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

Behavioral changes make sense, but all of them needs tests.

They live in tests/rustdoc-json. Sadly, I've not finished the docs for it yet (rust-lang/rustc-dev-guide#2422), but there's a draft here

type/generic_default.rs and gats.rs are probably good examples

@aDotInTheVoid aDotInTheVoid 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 Jun 15, 2025
A lot of these are large! Lots of room for improvement in the future.
A path without generic args, like `Reader`, currently has JSON produced
like this:
```
{"path":"Reader","id":286,"args":{"angle_bracketed":{"args":[],"constraints":[]}}}
```
Even though `types::Path::args` is `Option` and allows for "no args",
instead it gets represented as "empty args". (More like `Reader<>` than
`Reader`.)

This is due to a problem in `clean::Path::from_clean`. It only produces
`None` if the path is an empty string. This commit changes it to also
produce `None` if there are no generic args. The example above becomes:
```
{"path":"Reader","id":286,"args":null}
```
I looked at a few examples and saw this reduce the size of the JSON
output by 3-9%.

The commit also adds an assertion that non-final segments don't have any
generics; something the old code was implicitly relying on.

Note: the original sin here is that `clean::PathSegment::args` is not an
`Option`, unlike `{ast,hir}::PathSegment::args`. I want to fix that, but
it can be done separately.
As per the previous commit, generic args here can only appear on the
final segment. So make the comments obey that constraint.
They show up in three places: once as `Option<Box<GenericArgs>>`, once
as `Box<GenericArgs>`, and once as `GenericArgs`. The first option is
best. It is more compact because generic args are often missing. This
commit changes the latter two to the former.

Example output, before and after, for the `AssocItemConstraint` change:
```
{"name":"Offset","args":{"angle_bracketed":{"args":[],"constraints":[]}},"binding":{...}}
{"name":"Offset","args":null,"binding":{...}}
```
Example output, before and after, for the `Type::QualifiedPath` change:
```
{"qualified_path":{"name":"Offset","args":{"angle_bracketed":{"args":[],"constraints":[]}}, ...}}
{"qualified_path":{"name":"Offset","args":null, ...}}
```
This reduces JSON output size, but not by much (e.g. 0.5%), because
`AssocItemConstraint` and `Type::QualifiedPath` are uncommon.
@nnethercote nnethercote force-pushed the rustdoc-json-GenericArgs branch from 27eee69 to f3c20ca Compare June 16, 2025 00:10
@rustbot
Copy link
Collaborator

rustbot commented Jun 16, 2025

These commits modify tests/rustdoc-json.
rustdoc-json is a public (but unstable) interface.

Please ensure that if you've changed the output:

  • It's intentional.
  • The FORMAT_VERSION in src/librustdoc-json-types is bumped if necessary.

cc @aDotInTheVoid, @obi1kenobi

@nnethercote
Copy link
Contributor Author

I added a test as a separate commit early in the sequence, so the changes to GenericArgs are visible in the changes to the test.

@rustbot ready

@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 Jun 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustdoc-json Area: Rustdoc JSON backend 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants