Skip to content

feat(rustdoc-json): Add optional support for rkyv (de)serialization#153283

Open
LukeMathWalker wants to merge 1 commit intorust-lang:mainfrom
LukeMathWalker:add-rkyv-support
Open

feat(rustdoc-json): Add optional support for rkyv (de)serialization#153283
LukeMathWalker wants to merge 1 commit intorust-lang:mainfrom
LukeMathWalker:add-rkyv-support

Conversation

@LukeMathWalker
Copy link
Contributor

Motivation

The JSON documents produced by rustdoc-json are big. More often than not, tools need to access a small fraction of that output—e.g. a couple of types from a transitive dependency, or a subset of the fields on a given rustdoc-json-types type.

Using a binary (de)serialization format and a cache helps to drive down the performance cost of deserialization: you invoke rustdoc-json to get the JSON output you need, re-serialize it using a more perfomant format as target (e.g. bincode or postcard) and thus amortize the cost of future queries that hit the persistent cache rather than rustdoc-json.
This is better, but still not great: the deserialization cost for crates like std still shows up prominently in flamegraphs.

An Alternative Approach: rkyv

rkyv provides a different opportunity: you avoid paying the deserialization cost upfront thanks to zero-copy deserialization.
You're often able to determine if you need a certain entry from the JSON document using the archived version of that type, thus incurring the full deserialization cost only for the subset of items you actually need (example).

The Change

This PR adds support for rkyv behind a feature flag (rkyv_0_8).
For most types, it's a straight-forward derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) annotation. For co-recursive types, we need to adjust the generated bounds, using the techniques from rkyv's JSON example.

I have added new round-trip tests to ensure rkyv works as expected.

r? @aDotInTheVoid

@rustbot
Copy link
Collaborator

rustbot commented Mar 2, 2026

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

@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 Mar 2, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 2, 2026

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

@rust-log-analyzer

This comment has been minimized.

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.

This makes sense as a thing to add.

View changes since this review


#[cfg(feature = "rkyv_0_8")]
mod rkyv {
use std::fmt::Debug;
Copy link
Member

Choose a reason for hiding this comment

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

These tests don't run. When I applied

diff --git a/src/rustdoc-json-types/tests.rs b/src/rustdoc-json-types/tests.rs
index e878350e43b..258c22304c3 100644
--- a/src/rustdoc-json-types/tests.rs
+++ b/src/rustdoc-json-types/tests.rs
@@ -41,6 +41,11 @@ fn test_union_info_roundtrip() {

 #[cfg(feature = "rkyv_0_8")]
 mod rkyv {
+    #[test]
+    fn definenly_fails() {
+        panic!("at least the rkyv tests were ran");
+    }
+
     use std::fmt::Debug;

     use rkyv::Archive;

Running ./x test ./src/rustdoc-json-types/ still passed.

The fix (I think) is to enable this feature in bootsrap:

diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 88f10775333..ab1d2b8a24b 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3302,7 +3302,7 @@ fn run(self, builder: &Builder<'_>) {
             builder.kind,
             "src/rustdoc-json-types",
             SourceType::InTree,
-            &[],
+            &["rkyv_0_8".to_owned()],
         );

         // FIXME: this looks very wrong, libtest doesn't accept `-C` arguments and the quotes are fishy.

(CC @jieyouxu, is this ok to do?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apologies, I had only tested the crate directly via local cargo test, under the implicit assumption that the testing infrastructure would automatically pick up feature flags for matrix testing.
I've added the feature flag to the bootstrap script, let me know if other changes are needed.

@aDotInTheVoid
Copy link
Member

@rustbot author

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 3, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 3, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Mar 3, 2026
@LukeMathWalker
Copy link
Contributor Author

@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 Mar 3, 2026
@rust-log-analyzer

This comment has been minimized.

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.

Thanks, I hope this helps perf.

r=me with commits squashed, and when someone from T-bootstrap signs off that 39f7f0d is ok.

View changes since this review

@LukeMathWalker
Copy link
Contributor Author

Commits have been squashed @aDotInTheVoid. What's the best way to get a reviewer from T-bootstrap (or is your tag in the thread enough)?

@aDotInTheVoid
Copy link
Member

I asked on zulip (#t-infra/bootstrap > Review Request: Adding a feature in a test step.). Seems fine. (Sorry, I should've made that clear here).

@bors r+ rollup

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 9, 2026

📌 Commit 1d81c50 has been approved by aDotInTheVoid

It is now in the queue for this repository.

@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 Mar 9, 2026
aDotInTheVoid added a commit to aDotInTheVoid/rustdoc-types-contrib that referenced this pull request Mar 9, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 9, 2026
…=aDotInTheVoid

feat(rustdoc-json): Add optional support for rkyv (de)serialization

## Motivation

The JSON documents produced by `rustdoc-json` are _big_. More often than not, tools need to access a small fraction of that output—e.g. a couple of types from a transitive dependency, or a subset of the fields on a given `rustdoc-json-types` type.

Using a binary (de)serialization format and a cache helps to drive down the performance cost of deserialization: you invoke `rustdoc-json` to get the JSON output you need, re-serialize it using a more perfomant format as target (e.g. `bincode` or `postcard`) and thus amortize the cost of future queries that hit the persistent cache rather than `rustdoc-json`.
This is _better_, but still not great: the deserialization cost for crates like `std` still shows up prominently in flamegraphs.

## An Alternative Approach: rkyv

`rkyv` provides a different opportunity: you avoid paying the deserialization cost _upfront_ thanks to [zero-copy deserialization](https://rkyv.org/zero-copy-deserialization.html).
You're often able to determine if you need a certain entry from the JSON document using the archived version of that type, thus incurring the full deserialization cost only for the subset of items you actually need ([example](LukeMathWalker/pavex@d067e7e)).

## The Change

This PR adds support for `rkyv` behind a feature flag (`rkyv_0_8`).
For most types, it's a straight-forward `derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)` annotation. For co-recursive types, we need to adjust the generated bounds, using the techniques from [`rkyv`'s JSON example](https://github.com/rkyv/rkyv/blob/985b0230a0b9cb9fce4a4ee9facb6af148e27c8e/rkyv/examples/json_like_schema.rs).

I have added new round-trip tests to ensure `rkyv` works as expected.

r? @aDotInTheVoid
aDotInTheVoid added a commit to aDotInTheVoid/rustdoc-types-contrib that referenced this pull request Mar 9, 2026
aDotInTheVoid added a commit to aDotInTheVoid/rustdoc-types-contrib that referenced this pull request Mar 9, 2026
rust-bors bot pushed a commit that referenced this pull request Mar 9, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #153283 (feat(rustdoc-json): Add optional support for rkyv (de)serialization)
 - #153608 (ast_passes: unsupported arch w/ scalable vectors)
 - #153616 (Update `sysinfo` version to `0.38.4`)
 - #153619 (Update books)
 - #153624 (Ping fmease on parser modifications)
@JonathanBrouwer
Copy link
Contributor

@bors r-
#153625 (comment)

@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 Mar 9, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 9, 2026

This pull request was unapproved.

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

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 A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) 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.

5 participants