rustdoc in 2019
A couple weeks ago, the 2019 Rust All-Hands occured in Berlin. This was an opportunity to get a whole bunch of Rust contributors in the same place for a week, and get decisions done a lot faster than in a GitHub issue thread or a chatroom. Hard problems were discussed, plans were made, and serindipitous chance encounters occured that helped propel the project forward in new and exciting directions.
This was the second year for the All-Hands, and while it didn’t seem as exciting as last year’s (where it felt like three amazing new features were hitting FCP for stabilization every day!), it was no less important. There were much thornier discussions occuring, with farther-reaching implications, and a few topics seemed to have meetings (or at least hallway conversations) about them every day.
For me personally, the All-Hands is a chance to meet up with fellow contributors, put faces and voices to names that i see around the project, and get a chance to sit down with people to see how we can help each other in our respective domains. This year’s All-Hands in particular was important for me because this was the first year where rustdoc had its own team, and its own meeting slots! I got to organize three meetings for rustdoc, including one where i got to coordinate with compiler contributors to unblock some problems that we were having.
meeting 1: rustdoc roadmap
The first rustdoc meeting we had was to finalize what our priorities were for the year. Over the previous few months, we had accumulated ideas for big projects to undertake, and this meeting was there so we could pick from the list that had come together to decide what were the best ones for rustdoc. The full decision is at the bottom of this post.
meeting 2: testing rustdoc itself
The second meeting was a discussion on how to add more testing to rustdoc itself. While rustdoc has a lot of tests, it doesn’t have that extensive of a test suite, because a lot of its functionality exists in the browser, which isn’t something that can be tested easily in a headless CI environment. However, there are resources available to allow testing of websites in an automatic fashion, and we would like to start applying them to rustdoc’s output so we can track regressions in CSS, user interaction, NoScript environments, etc.
The first step we wanted to start doing was setting up a crater-like server that could render pages and run a visual regression test against them, to ensure that we don’t accidentally regress coloring or layout.
We also wanted to start running a linter on our JavaScript, to have more automated checking of it in CI. There was a recent PR that attempted to add it, but it stalled and was closed due to the author running out of time to complete it. We would love to resurrect that PR and push it across the finish line to get our JavaScript better tested.
meeting 3: coordinating rustdoc and rustc
The last meeting was an opportunity to coordinate with compiler contributors, and get a chance to unblock work that required reaching into deeper and deeper parts of the compiler. An interesting part of working on rustdoc for long enough is that over time, more and more features have come in that required some effort inside the compiler to properly support, rather than being something that rustdoc could accomplish on its own. Coordinating this effort can be a fun introduction to the first few phases of compilation if the required change is small enough, but there are also some features that ran into structural roadblocks due to how the compiler is structured.
This meeting was a great opportunity to lay out what rustdoc was trying to do, and get some feedback on how to use the compiler internals to accomplish what we needed without reaching for the much-more-grandiose schemes i had come up with as a semi-outsider. I was possibly the most excited for this one, and it generated a lot of great ideas!
The Rustdoc 2019 Roadmap
As mentioned above, this week also gave us a chance to center our priorities for the coming year. As one of the core tools that affects how people perceive Rust both inside and outside the community, it’s important that we maintain rustdoc’s reputation as one of the best API documentation generators. There are a number of in-progress features and numerous incoming feature requests that we need to balance between our limited resources and the existing tool design. That said, we believe there are a number of improvements we can make in a year that will help us continue to deserve that hard-earned reputation.
In keeping with the growing theme of “maturity” coming from around the project, this year the Rustdoc Team will focus on finishing what we’ve started, polishing what we have, and getting rustdoc in more and more places. Put more concretely, here are our priorities in 2019:
- Pushing existing unstable features to completion
- Improving documenatation tests
- Reviving JSON output
- Experimenting with an archive and server to emit fewer files
I’d like to go into more detail for each one:
pushing existing unstable features
There are (at least) three high-profile unstable features for rustdoc that are partially implemented. All these features are seeing a fair amount of use already in the community, and they work well for most situations. But for each one, there’s some implementation problem that is keeping it from being pushed all the way to stabilization. For this year, the Rustdoc Team would like to coordinate efforts to push these features to their fullest, and call for their stabilization:
- Intra-doc links
- Cross-platform docs with
#[doc(cfg)]
- Documentation management with
#[doc(include)]
improving documentation tests
Documentation tests (commonly called “doctests”) are one of the most powerful features of rustdoc. The ability to ensure that code samples written into documentation are always valid code creates confidence in documentation that won’t go out of sync with the code it’s describing. That said, there are still places where doctest code can be improved, or new features added to make them more useful in situations where they’re not available today. For this year, the Rustdoc Team would like to create a “Doctests Working Group” to focus on improvements to the doctest system. Some initial ideas put forth include:
- Cross-compilation of doctests
- Improvements in doctest error reporting
- Refactoring code detection to properly handle more kinds of code
JSON output
Several years ago, rustdoc supported outputing JSON in addition to its usual HTML. However, the old implementation of it was buggy and incomplete, so it was eventually removed. This hasn’t stopped people from desiring the feature, though. Having a machine-readable format of the API of a crate that focused on its documentation would allow Rust documentation to be more easily integrated into other documentation hosts, or to allow the creation of alternative “frontends” that consumed the JSON to create a different output from rustdoc’s classic static HTML files. For this year, the Rustdoc Team would like to investigate the revival of JSON output and create an initial implementation, to allow users to experiment with the format.
experimental archive format output
One of the biggest performance problems facing rustdoc, especially on Windows, is the fact that it generates at least one file per documentable “item” in the crate. This is a result of the fact that rustdoc acts like a static site generator, creating a plain set of web pages from its input. This combines with the design of the output site to give each item its own webpage to breathe to force the creation of so many files. One solution to this problem is to make rustdoc output an intermediate format, like the aforementioned JSON. This could offload the presentation layer to something that can take an alternate direction with the design of the site.
Another way is to change the encoding of the files on disk. Last year, an experimental web server was created that used a custom archive format to stream compressed files directly without decompressing the files and recompressing them again. It was made to serve rustdoc HTML output effeciently, and demonstrates its use in documentation by compressing documentation created by rustdoc. For this year, the Rustdoc Team would like to investigate extending its custom archive format and emitting it natively, so that users can reap the benefits of the file server without having to emit all the HTML files first.
we’re just getting started
I’ve been immersed in the Rust world for long enough that it’s hard for me to gauge how well rustdoc performs as a tool, in comparison to other languages and communities. So it’s refreshing to hear people say positive things about the quality of Rust documentation. (Even if it’s immediately followed by a feature request!) However, i still feel like there is plenty of room for improvement, and i would love to see rustdoc reach greater and greater heights.
As a teaser for next time, there’s another related post i would like to write up soon, about docs.rs. Last year, we were able to bring it into the Rust Project under the Rustdoc Team, and i’ve been working with the creator and maintainer to help improve it as well. We’ve also started making some plans to improve docs.rs, and i would love to share that soon. Stay tuned!