-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for RFC 2963: rustdoc JSON backend #76578
Comments
cc @P1n3appl3 if you want to help fill in substeps for the tracking issue and/or help implement them |
Implemented in #79539 |
@rustbot modify labels: A-rustdoc-json |
=== stdout === === stderr === error: the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see rust-lang/rust#76578) ==============
=== stdout === === stderr === error: the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see rust-lang/rust#76578) ==============
This comment was marked as off-topic.
This comment was marked as off-topic.
triagebot.yml: CC Enselic when rustdoc-json-types changes Being the maintainer of [cargo-public-api](https://github.com/Enselic/cargo-public-api) which relies on [rustdoc JSON](rust-lang#76578) means I have high stakes in the rustdoc JSON format itself. Would be great if I could be pinged when the format is about to change. I hope this is OK. Big thanks in advance.
Some blocker's from zulip discussion:
|
A quick note for users who want to try this feature: cargo nightly rustdoc --lib -p <your-package> -- -Z unstable-options --output-format json |
I notice that the output from this doesn't include items in stdlib (just references to them), just like the old -Zsave-analysis feature. With -Zsave-analysis, you could get the stdlib analysis from the |
There's a nightly-only component called
Depending on the details of your use case, it's also possible that some of the machinery that powers |
My usecase is rsbrowse, a TUI interactive code browser. I implemented it using -Zsave-analysis (so currently it doesn't work, unless you can point it at a really old compiler), and the rustdoc json output seems like a perfect replacement for that. I had initially tried replacing it with rust-analyzer's LSIF output, but that's primarily intended for going from source code text -> type info, whereas I really want the reverse, and it's not good for that. |
Very cool! I hadn't heard of rsbrowse before. I think rsbrowse and cargo-semver-checks run into the exact same combination of issues: resolving and querying items, which are possibly across crate boundaries, and then pointing to specific bits of code as needed (whether to explore or to flag a semver issue). I'm hopeful that they might be able to share a solution as well, if you're interested! I recently gave a talk on the architecture behind In any case, I have quite a bit of experience with rustdoc JSON, including how to minimize the amount of work needed to stay up to date on rustdoc format versions which change rather frequently — on average, ~once per Rust release. There's also a limitation in rustdoc JSON at the moment that makes it somewhat challenging to resolve items across crate boundaries, but I think it's surmountable. Give me a ping if I can help, or if you're interested in building atop some of the same infrastructure that powers cargo-semver-checks and our playground! |
I took a couple days and reimplemented One problem I've found so far is that the stdlib files seem to be missing things EDIT: I just realized, it's probably because the stdlib files were generated without There also doesn't seem to be a way to get it to generate json for build-dependencies like I'm also not sure how it handles multiple versions of a crate in a dependency tree. But overall, for me, this feature is like 95% perfect, and I can pretty easily work around the remaining rough edges. I'm very happy with the data format! example errors showing missing paths in `core`
|
Agree with @wfraser, I've been doing a big re-write of my code gen crate, and took the time to properly crawl the output for things I am interested in. My biggest issue so far is cross-crate lookups, my use case requires analyzing this json from multiple crates and then trying to match them up - specifically traits and their impls across crates. Everything works fine inside the one local crate, but ID's are not stable across multiple crates (actually sometimes they seem to line up, but not always), this means that if I have an Item for which I only have the This lets me generate public import paths in code gen. It would be nice to have some sort of stable ID which works across crates, maybe a combination of crate name and the ID |
AFAIK there's currently no guaranteed way to resolve cross-crate imports across multiple versions of the same crate. This is why cargo-semver-checks doesn't support cross-crate analysis at the moment. I believe @LukeMathWalker was looking into adding a way to reliably look up items across crate boundaries. At the moment I can't seem to find the link to the thread where that was discussed, so I'm not sure what the status on that is. |
My strategy to overcome this limitation relies on rust-lang/compiler-team#635 (or some variations of it) landing. |
See the first section of #106697, for what I want to eventually do on this. (And more broadly, don't bet on anything in that issue getting finished this year, it's been alot) |
It seems that inner items, such as For instance, if we have this code: struct MyStruct {
my_field: u64,
} we will get this json (some fields omitted for brevity): {
"index": {
"0:5:1777": {
"id": "0:5:1777",
"name": "my_field",
"inner": { "struct_field": { "primitive": "u64" } }
},
"0:4:1776": {
"id": "0:4:1776",
"name": "MyStruct",
"inner": { "struct": { "kind": { "plain": { "fields": [ "0:5:1777" ] } } } }
}
},
"paths": {
"0:4:1776": {
"path": [ "foo", "MyStruct"],
"kind": "struct"
}
},
"format_version": 28
} Note that there is no path for Ideally we would have the field in {
"index": {
"0:5:1777": {
"id": "0:5:1777",
"name": "my_field",
"parent": "0:4:1776"
},
"0:4:1776": {
"id": "0:4:1776",
"name": "MyStruct",
}
}
} That would also make it easy to go from field to the corresponding Of course, in an ideal world, we would have both: inner item paths in |
👋 I'm the maintainer of Unfortunately, I think that
This is inherent complexity in the domain, and I don't think rustdoc JSON will be able to handle it for us. The way I've already implemented and thoroughly tested all this logic, and I'd be happy to help you get started with it if you're open to trying it out! P.S.: |
Thanks @obi1kenobi for your answer. I wasn't aware the number of path could explode and even be infinite. I also wasn't aware of the trustfall query language: it seem that it might be useful for what I'm doing (thanks for creating that!). Given this information, I want to change my suggestion to something a bit more selfish (because it more directly solves my problem). Since an {
"index": {
"0:0:1779": {
"links": {
"MyStruct::my_field": "0:5:1777"
}
}
}
} we could have {
"index": {
"0:0:1779": {
"links": {
"MyStruct::my_field": { "id": "0:5:1777", "path": ["foo", "MyStruct", "my_field"] }
}
}
}
} (An even more selfish suggestion would be for the html link to be part of |
(Again speaking in a purely personal capacity.) Both suggestions have the effect of increasing the file size in order to denormalize the format. It's a denormalization because this info was already available elsewhere, and it's being duplicated for convenience. It is my perception that both size increases and denormalization come with strong negative externalities, and are unlikely to happen. For example:
I think it's in our best interest as rustdoc users to make sure rustdoc maintainers can focus on high-impact changes that unlock new capabilities for us. We can add ease-of-use denormalizations one abstraction layer above rustdoc JSON itself, for example via a layer like Trustfall and its rustdoc adapter. If the query {
Crate {
item {
... on Struct {
struct_id: id @output
struct_name: name @output
link {
linked_item_type: __typename @output
linked_item_id: id @output
linked_item_name: name @output
}
}
}
}
} I'd be happy to add it if it would be useful to you. |
PR adding the above to the Trustfall schema for rustdoc: obi1kenobi/trustfall-rustdoc-adapter#308 Lmk what you think! |
Referring to Zulip discussion Where to find keyword entries in JSON rustdoc, currently it seems not possible to include keywords in the JSON rustdoc. I am not sure how hard it would be to implement this feature, but hopefully it will be considered before we stabilize it. |
RFC PR: rust-lang/rfcs#2963Area: Rustdoc JSON backend
RFC: https://rust-lang.github.io/rfcs/2963-rustdoc-json.html
Documentation: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/
Issues: A-rustdoc-json
Todo:
The text was updated successfully, but these errors were encountered: