# 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/HEAD/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/HEAD/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.
* Use `./x.py test tidy --extra-checks=js` to run rustdoc’s JavaScript checks (`eslint`, `es-check`, and `tsc`).
> **Note:** `./x.py test tidy` already runs these checks automatically when JS/TS sources changed; `--extra-checks=js` forces them explicitly.

### JavaScript CI checks

Rustdoc’s JavaScript and TypeScript are checked during CI by `eslint`, `es-check`, and `tsc` (not by compiletest).
These run as part of the `tidy` job.

```console
./x.py test tidy --extra-checks=js
```

The `--extra-checks=js` flag enables the frontend linting that runs in CI.

[`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 have [a list of 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] [discussions][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
[a list of supported browsers]: https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html#supported-browsers

## 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 only sometimes 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 host their own documentation.
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.
