|  | # Rustdoc overview | 
|  |  | 
|  | `rustdoc` lives in-tree with the | 
|  | compiler and standard library. This chapter is about how it works. | 
|  | For information about Rustdoc's features and how to use them, see | 
|  | the [Rustdoc book](https://doc.rust-lang.org/nightly/rustdoc/). | 
|  | For more details about how rustdoc works, see the | 
|  | ["Rustdoc internals" chapter][Rustdoc internals]. | 
|  |  | 
|  | [Rustdoc internals]: ./rustdoc-internals.md | 
|  |  | 
|  | `rustdoc` uses `rustc` internals (and, of course, the standard library), so you | 
|  | will have to build the compiler and `std` once before you can build `rustdoc`. | 
|  |  | 
|  | Rustdoc is implemented entirely within the crate [`librustdoc`][rd]. It runs | 
|  | the compiler up to the point where we have an internal representation of a | 
|  | crate (HIR) and the ability to run some queries about the types of items. [HIR] | 
|  | and [queries] are discussed in the linked chapters. | 
|  |  | 
|  | [HIR]: ./hir.md | 
|  | [queries]: ./query.md | 
|  | [rd]: https://github.com/rust-lang/rust/tree/master/src/librustdoc | 
|  |  | 
|  | `librustdoc` performs two major steps after that to render a set of | 
|  | documentation: | 
|  |  | 
|  | * "Clean" the AST into a form that's more suited to creating documentation (and | 
|  | slightly more resistant to churn in the compiler). | 
|  | * Use this cleaned AST to render a crate's documentation, one page at a time. | 
|  |  | 
|  | Naturally, there's more than just this, and those descriptions simplify out | 
|  | lots of details, but that's the high-level overview. | 
|  |  | 
|  | (Side note: `librustdoc` is a library crate! The `rustdoc` binary is created | 
|  | using the project in [`src/tools/rustdoc`][bin]. Note that literally all that | 
|  | does is call the `main()` that's in this crate's `lib.rs`, though.) | 
|  |  | 
|  | [bin]: https://github.com/rust-lang/rust/tree/master/src/tools/rustdoc | 
|  |  | 
|  | ## Cheat sheet | 
|  |  | 
|  | * Run `./x setup tools` before getting started. This will configure `x` | 
|  | with nice settings for developing rustdoc and other tools, including | 
|  | downloading a copy of rustc rather than building it. | 
|  | * Use `./x check rustdoc` to quickly check for compile errors. | 
|  | * Use `./x build library rustdoc` to make a usable | 
|  | rustdoc you can run on other projects. | 
|  | * Add `library/test` to be able to use `rustdoc --test`. | 
|  | * Run `rustup toolchain link stage2 build/host/stage2` to add a | 
|  | custom toolchain called `stage2` to your rustup environment. After | 
|  | running that, `cargo +stage2 doc` in any directory will build with | 
|  | your locally-compiled rustdoc. | 
|  | * Use `./x doc library` to use this rustdoc to generate the | 
|  | standard library docs. | 
|  | * The completed docs will be available in `build/host/doc` (under `core`, `alloc`, and `std`). | 
|  | * If you want to copy those docs to a webserver, copy all of | 
|  | `build/host/doc`, since that's where the CSS, JS, fonts, and landing | 
|  | page are. | 
|  | * For frontend debugging, disable the `rust.docs-minification` option in [`bootstrap.toml`]. | 
|  | * Use `./x test tests/rustdoc*` to run the tests using a stage1 | 
|  | rustdoc. | 
|  | * See [Rustdoc internals] for more information about tests. | 
|  |  | 
|  | [`bootstrap.toml`]: ./building/how-to-build-and-run.md | 
|  |  | 
|  | ## Code structure | 
|  |  | 
|  | All paths in this section are relative to `src/librustdoc/` in the rust-lang/rust repository. | 
|  |  | 
|  | * Most of the HTML printing code is in `html/format.rs` and `html/render/mod.rs`. | 
|  | It's in a bunch of functions returning `impl std::fmt::Display`. | 
|  | * The data types that get rendered by the functions mentioned above are defined in `clean/types.rs`. | 
|  | The functions responsible for creating them from the `HIR` and the `rustc_middle::ty` IR | 
|  | live in `clean/mod.rs`. | 
|  | * The bits specific to using rustdoc as a test harness are in | 
|  | `doctest.rs`. | 
|  | * The Markdown renderer is loaded up in `html/markdown.rs`, including functions | 
|  | for extracting doctests from a given block of Markdown. | 
|  | * Frontend CSS and JavaScript are stored in `html/static/`. | 
|  | * Re. JavaScript, type annotations are written using [TypeScript-flavored JSDoc] | 
|  | comments and an external `.d.ts` file. | 
|  | This way, the code itself remains plain, valid JavaScript. | 
|  | We only use `tsc` as a linter. | 
|  |  | 
|  | [TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html | 
|  |  | 
|  | ## Tests | 
|  |  | 
|  | `rustdoc`'s integration tests are split across several test suites. | 
|  | See [Rustdoc tests suites](tests/compiletest.md#rustdoc-test-suites) for more details. | 
|  |  | 
|  | ## Constraints | 
|  |  | 
|  | We try to make rustdoc work reasonably well with JavaScript disabled, and when | 
|  | browsing local files. We support | 
|  | [these browsers](https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html#supported-browsers). | 
|  |  | 
|  | Supporting local files (`file:///` URLs) brings some surprising restrictions. | 
|  | Certain browser features that require secure origins, like `localStorage` and | 
|  | Service Workers, don't work reliably. We can still use such features but we | 
|  | should make sure pages are still usable without them. | 
|  |  | 
|  | Rustdoc [does not type-check function bodies][platform-specific docs]. | 
|  | This works by [overriding the built-in queries for typeck][override queries], | 
|  | by [silencing name resolution errors], and by [not resolving opaque types]. | 
|  | This comes with several caveats: in particular, rustdoc *cannot* run any parts of the compiler that | 
|  | require type-checking bodies; for example it cannot generate `.rlib` files or run most lints. | 
|  | We want to move away from this model eventually, but we need some alternative for | 
|  | [the people using it][async-std]; see [various][zulip stop accepting broken code] | 
|  | [previous][rustdoc meeting 2024-07-08] [zulip][compiler meeting 2023-01-26] [discussion][notriddle rfc]. | 
|  | For examples of code that breaks if this hack is removed, see | 
|  | [`tests/rustdoc-ui/error-in-impl-trait`]. | 
|  |  | 
|  | [platform-specific docs]: https://doc.rust-lang.org/rustdoc/advanced-features.html#interactions-between-platform-specific-docs | 
|  | [override queries]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/src/librustdoc/core.rs#L299-L323 | 
|  | [silencing name resolution errors]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/compiler/rustc_resolve/src/late.rs#L4517 | 
|  | [not resolving opaque types]: https://github.com/rust-lang/rust/blob/52bf0cf795dfecc8b929ebb1c1e2545c3f41d4c9/compiler/rustc_hir_analysis/src/check/check.rs#L188-L194 | 
|  | [async-std]: https://github.com/rust-lang/rust/issues/75100 | 
|  | [rustdoc meeting 2024-07-08]: https://rust-lang.zulipchat.com/#narrow/channel/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449969836 | 
|  | [compiler meeting 2023-01-26]: https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202023-01-26/near/323755789 | 
|  | [zulip stop accepting broken code]: https://rust-lang.zulipchat.com/#narrow/stream/266220-rustdoc/topic/stop.20accepting.20broken.20code | 
|  | [notriddle rfc]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/Pre-RFC.3A.20stop.20accepting.20broken.20code | 
|  | [`tests/rustdoc-ui/error-in-impl-trait`]: https://github.com/rust-lang/rust/tree/163cb4ea3f0ae3bc7921cc259a08a7bf92e73ee6/tests/rustdoc-ui/error-in-impl-trait | 
|  |  | 
|  | ## Multiple runs, same output directory | 
|  |  | 
|  | Rustdoc can be run multiple times for varying inputs, with its output set to the | 
|  | same directory. That's how cargo produces documentation for dependencies of the | 
|  | current crate. It can also be done manually if a user wants a big | 
|  | documentation bundle with all of the docs they care about. | 
|  |  | 
|  | HTML is generated independently for each crate, but there is some cross-crate | 
|  | information that we update as we add crates to the output directory: | 
|  |  | 
|  | - `crates<SUFFIX>.js` holds a list of all crates in the output directory. | 
|  | - `search-index<SUFFIX>.js` holds a list of all searchable items. | 
|  | - For each trait, there is a file under `implementors/.../trait.TraitName.js` | 
|  | containing a list of implementors of that trait. The implementors may be in | 
|  | different crates than the trait, and the JS file is updated as we discover | 
|  | new ones. | 
|  |  | 
|  | ## Use cases | 
|  |  | 
|  | There are a few major use cases for rustdoc that you should keep in mind when | 
|  | working on it: | 
|  |  | 
|  | ### Standard library docs | 
|  |  | 
|  | These are published at <https://doc.rust-lang.org/std> as part of the Rust release | 
|  | process. Stable releases are also uploaded to specific versioned URLs like | 
|  | <https://doc.rust-lang.org/1.57.0/std/>. Beta and nightly docs are published to | 
|  | <https://doc.rust-lang.org/beta/std/> and <https://doc.rust-lang.org/nightly/std/>. | 
|  | The docs are uploaded with the [promote-release | 
|  | tool](https://github.com/rust-lang/promote-release) and served from S3 with | 
|  | CloudFront. | 
|  |  | 
|  | The standard library docs contain five crates: alloc, core, proc_macro, std, and | 
|  | test. | 
|  |  | 
|  | ### docs.rs | 
|  |  | 
|  | When crates are published to crates.io, docs.rs automatically builds | 
|  | and publishes their documentation, for instance at | 
|  | <https://docs.rs/serde/latest/serde/>. It always builds with the current nightly | 
|  | rustdoc, so any changes you land in rustdoc are "insta-stable" in that they will | 
|  | have an immediate public effect on docs.rs. Old documentation is not rebuilt, so | 
|  | you will see some variation in UI when browsing old releases in docs.rs. Crate | 
|  | authors can request rebuilds, which will be run with the latest rustdoc. | 
|  |  | 
|  | Docs.rs performs some transformations on rustdoc's output in order to save | 
|  | storage and display a navigation bar at the top. In particular, certain static | 
|  | files, like main.js and rustdoc.css, may be shared across multiple invocations | 
|  | of the same version of rustdoc. Others, like crates.js and sidebar-items.js, are | 
|  | different for different invocations. Still others, like fonts, will never | 
|  | change. These categories are distinguished using the `SharedResource` enum in | 
|  | `src/librustdoc/html/render/write_shared.rs` | 
|  |  | 
|  | Documentation on docs.rs is always generated for a single crate at a time, so | 
|  | the search and sidebar functionality don't include dependencies of the current | 
|  | crate. | 
|  |  | 
|  | ### Locally generated docs | 
|  |  | 
|  | Crate authors can run `cargo doc --open` in crates they have checked | 
|  | out locally to see the docs. This is useful to check that the docs they | 
|  | are writing are useful and display correctly. It can also be useful for | 
|  | people to view documentation on crates they aren't authors of, but want to | 
|  | use. In both cases, people may use `--document-private-items` Cargo flag to | 
|  | see private methods, fields, and so on, which are normally not displayed. | 
|  |  | 
|  | By default `cargo doc` will generate documentation for a crate and all of its | 
|  | dependencies. That can result in a very large documentation bundle, with a large | 
|  | (and slow) search corpus. The Cargo flag `--no-deps` inhibits that behavior and | 
|  | generates docs for just the crate. | 
|  |  | 
|  | ### Self-hosted project docs | 
|  |  | 
|  | Some projects like to host their own documentation. For example: | 
|  | <https://docs.serde.rs/>. This is easy to do by locally generating docs, and | 
|  | simply copying them to a web server. Rustdoc's HTML output can be extensively | 
|  | customized by flags. Users can add a theme, set the default theme, and inject | 
|  | arbitrary HTML. See `rustdoc --help` for details. |