···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 61
34expression: output
45---
56# Getting started
6777-Follow these steps to start using `mdbook-rustdoc-link` in your book project!
88-98## Install
1091110You will need to:
12111313-1. Have [rust-analyzer]:
1212+1. Have [rust-analyzer].:
14131515- - If you already use the [VS Code extension][ra-extension]: this crate automatically
1616- uses the server binary that comes with it, no extra setup is needed!
1717- - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure
1818- it's on your `PATH`.
1414+ - If you already use the [VS Code extension][ra-extension], no setup is required: the
1515+ preprocessor automatically uses the server binary packaged with it.
1616+ - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure it
1717+ is available on `PATH`.
19182020-2. Install this crate:
1919+2. Install the preprocessor:
21202221 ```
2322 cargo install mdbookkit --features rustdoc-link
2423 ```
25242626- Or you can grab precompiled binaries from [GitHub releases][gh-releases].
2525+ Alternatively, you may obtain precompiled binaries from [GitHub
2626+ releases][gh-releases].
2727+2828+ <!-- TODO: cargo binstall -->
27292830## Configure
29313030-Configure your `book.toml` to use it as a [preprocessor]:
3232+Configure your `book.toml` to use the installed program as a [preprocessor]:
31333234```toml
3335[book]
···3638[preprocessor.rustdoc-link]
3739# mdBook will run `mdbook-rustdoc-link`
3840after = ["links"]
3939-# recommended, so that it can see content from {{#include}} as well
4141+# mdBook will run this preprocessor after the default `links` preprocessor.
4242+# This is recommended. It allows the preprocessor to see text embedded
4343+# via {{#include}} directives.
4044```
41454246## Write
43474444-In your documentation, when you want to link to a Rust item, such as a type, a function,
4545-etc., simply use its name in place of a URL, like this:
4848+In your documentation, where you want to link to a Rust item, such as a type, a
4949+function, etc., simply use its name in place of a URL:
46504751```md
4852Like [`std::thread::spawn`], [`tokio::task::spawn`] returns a
4953[`JoinHandle`][tokio::task::JoinHandle] struct.
5054```
51555252-The preprocessor will then turn them into hyperlinks:
5656+The preprocessor will convert such symbols into hyperlinks:
53575458<figure class="fig-text">
5559···58625963</figure>
60646161-This works in both `mdbook build` and `mdbook serve`!
6565+The preprocessor runs in both `mdbook build` and `mdbook serve`.
62666367
64686565-To read more about this project, feel free to return to [Overview](index.md#overview).
6666-6769> [!IMPORTANT]
6870>
6969-> It is assumed that you are running `mdbook` within a Cargo project.
7171+> It is assumed that you are running mdBook from within a Cargo project.
7072>
7173> If you are working on a crate, and your book directory is within your source tree,
7272-> such as next to `Cargo.toml`, then running `mdbook` from there will "just work".
7474+> such as next to `Cargo.toml`, then running mdBook from there will "just work".
7375>
7474-> If your book doesn't belong to a Cargo project, refer to
7575-> [Workspace layout](workspace-layout.md) for more information on how you can setup up
7676-> the preprocessor.
7676+> If your book doesn't reside within a Cargo project, refer to
7777+> [Workspace layout](workspace-layout.md) for instructions on setting up the
7878+> preprocessor.
77797880> [!TIP]
7981>
···8284>
8385> Items from `std` will generate links to <https://doc.rust-lang.org>, while items from
8486> third-party crates will generate links to <https://docs.rs>.
8585->
8686-> So really, rust-analyzer is doing the heavy-lifting here. This crate is just the glue
8787-> code :)
8787+8888+## Next steps
8989+9090+- See the full list of [supported syntax](supported-syntax.md).
9191+- Understand [how the preprocessor resolves links](name-resolution.md) under the hood.
9292+- Check out [available configuration options](configuration.md).
9393+- Learn about some [known issues and limitations](known-issues.md).
88948995<!-- prettier-ignore-start -->
9096
···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 61
34expression: output
45---
56# mdbook-rustdoc-link
···11121213</div>
13141414-**[_rustdoc_-style linking][rustdoc] for [mdBook]** (with the help of [rust-analyzer]).
1515+Link to Rust API docs by name in [mdBook], [_rustdoc_-style][rustdoc].
15161616-You write:
1717+Instead of manually finding and pasting URLs, you simply write ...
17181819```md
1920The [`option`][std::option] and [`result`][std::result] modules define optional and
···2223collections. [^1]
2324```
24252525-You get:
2626+... and you will get:
26272728<figure class="fig-text">
2829···33343435</figure>
35363636-`mdbook-rustdoc-link` is an mdBook [preprocessor]. Using rust-analyzer, it converts type
3737-names, module paths, and so on, into links to online crate docs. No more finding and
3838-pasting URLs by hand.
3939-4037<figure>
41384239
43404441</figure>
45424343+> [!NOTE]
4444+>
4545+> This preprocessor depends on [rust-analyzer] to accurately resolve Rust items.
4646+4647## Overview
47484848-To get started, simply follow the [quickstart guide](getting-started.md)!
4949-5050-If you would like to read more about this crate:
4949+Follow the [quickstart guide](getting-started.md) to try out the preprocessor.
51505251For **writing documentation** —
53525454-- To learn more about how it is resolving items into links, including
5353+- To learn more about how the preprocessor resolves items into links, including
5554 [feature-gated items](name-resolution.md#feature-gated-items), see
5655 [Name resolution](name-resolution.md).
5757-- To know how to link to other types of items like
5656+- To learn how to link to additional items such as
5857 [functions, macros](supported-syntax.md#functions-and-macros), and
5958 [implementors](supported-syntax.md#implementors-and-fully-qualified-syntax), see
6059 [Supported syntax](supported-syntax.md).
61606262-For **adapting this crate to your project** —
6161+For **making the preprocessor work with your project** —
63626463- If you use [Cargo workspaces][workspaces], see specific instructions in
6564 [Workspace layout](workspace-layout.md).
···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 61
34expression: output
45---
56# Known issues
6777-<details class="toc" open>
88- <summary>Sections</summary>
99-1010-- [Performance](#performance)
1111-- [Incorrect links](#incorrect-links)
1212- - [Macros](#macros)
1313- - [Trait items](#trait-items)
1414- - [Private items](#private-items)
1515-- [Unresolved items](#unresolved-items)
1616- - [Associated items on primitive types](#associated-items-on-primitive-types)
1717-- [Sites other than docs.rs](#sites-other-than-docsrs)
1818-- [Wrong line numbers in diagnostics](#wrong-line-numbers-in-diagnostics)
1919-2020-</details>
2121-228## Performance
2392410`mdbook-rustdoc-link` itself doesn't need much processing power, but it invokes
2525-rust-analyzer, which does a full scan of your workspace. The larger your codebase is,
2626-the longer `mdbook` will have to wait for the preprocessor. This is the source of the
1111+rust-analyzer, which does a full scan of your workspace. The larger your workspace is,
1212+the longer mdBook will have to wait for the preprocessor. This is the source of the
2713majority of the run time.
28142915There is an [experimental caching feature](caching.md#enabling-caching), which persists
3016query results after runs and reuses them when possible, avoiding spawning rust-analyzer
3117when your edit doesn't involve item links.
32183333-## Incorrect links
3434-3535-In limited circumstances, the preprocessor generates links that are incorrect or
3636-inaccessible.
1919+## Incorrect/unresolvable links
37203821> [!NOTE]
3922>
4040-> The following observations are based on rust-analyzer
4141-> <ra-version>(version)</ra-version>.
2323+> The following observations are as of rust-analyzer <ra-version>(version)</ra-version>.
42244343-### Macros
2525+In some circumstances, the preprocessor generates links that are incorrect or
2626+inaccessible.
44274545-Macros exported with [`#[macro_export]`][macro_export] are always exported at crate
4646-root, and are documented as such by rustdoc, but rust-analyzer currently generates links
4747-to the modules they are defined in. For example:
2828+### Derive macros
48294949-- [~~`panic!`~~](https://doc.rust-lang.org/stable/std/macros/macro.panic.html "panic!"), and many other `std` macros
5050- - The correct link is
5151- [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
5252-- [~~`serde_json::json!`~~](https://docs.rs/serde_json/1.0.140/serde_json/macros/macro.json.html "serde_json::json!")
5353- - The correct link is
5454- [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json]
3030+Previously, it was possible to link to the documentation for a derive macro instead of
3131+the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros),
3232+for example, by writing [`[serde::Serialize!]`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize") instead of
3333+[`[serde::Serialize]`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize").
55345656-Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually
5757-generates `attr.<macro_name>.html`. For example:
3535+This no longer works due to an upstream change. To link to such derive macros, you must
3636+use paths that directly point to them, for example, `serde_derive::Serialize`.
3737+3838+### Attribute macros
3939+4040+Links generated by rust-analyzer for attribute macros end with
4141+`macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For
4242+example:
58435944- [~~`tokio::main!`~~](https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html "tokio::main!")
6045 - The correct link is
···8772The preprocessor does not yet warn you about links to private items: rust-analyzer will
8873generate links for items regardless of their crate-level visibility.
89749090-## Unresolved items
9191-9292-### Associated items on primitive types
9393-9494-> [!NOTE]
9595->
9696-> The following observations are based on rust-analyzer
9797-> <ra-version>(version)</ra-version>.
7575+### Items on primitive types
98769977Links to associated methods and items on primitive types are currently not resolved by
10078rust-analyzer. For example:
···1068410785Currently, items from crates other than `std` always generate links that point to
10886<https://docs.rs>. `mdbook-rustdoc-link` does not yet support configuring alternative
109109-hosting sites for crates (such as `wasm-bindgen` which hosts API docs under
110110-`https://rustwasm.github.io/wasm-bindgen/api/`).
8787+URL prefixes.
1118811289## Wrong line numbers in diagnostics
11390···129106130107Unless mdBook somehow gains [source map][sourcemap] support, this problem is unlikely to
131108ever be solved.
109109+110110+## Resolved issues
111111+112112+### Since rust-analyzer `2025-08-11`
113113+114114+Previously, generated links to macros were often incorrect. These are currently
115115+[fixed upstream](https://github.com/rust-lang/rust-analyzer/pull/20384) as of
116116+rust-analyzer
117117+[`2025-08-11`](https://github.com/rust-lang/rust-analyzer/releases/tag/2025-08-11).
118118+119119+<details>
120120+ <summary>Original description</summary>
121121+122122+Macros exported with [`#[macro_export]`][macro_export] are always exported at crate
123123+root, and are documented as such by rustdoc, but rust-analyzer currently generates links
124124+to the modules they are defined in. For example:
125125+126126+- [~~`panic!`~~](https://doc.rust-lang.org/stable/std/macro.panic.html "panic!"), and many other `std` macros
127127+ - The correct link is
128128+ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
129129+- [~~`serde_json::json!`~~](https://docs.rs/serde_json/1.0.145/serde_json/macro.json.html "serde_json::json!")
130130+ - The correct link is
131131+ [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json]
132132+133133+</details>
132134133135<!-- prettier-ignore-start -->
134136
···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 76
34expression: report
45---
56 info: successfully resolved all links
66- ╭─[known-issues:45:3]
77+ ╭─[known-issues:27:25]
88+ │ the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros),
99+ │ for example, by writing [`[serde::Serialize!]`][serde::Serialize] instead of
1010+ · ────────────────────┬────────────────────
1111+ · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html
1212+ │ [`[serde::Serialize]`][serde::Serialize].
1313+ · ────────────────────┬───────────────────
1414+ · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html
715 │
88- │ - [~~`panic!`~~], and many other `std` macros
99- · ───────┬──────
1010- · ╰── https://doc.rust-lang.org/stable/std/macros/macro.panic.html
1111- │ - The correct link is
1212- │ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
1313- │ - [~~`serde_json::json!`~~]
1414- · ────────────┬────────────
1515- · ╰── https://docs.rs/serde_json/1.0.140/serde_json/macros/macro.json.html
1616- │ - The correct link is
1717- │ [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json]
1616+ │ This no longer works due to an upstream change. To link to such derive macros, you must
1717+ │ use paths that directly point to them, for example, `serde_derive::Serialize`.
1818+ │
1919+ │ ### Attribute macros
1820 │
1919- │ Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually
2020- │ generates `attr.<macro_name>.html`. For example:
2121+ │ Links generated by rust-analyzer for attribute macros end with
2222+ │ `macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For
2323+ │ example:
2124 │
2225 │ - [~~`tokio::main!`~~]
2326 · ──────────┬─────────
···4447 · ╰── https://doc.rust-lang.org/stable/core/net/ip_addr/enum.IpAddr.html#method.from
4548 │
4649 ╰────
5050+ ╭─[known-issues:121:3]
5151+ │
5252+ │ - [~~`panic!`~~], and many other `std` macros
5353+ · ───────┬──────
5454+ · ╰── https://doc.rust-lang.org/stable/std/macro.panic.html
5555+ │ - The correct link is
5656+ │ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
5757+ │ - [~~`serde_json::json!`~~]
5858+ · ────────────┬────────────
5959+ · ╰── https://docs.rs/serde_json/1.0.145/serde_json/macro.json.html
6060+ │ - The correct link is
6161+ ╰────
···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 61
34expression: output
45---
56# Supported syntax
···11121213</div>
13141414-This page showcases all the syntax supported by `mdbook-rustdoc-link`.
1515-1616-Most of the formats [supported by rustdoc][rustdoc-linking] are supported. Unsupported
1515+Most of the syntax [supported by rustdoc][rustdoc-linking] are supported. Unsupported
1716syntax and differences in behavior are emphasized below.
18171918In general, specifying items as you would when writing Rust code should "just work".
2020-2121-<details class="toc" open>
2222- <summary>Sections</summary>
2323-2424-- [Types, modules, and associated items](#types-modules-and-associated-items)
2525-- [Generic parameters](#generic-parameters)
2626-- [Functions and macros](#functions-and-macros)
2727-- [Implementors and fully qualified syntax](#implementors-and-fully-qualified-syntax)
2828-- [Disambiguators](#disambiguators)
2929-- [Special types](#special-types)
3030-- [Struct fields](#struct-fields)
3131-- [Markdown link syntax](#markdown-link-syntax)
3232-- [Linking to page sections](#linking-to-page-sections)
3333-3434-</details>
35193620> [!TIP]
3721>
3822> This page is also used for snapshot testing! To see how all the links would look like
3923> in Markdown after they have been processed, see
4040-> [supported-syntax.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.snap)
2424+> [supported-syntax.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.snap)
4125> and
4242-> [supported-syntax.stderr.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.stderr.snap).
2626+> [supported-syntax.stderr.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.stderr.snap).
43274444-## Types, modules, and associated items
2828+## Types, modules, associated items
45294630> ```md
4731> Module [`alloc`][std::alloc] — Memory allocation APIs.
···67516852## Generic parameters
69537070-Types can contain generic parameters. This is _compatible_ with rustdoc.
5454+Types may contain generic parameters. This is _compatible_ with rustdoc.
71557256> ```md
7357> [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime.
···8771> | [`&'a mut T`](https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html "std::marker::PhantomData<&'a mut T>") | **in**variant |
8872> | [`fn(T)`](https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html "std::marker::PhantomData<fn(T)>") | **contra**variant |
89739090-This includes if you use turbofish:
7474+Turbofish are also supported:
91759276> ```md
9377> `collect()` is one of the few times you’ll see the syntax affectionately known as the
···998310084## Functions and macros
10185102102-To indicate that an item is a function, add `()` after the function name. To indicate
103103-that an item is a macro, add `!` after the macro name, optionally followed by `()`,
104104-`[]`, or `{}`. This is _compatible_ with rustdoc.
105105-106106-Note that there cannot be arguments within `()`, `[]`, or `{}`.
8686+Functions and macros can be linked to just like other named items. To distinguish a
8787+function from other items of the same name, add `()` after the function name. To
8888+distinguish a macro from other items of the same name, add `!` after the macro name.
8989+This is _compatible_ with rustdoc.
1079010891> ```md
109109-> [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally
110110-> use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]!
9292+> [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use
9393+> [`format`][std::fmt::format()] in place of [`format!`][std::format!]!
11194> ```
11295>
113113-> [`vec!`](https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html "std::vec!")[^2] is different from [`vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), and don't accidentally
114114-> use [`format()`](https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html "std::fmt::format()") in place of [`format!()`](https://doc.rust-lang.org/stable/alloc/macros/macro.format.html "std::format!()")[^2]!
9696+> [`vec!`](https://doc.rust-lang.org/stable/alloc/macro.vec.html "std::vec!") is different from [`vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), and don't accidentally use
9797+> [`format`](https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html "std::fmt::format()") in place of [`format!`](https://doc.rust-lang.org/stable/alloc/macro.format.html "std::format!")!
11598116116-The macro syntax works for attribute and derive macros as well (even though this is not
117117-how they are invoked).
9999+Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax
100100+works for attribute and derive macros as well (even though this is not how they are
101101+invoked).
118102119119-> ```md
120120-> There is a [derive macro][serde::Serialize!] to generate implementations of the
121121-> [`Serialize`][serde::Serialize] trait.
122122-> ```
103103+> [!NOTE]
104104+>
105105+> As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no
106106+> longer disambiguate between a derive macro and its corresponding trait. For example,
107107+>
108108+> > ```
109109+> > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait.
110110+> > ```
111111+> >
112112+> > Both [`serde::Serialize`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize") and [`serde::Serialize!`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize!") link to the `Serialize` trait.
123113>
124124-> There is a [derive macro](https://docs.rs/serde_derive/1.0.219/serde_derive/derive.Serialize.html "serde::Serialize!") to generate implementations of the
125125-> [`Serialize`](https://docs.rs/serde/1.0.219/serde/ser/trait.Serialize.html "serde::Serialize") trait.
114114+> To link to such derive macros, you must use paths that directly point to them, such as
115115+> `serde_derive::Serialize`.
126116127127-## Implementors and fully qualified syntax
117117+## Fully qualified paths
128118129129-Trait implementors may supply additional documentation about their implementations. To
130130-link to implemented items instead of the traits themselves, use fully qualified paths,
131131-including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not
132132-currently support.
119119+Trait implementors may supply additional documentation about the implementation. To link
120120+to such documentation instead of the traits themselves, use fully qualified paths,
121121+including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc
122122+does not currently support.
133123134124> ```md
135125> [`Result<T, E>`] implements [`IntoIterator`]; its
···150140> [!NOTE]
151141>
152142> If your type has generic parameters, you must supply concrete types for them for
153153-> rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't
143143+> rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not
154144> work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally
155145> in scope).
156146157157-## Disambiguators
158158-159159-rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
160160-ignored**:
161161-162162-> ```md
163163-> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
164164-> ```
165165->
166166-> [`std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), [`mod@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "mod@std::vec"), and [`macro@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "macro@std::vec") all link to the `vec` _module_.
167167-168168-This is largely okay because currently, duplicate names in Rust are allowed only if they
169169-correspond to items in different [namespaces], for example, between macros and modules,
170170-and between struct fields and methods — this is mostly covered by the function and macro
171171-syntax, described [above](#functions-and-macros).
172172-173173-If you encounter items that must be disambiguated using rustdoc's disambiguator syntax,
174174-other than [the "special types" listed below](#special-types), please [file an
175175-issue][gh-issues]!
176176-177177-## Special types
178178-179179-> [!WARNING]
180180-181181-There is **no support** on types whose syntax is not a path; they are currently not
182182-parsed at all:
183183-184184-> references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like
185185-> `*const T`, trait objects like `dyn Any`, and the never type `!`
186186-187187-Note that such types can still be used as generic params, just not as standalone types.
188188-189189-## Struct fields
190190-191191-> [!WARNING]
192192-193193-Linking to struct fields is **not supported** yet. This is **incompatible** with
194194-rustdoc.
195195-196196-## Markdown link syntax
147147+## Link format
197148198149All Markdown link formats supported by rustdoc are supported:
199150···229180Shortcuts are supported, and can contain inline markups:
230181231182> ```md
232232-> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro.
183183+> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro.
233184> ```
234185>
235235-> You can create a [`Vec`](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html "Vec") with [**`Vec::new`**](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new "Vec::new"), or by using the [*`vec!`*](https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html "vec!")[^2] macro.
236236-237237-(The items must still be resolvable; in this case `Vec` and `vec!` come from the
238238-prelude.)
186186+> You can create a [`Vec`](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html "Vec") with [**`Vec::new`**](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new "Vec::new"), or by using the [*`vec!`*](https://doc.rust-lang.org/stable/alloc/macro.vec.html "vec!") macro.
239187240188## Linking to page sections
241189242242-To link to a known section on a page, use a URL fragment, just like a normal link. This
243243-is _compatible_ with rustdoc.
190190+To link to a known section on a page, use a URL fragment, as you would otherwise specify
191191+for an HTTP URL. This is _compatible_ with rustdoc.
244192245193<!-- prettier-ignore-start -->
246194···252200253201<!-- prettier-ignore-end -->
254202203203+## Unsupported syntax
204204+205205+### Disambiguators
206206+207207+rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
208208+ignored.** To disambiguate functions and macros, use the
209209+[functions and macros](#functions-and-macros) syntax.
210210+211211+> ```md
212212+> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
213213+> ```
214214+>
215215+> [`std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), [`mod@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "mod@std::vec"), and [`macro@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "macro@std::vec") all link to the `vec` _module_.
216216+217217+### Special types
218218+219219+There is **no support** on types whose syntax is not a path; they are currently not
220220+parsed at all:
221221+222222+> references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like
223223+> `*const T`, trait objects like `dyn Any`, and the never type `!`
224224+225225+Note that such types can still be used as generic params, just not as standalone types.
226226+227227+### Struct fields
228228+229229+Linking to struct fields is **not supported** yet. This is **incompatible** with
230230+rustdoc.
231231+255232[^1]:
256233 rust-analyzer's ability to generate links for enum variants like `Option::Some` was
257234 improved only somewhat recently: before
258235 [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants
259236 and associated items may only point to the types themselves. If linking to such
260237 items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer
261261- first!
262262-263263-[^2]:
264264- As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros
265265- don't always work. Examples include [`std::format!`](https://doc.rust-lang.org/stable/alloc/macros/macro.format.html "std::format!") (seen above) and
266266- [`tokio::main!`](https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html "tokio::main!"). For more info, see [Known issues](known-issues.md#macros).
238238+ first.
267239268240<!-- prettier-ignore-start -->
269241
···11---
22-source: crates/mdbookkit/tests/rustdoc_link.rs
22+source: crates/mdbook-rustdoc-links/src/tests.rs
33+assertion_line: 76
34expression: report
45---
56 info: successfully resolved all links
66- ╭─[supported-syntax:46:10]
77+ ╭─[supported-syntax:29:10]
78 │ >
89 │ > Module [`alloc`][std::alloc] — Memory allocation APIs.
910 · ──────────┬──────────
···3435 │
3536 │ ## Generic parameters
3637 │
3737- │ Types can contain generic parameters. This is _compatible_ with rustdoc.
3838+ │ Types may contain generic parameters. This is _compatible_ with rustdoc.
3839 │
3940 │ > ```md
4041 │ > [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime.
···6061 · ─────────────────────┬────────────────────
6162 · ╰── https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html
6263 │
6363- │ This includes if you use turbofish:
6464+ │ Turbofish are also supported:
6465 │
6566 │ > ```md
6667 │ > `collect()` is one of the few times you’ll see the syntax affectionately known as the
···7475 │
7576 │ ## Functions and macros
7677 │
7777- │ To indicate that an item is a function, add `()` after the function name. To indicate
7878- │ that an item is a macro, add `!` after the macro name, optionally followed by `()`,
7979- │ `[]`, or `{}`. This is _compatible_ with rustdoc.
8080- │
8181- │ Note that there cannot be arguments within `()`, `[]`, or `{}`.
7878+ │ Functions and macros can be linked to just like other named items. To distinguish a
7979+ │ function from other items of the same name, add `()` after the function name. To
8080+ │ distinguish a macro from other items of the same name, add `!` after the macro name.
8181+ │ This is _compatible_ with rustdoc.
8282 │
8383 │ > ```md
8484- │ > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally
8585- │ > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]!
8484+ │ > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use
8585+ │ > [`format`][std::fmt::format()] in place of [`format!`][std::format!]!
8686 │ > ```
8787 │ >
8888- │ > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally
8989- · ─────────┬───────── ────────┬────────
9090- · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
9191- · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html
9292- │ > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]!
9393- · ────────────────┬─────────────── ──────────────┬──────────────
9494- · │ ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.format.html
9595- · ╰── https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html
8888+ │ > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use
8989+ · ─────────┬───────── ────────┬────────
9090+ · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
9191+ · ╰── https://doc.rust-lang.org/stable/alloc/macro.vec.html
9292+ │ > [`format`][std::fmt::format()] in place of [`format!`][std::format!]!
9393+ · ───────────────┬────────────── ────────────┬────────────
9494+ · │ ╰── https://doc.rust-lang.org/stable/alloc/macro.format.html
9595+ · ╰── https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html
9696 │
9797- │ The macro syntax works for attribute and derive macros as well (even though this is not
9898- │ how they are invoked).
9797+ │ Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax
9898+ │ works for attribute and derive macros as well (even though this is not how they are
9999+ │ invoked).
99100 │
100100- │ > ```md
101101- │ > There is a [derive macro][serde::Serialize!] to generate implementations of the
102102- │ > [`Serialize`][serde::Serialize] trait.
103103- │ > ```
101101+ │ > [!NOTE]
102102+ │ >
103103+ │ > As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no
104104+ │ > longer disambiguate between a derive macro and its corresponding trait. For example,
104105 │ >
105105- │ > There is a [derive macro][serde::Serialize!] to generate implementations of the
106106- · ────────────────┬────────────────
107107- · ╰── https://docs.rs/serde_derive/1.0.219/serde_derive/derive.Serialize.html
108108- │ > [`Serialize`][serde::Serialize] trait.
109109- · ───────────────┬───────────────
110110- · ╰── https://docs.rs/serde/1.0.219/serde/ser/trait.Serialize.html
106106+ │ > > ```
107107+ │ > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait.
108108+ │ > > ```
109109+ │ > >
110110+ │ > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait.
111111+ · ──────────┬───────── ──────────┬──────────
112112+ · │ ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html
113113+ · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html
114114+ │ >
115115+ │ > To link to such derive macros, you must use paths that directly point to them, such as
116116+ │ > `serde_derive::Serialize`.
111117 │
112112- │ ## Implementors and fully qualified syntax
118118+ │ ## Fully qualified paths
113119 │
114114- │ Trait implementors may supply additional documentation about their implementations. To
115115- │ link to implemented items instead of the traits themselves, use fully qualified paths,
116116- │ including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not
117117- │ currently support.
120120+ │ Trait implementors may supply additional documentation about the implementation. To link
121121+ │ to such documentation instead of the traits themselves, use fully qualified paths,
122122+ │ including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc
123123+ │ does not currently support.
118124 │
119125 │ > ```md
120126 │ > [`Result<T, E>`] implements [`IntoIterator`]; its
···147153 │ > [!NOTE]
148154 │ >
149155 │ > If your type has generic parameters, you must supply concrete types for them for
150150- │ > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't
156156+ │ > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not
151157 │ > work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally
152158 │ > in scope).
153159 │
154154- │ ## Disambiguators
155155- │
156156- │ rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
157157- │ ignored**:
158158- │
159159- │ > ```md
160160- │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
161161- │ > ```
162162- │ >
163163- │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
164164- · ──────┬───── ────────┬─────── ─────────┬────────
165165- · │ │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
166166- · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
167167- · ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
168168- │
169169- │ This is largely okay because currently, duplicate names in Rust are allowed only if they
170170- │ correspond to items in different [namespaces], for example, between macros and modules,
171171- │ and between struct fields and methods — this is mostly covered by the function and macro
172172- │ syntax, described [above](#functions-and-macros).
173173- │
174174- │ If you encounter items that must be disambiguated using rustdoc's disambiguator syntax,
175175- │ other than [the "special types" listed below](#special-types), please [file an
176176- │ issue][gh-issues]!
177177- │
178178- │ ## Special types
179179- │
180180- │ > [!WARNING]
181181- │
182182- │ There is **no support** on types whose syntax is not a path; they are currently not
183183- │ parsed at all:
184184- │
185185- │ > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like
186186- │ > `*const T`, trait objects like `dyn Any`, and the never type `!`
187187- │
188188- │ Note that such types can still be used as generic params, just not as standalone types.
189189- │
190190- │ ## Struct fields
191191- │
192192- │ > [!WARNING]
193193- │
194194- │ Linking to struct fields is **not supported** yet. This is **incompatible** with
195195- │ rustdoc.
196196- │
197197- │ ## Markdown link syntax
160160+ │ ## Link format
198161 │
199162 │ All Markdown link formats supported by rustdoc are supported:
200163 │
···236199 │ Shortcuts are supported, and can contain inline markups:
237200 │
238201 │ > ```md
239239- │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro.
202202+ │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro.
240203 │ > ```
241204 │ >
242242- │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro.
205205+ │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro.
243206 · ───┬─── ────────┬─────── ─────┬────
244244- · │ │ ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html
207207+ · │ │ ╰── https://doc.rust-lang.org/stable/alloc/macro.vec.html
245208 · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new
246209 · ╰── https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html
247210 │
248248- │ (The items must still be resolvable; in this case `Vec` and `vec!` come from the
249249- │ prelude.)
250250- │
251211 │ ## Linking to page sections
252212 │
253253- │ To link to a known section on a page, use a URL fragment, just like a normal link. This
254254- │ is _compatible_ with rustdoc.
213213+ │ To link to a known section on a page, use a URL fragment, as you would otherwise specify
214214+ │ for an HTTP URL. This is _compatible_ with rustdoc.
255215 │
256216 │ <!-- prettier-ignore-start -->
257217 │
···265225 │
266226 │ <!-- prettier-ignore-end -->
267227 │
268268- │ [^1]:
269269- │ rust-analyzer's ability to generate links for enum variants like `Option::Some` was
270270- │ improved only somewhat recently: before
271271- │ [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants
272272- │ and associated items may only point to the types themselves. If linking to such
273273- │ items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer
274274- │ first!
228228+ │ ## Unsupported syntax
275229 │
276276- │ [^2]:
277277- │ As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros
278278- │ don't always work. Examples include [`std::format!`] (seen above) and
279279- · ────────┬───────
280280- · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.format.html
281281- │ [`tokio::main!`]. For more info, see [Known issues](known-issues.md#macros).
282282- · ────────┬───────
283283- · ╰── https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html
230230+ │ ### Disambiguators
231231+ │
232232+ │ rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
233233+ │ ignored.** To disambiguate functions and macros, use the
234234+ │ [functions and macros](#functions-and-macros) syntax.
235235+ │
236236+ │ > ```md
237237+ │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
238238+ │ > ```
239239+ │ >
240240+ │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
241241+ · ──────┬───── ────────┬─────── ─────────┬────────
242242+ · │ │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
243243+ · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
244244+ · ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html
284245 │
285246 ╰────
···11# Caching
2233By default, `mdbook-rustdoc-link` spawns a fresh `rust-analyzer` process every time it
44-runs. rust-analyzer then reindexes your entire project before resolving links.
44+runs. rust-analyzer must then reindex your entire project before being able to resolve
55+links.
5666-This makes the `mdbook serve` command significantly slower, more so if your project
77-contains a large number of dependencies. It is as if for every live reload, you had to
88-reopen your editor.
77+This makes the `mdbook serve` command significantly less responsive, which gets worse if
88+your project contains a large number of dependencies. It is as if for every live reload,
99+you had to reopen your editor.
9101011To mitigate this, there is an experimental caching feature. The feature is disabled by
1112default.
12131314## Enabling caching
14151515-In your `book.toml`, in the `[preprocessor.rustdoc-link]` table, set
1616+In `book.toml`, in the `[preprocessor.rustdoc-link]` table, set
1617[`cache-dir`](configuration.md#cache-dir) to the relative path of a directory of your
1717-choice (_other than_ your book's `build-dir`), for example:
1818+choice, _outside_ of your book's `build-dir`, for example:
18191920```toml
2021[preprocessor.rustdoc-link]
···2223# You could also point to an arbitrary directory in target/
2324```
24252525-Now, when `mdbook` rebuilds your book during `build` or `serve`, the preprocessor reuses
2626-the previous resolution and **skips rust-analyzer entirely if** your edit does not
2727-involve changes in the set of Rust items to be linked, that is, no new items unseen in
2828-the previous build.
2626+This enables the preprocessor to persist the list of links resolved during a build. When
2727+mdBook rebuilds your book during `build` or `serve`, the preprocessor reuses the
2828+previous resolution and **skips rust-analyzer entirely if** your edit does not involve
2929+changes in the set of Rust items to be linked, that is, if there are no new items unseen
3030+in the previous build.
29313032> [!IMPORTANT]
3133>
···3436> file could trigger additional reloads. See [Specify exclude
3537> patterns][specify-exclude-patterns] in the mdBook documentation.
3638>
3737-> **Do not** use your book's `build-dir` as the `cache-dir`: `mdbook` clears the output
3939+> Items that fail to resolve are not included in the cache. If such "broken" links
4040+> persist in the Markdown source, cache will be invalidated on every run, and
4141+> rust-analyzer will always run.
4242+>
4343+> **Do not** use your book's `build-dir` as the `cache-dir`: mdbook clears the output
3844> directory on every build, making this setup useless.
39454046## How it works
···46524753The effectiveness of this mechanism is based on the following assumptions:
48544949-- Most of the changes made during authoring don't actually involve item links.
5555+- Most of the changes made during authoring don't involve item links.
5056- Assuming the environment is unchanged, the same set of items should resolve to the
5157 same set of links.
52585353-The cache keeps the following information in a `cache.json`:
5959+The cache keeps the following information in a `cache.json` file:
54605561- The set of items to be resolved, and their resolved links
5662- The environment, as a checksum over the contents of:
···6369If a subsequent run has the same set of items (or a subset) and the same checksum
6470(meaning you did not update your code), then the preprocessor simply reuses the previous
6571results.
6666-6767-> [!TIP]
6868->
6969-> Items that fail to resolve are not included in the cache.
7070->
7171-> If you keep such broken links in your Markdown source, the cache will permanently
7272-> miss, and rust-analyzer will run on every edit.
73727473## Help wanted 🙌
7574···118117119118### Postscript
120119121121-`mdbook` encourages a stateless architecture for preprocessors. Preprocessors are
122122-expected to work like pure functions over the entire book, even for `mdbook serve`.
123123-Preprocessors are not informed on whether they are invoked as part of `mdbook build`
124124-(prefer fresh starts) or `mdbook serve` (maintain states between run).
120120+mdBook encourages a stateless architecture for preprocessors. Preprocessors are expected
121121+to work like pure functions over the entire book, even for `mdbook serve`. Preprocessors
122122+are not informed on whether they are invoked as part of `mdbook build` (prefer fresh
123123+starts) or `mdbook serve` (maintain states between run).
125124126125`rust-analyzer`, meanwhile, has a stateful architecture that also doesn't yet have
127126[persistent caching][ra-persistent-cache][^1]. It is [designed][ra-architecture] to take
···129128edited) entirely in memory.
130129131130So `rust-analyzer` has an extremely incremental architecture, perfect for complex
132132-languages like Rust, and `mdbook` has an explicitly non-incremental architecture,
133133-perfect for rendering Markdown. This makes them somewhat challenging to work well
134134-together in a live-reload scenario.
131131+languages like Rust, and mdBook has an explicitly non-incremental architecture, perfect
132132+for rendering Markdown. This makes them somewhat challenging to work well together in a
133133+live-reload scenario.
135134136135[^1]:
137136 It was mentioned that the [recently updated, salsa-ified rust-analyzer][salsa]
+18-27
docs/src/rustdoc-link/continuous-integration.md
···11# Continuous integration
2233This page gives information and tips for using `mdbook-rustdoc-link` in a continuous
44-integration (CI) environment.
55-66-The preprocessor behaves differently in terms of logging, error handling, etc., when it
77-detects it is running in CI.
88-99-<details class="toc" open>
1010- <summary>Sections</summary>
1111-1212-- [Detecting CI](#detecting-ci)
1313-- [Installing rust-analyzer](#installing-rust-analyzer)
1414-- [Logging](#logging)
1515-- [Error handling](#error-handling)
1616-1717-</details>
44+integration (CI) environment. The preprocessor optimizes some behaviors for CI, in terms
55+of error handling, logging, etc.
186197## Detecting CI
2082121-To determine whether it is running in CI, the preprocessor honors the `CI` environment
2222-variable. Specifically:
99+To determine whether it is running in a CI environment, the preprocessor honors the `CI`
1010+environment variable. Specifically:
23112412- If `CI` is set to `"true"`, then it is considered in CI[^ci-true];
2513- Otherwise, it is considered not in CI.
26142727-Most major CI/CD services, such as [GitHub Actions][github-actions-ci] and [GitLab
2828-CI/CD][gitlab-ci], automatically configure this variable for you.
1515+Providers such as [GitHub Actions][github-actions-ci] and [GitLab CI/CD][gitlab-ci] have
1616+this variable configured by default.
29173018## Installing rust-analyzer
31193220rust-analyzer must be on `PATH` when running in CI[^ra-on-path].
33213434-One way is to install it via [rustup][rustup-ra]. For example, in [GitHub
2222+One way to install it is via [rustup][rustup-ra]. For example, in [GitHub
3523Actions][dtolnay/rust-toolchain], you can use:
36243725```yaml
···43314432> [!NOTE]
4533>
4646-> Be aware that rust-analyzer from rustup follows Rust's release schedule, which means
4747-> it may lag behind the version bundled with the VS Code extension.
3434+> rust-analyzer from rustup follows Rust's release schedule, which may lag behind the
3535+> version bundled with the VS Code extension.
48364937## Logging
3838+3939+<!-- TODO: -->
50405141By default, the preprocessor shows a progress spinner when it is running.
5242···57475848## Error handling
59496060-By default, when the preprocessor encounters any non-fatal issues, such as when a link
6161-fails to resolve, it prints them as warnings but continues to run. This is so that your
6262-book continues to build via `mdbook serve` while you make edits.
5050+When running locally, when the preprocessor encounters any non-fatal issues, such as
5151+when a link fails to resolve, it prints them as warnings but continues to run. This is
5252+so that your book continues to build via `mdbook serve` while you make edits.
63536454When running in CI, all such warnings are promoted to errors. The preprocessor will exit
6565-with a non-zero status code when there are warnings, which will fail your build. This
6666-prevents outdated or incorrect links from being accidentally deployed.
5555+with a non-zero status code which will fail your build. This is to prevent outdated or
5656+incorrect links from being accidentally deployed.
67576858You can explicitly control this behavior using the
6959[`fail-on-warnings`](configuration.md#fail-on-warnings) option.
70607161[^ra-on-path]:
7272- Unless you use the [`rust-analyzer`](configuration.md#rust-analyzer) option.
6262+ You may alternatively specify a command to use for rust-analyzer via the
6363+ [`rust-analyzer`](configuration.md#rust-analyzer) configuration option.
73647465[^ci-true]:
7566 Specifically, when `CI` is anything other than `""`, `"0"`, or `"false"`. The logic
+30-25
docs/src/rustdoc-link/getting-started.md
···11# Getting started
2233-Follow these steps to start using `mdbook-rustdoc-link` in your book project!
44-53## Install
6475You will need to:
8699-1. Have [rust-analyzer]:
77+1. Have [rust-analyzer].:
1081111- - If you already use the [VS Code extension][ra-extension]: this crate automatically
1212- uses the server binary that comes with it, no extra setup is needed!
1313- - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure
1414- it's on your `PATH`.
99+ - If you already use the [VS Code extension][ra-extension], no setup is required: the
1010+ preprocessor automatically uses the server binary packaged with it.
1111+ - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure it
1212+ is available on `PATH`.
15131616-2. Install this crate:
1414+2. Install the preprocessor:
17151816 ```
1917 cargo install mdbookkit --features rustdoc-link
2018 ```
21192222- Or you can grab precompiled binaries from [GitHub releases][gh-releases].
2020+ Alternatively, you may obtain precompiled binaries from [GitHub
2121+ releases][gh-releases].
2222+2323+ <!-- TODO: cargo binstall -->
23242425## Configure
25262626-Configure your `book.toml` to use it as a [preprocessor]:
2727+Configure your `book.toml` to use the installed program as a [preprocessor]:
27282829```toml
2930[book]
···3233[preprocessor.rustdoc-link]
3334# mdBook will run `mdbook-rustdoc-link`
3435after = ["links"]
3535-# recommended, so that it can see content from {{#include}} as well
3636+# mdBook will run this preprocessor after the default `links` preprocessor.
3737+# This is recommended. It allows the preprocessor to see text embedded
3838+# via {{#include}} directives.
3639```
37403841## Write
39424040-In your documentation, when you want to link to a Rust item, such as a type, a function,
4141-etc., simply use its name in place of a URL, like this:
4343+In your documentation, where you want to link to a Rust item, such as a type, a
4444+function, etc., simply use its name in place of a URL:
42454346```md
4447Like [`std::thread::spawn`], [`tokio::task::spawn`] returns a
4548[`JoinHandle`][tokio::task::JoinHandle] struct.
4649```
47504848-The preprocessor will then turn them into hyperlinks:
5151+The preprocessor will convert such symbols into hyperlinks:
49525053<figure class="fig-text">
5154···54575558</figure>
56595757-This works in both `mdbook build` and `mdbook serve`!
6060+The preprocessor runs in both `mdbook build` and `mdbook serve`.
58615962
6060-6161-To read more about this project, feel free to return to [Overview](index.md#overview).
62636364> [!IMPORTANT]
6465>
6565-> It is assumed that you are running `mdbook` within a Cargo project.
6666+> It is assumed that you are running mdBook from within a Cargo project.
6667>
6768> If you are working on a crate, and your book directory is within your source tree,
6868-> such as next to `Cargo.toml`, then running `mdbook` from there will "just work".
6969+> such as next to `Cargo.toml`, then running mdBook from there will "just work".
6970>
7070-> If your book doesn't belong to a Cargo project, refer to
7171-> [Workspace layout](workspace-layout.md) for more information on how you can setup up
7272-> the preprocessor.
7171+> If your book doesn't reside within a Cargo project, refer to
7272+> [Workspace layout](workspace-layout.md) for instructions on setting up the
7373+> preprocessor.
73747475> [!TIP]
7576>
···7879>
7980> Items from `std` will generate links to <https://doc.rust-lang.org>, while items from
8081> third-party crates will generate links to <https://docs.rs>.
8181->
8282-> So really, rust-analyzer is doing the heavy-lifting here. This crate is just the glue
8383-> code :)
8282+8383+## Next steps
8484+8585+- See the full list of [supported syntax](supported-syntax.md).
8686+- Understand [how the preprocessor resolves links](name-resolution.md) under the hood.
8787+- Check out [available configuration options](configuration.md).
8888+- Learn about some [known issues and limitations](known-issues.md).
84898590<!-- prettier-ignore-start -->
8691
+11-13
docs/src/rustdoc-link/index.md
···7788</div>
991010-**[_rustdoc_-style linking][rustdoc] for [mdBook]** (with the help of [rust-analyzer]).
1010+Link to Rust API docs by name in [mdBook], [_rustdoc_-style][rustdoc].
11111212-You write:
1212+Instead of manually finding and pasting URLs, you simply write ...
13131414```md
1515The [`option`][std::option] and [`result`][std::result] modules define optional and
···1818collections. [^1]
1919```
20202121-You get:
2121+... and you will get:
22222323<figure class="fig-text">
2424···29293030</figure>
31313232-`mdbook-rustdoc-link` is an mdBook [preprocessor]. Using rust-analyzer, it converts type
3333-names, module paths, and so on, into links to online crate docs. No more finding and
3434-pasting URLs by hand.
3535-3632<figure>
37333834
39354036</figure>
41374242-## Overview
3838+> [!NOTE]
3939+>
4040+> This preprocessor depends on [rust-analyzer] to accurately resolve Rust items.
43414444-To get started, simply follow the [quickstart guide](getting-started.md)!
4242+## Overview
45434646-If you would like to read more about this crate:
4444+Follow the [quickstart guide](getting-started.md) to try out the preprocessor.
47454846For **writing documentation** —
49475050-- To learn more about how it is resolving items into links, including
4848+- To learn more about how the preprocessor resolves items into links, including
5149 [feature-gated items](name-resolution.md#feature-gated-items), see
5250 [Name resolution](name-resolution.md).
5353-- To know how to link to other types of items like
5151+- To learn how to link to additional items such as
5452 [functions, macros](supported-syntax.md#functions-and-macros), and
5553 [implementors](supported-syntax.md#implementors-and-fully-qualified-syntax), see
5654 [Supported syntax](supported-syntax.md).
57555858-For **adapting this crate to your project** —
5656+For **making the preprocessor work with your project** —
59576058- If you use [Cargo workspaces][workspaces], see specific instructions in
6159 [Workspace layout](workspace-layout.md).
+46-45
docs/src/rustdoc-link/known-issues.md
···11# Known issues
2233-<details class="toc" open>
44- <summary>Sections</summary>
55-66-- [Performance](#performance)
77-- [Incorrect links](#incorrect-links)
88- - [Macros](#macros)
99- - [Trait items](#trait-items)
1010- - [Private items](#private-items)
1111-- [Unresolved items](#unresolved-items)
1212- - [Associated items on primitive types](#associated-items-on-primitive-types)
1313-- [Sites other than docs.rs](#sites-other-than-docsrs)
1414-- [Wrong line numbers in diagnostics](#wrong-line-numbers-in-diagnostics)
1515-1616-</details>
1717-183## Performance
194205`mdbook-rustdoc-link` itself doesn't need much processing power, but it invokes
2121-rust-analyzer, which does a full scan of your workspace. The larger your codebase is,
2222-the longer `mdbook` will have to wait for the preprocessor. This is the source of the
66+rust-analyzer, which does a full scan of your workspace. The larger your workspace is,
77+the longer mdBook will have to wait for the preprocessor. This is the source of the
238majority of the run time.
2492510There is an [experimental caching feature](caching.md#enabling-caching), which persists
2611query results after runs and reuses them when possible, avoiding spawning rust-analyzer
2712when your edit doesn't involve item links.
28132929-## Incorrect links
3030-3131-In limited circumstances, the preprocessor generates links that are incorrect or
3232-inaccessible.
1414+## Incorrect/unresolvable links
33153416> [!NOTE]
3517>
3636-> The following observations are based on rust-analyzer
3737-> <ra-version>(version)</ra-version>.
1818+> The following observations are as of rust-analyzer <ra-version>(version)</ra-version>.
38193939-### Macros
2020+In some circumstances, the preprocessor generates links that are incorrect or
2121+inaccessible.
2222+2323+### Derive macros
2424+2525+Previously, it was possible to link to the documentation for a derive macro instead of
2626+the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros),
2727+for example, by writing [`[serde::Serialize!]`][serde::Serialize] instead of
2828+[`[serde::Serialize]`][serde::Serialize].
40294141-Macros exported with [`#[macro_export]`][macro_export] are always exported at crate
4242-root, and are documented as such by rustdoc, but rust-analyzer currently generates links
4343-to the modules they are defined in. For example:
3030+This no longer works due to an upstream change. To link to such derive macros, you must
3131+use paths that directly point to them, for example, `serde_derive::Serialize`.
44324545-- [~~`panic!`~~], and many other `std` macros
4646- - The correct link is
4747- [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
4848-- [~~`serde_json::json!`~~]
4949- - The correct link is
5050- [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json]
3333+### Attribute macros
51345252-Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually
5353-generates `attr.<macro_name>.html`. For example:
3535+Links generated by rust-analyzer for attribute macros end with
3636+`macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For
3737+example:
54385539- [~~`tokio::main!`~~]
5640 - The correct link is
···8367The preprocessor does not yet warn you about links to private items: rust-analyzer will
8468generate links for items regardless of their crate-level visibility.
85698686-## Unresolved items
8787-8888-### Associated items on primitive types
8989-9090-> [!NOTE]
9191->
9292-> The following observations are based on rust-analyzer
9393-> <ra-version>(version)</ra-version>.
7070+### Items on primitive types
94719572Links to associated methods and items on primitive types are currently not resolved by
9673rust-analyzer. For example:
···1027910380Currently, items from crates other than `std` always generate links that point to
10481<https://docs.rs>. `mdbook-rustdoc-link` does not yet support configuring alternative
105105-hosting sites for crates (such as `wasm-bindgen` which hosts API docs under
106106-`https://rustwasm.github.io/wasm-bindgen/api/`).
8282+URL prefixes.
1078310884## Wrong line numbers in diagnostics
10985···125101126102Unless mdBook somehow gains [source map][sourcemap] support, this problem is unlikely to
127103ever be solved.
104104+105105+## Resolved issues
106106+107107+### Since rust-analyzer `2025-08-11`
108108+109109+Previously, generated links to macros were often incorrect. These are currently
110110+[fixed upstream](https://github.com/rust-lang/rust-analyzer/pull/20384) as of
111111+rust-analyzer
112112+[`2025-08-11`](https://github.com/rust-lang/rust-analyzer/releases/tag/2025-08-11).
113113+114114+<details>
115115+ <summary>Original description</summary>
116116+117117+Macros exported with [`#[macro_export]`][macro_export] are always exported at crate
118118+root, and are documented as such by rustdoc, but rust-analyzer currently generates links
119119+to the modules they are defined in. For example:
120120+121121+- [~~`panic!`~~], and many other `std` macros
122122+ - The correct link is
123123+ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic]
124124+- [~~`serde_json::json!`~~]
125125+ - The correct link is
126126+ [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json]
127127+128128+</details>
128129129130<!-- prettier-ignore-start -->
130131
+17-19
docs/src/rustdoc-link/motivation.md
···11# Motivation
2233-[rustdoc supports linking to items by name][rustdoc], a.k.a. [intra-doc
44-links][intra-doc-link]. This is awesome for at least two reasons:
33+[rustdoc supports linking to items by name][rustdoc]. This is awesome for at least two
44+reasons:
5566-- It's convenient. It could be as simple as [just adding brackets][uv-brackets].
77-- [Docs.rs](https://docs.rs) will generate cross-crate links that are version-pinned.
66+- It's convenient. It could be as simple as [just adding brackets around
77+ names][uv-brackets].
88+- Links generated via rustdoc are version-pinned. Instead of seeing links that default
99+ to the latest version, where items may have been moved or deleted, you get the
1010+ versions that your packages actually depend on.
811912mdBook doesn't have the luxury of accessing compiler internals yet, so you are left with
1010-manually sourcing links from docs.rs. Then one of two things could happen:
1313+manually sourcing links from [docs.rs](https://docs.rs). Then one of two things could
1414+happen:
11151212-- APIs are mentioned without linking to reference docs.
1313-1414- This is probably fine for tutorials and examples, but it does mean readers of your
1515- docs won't be able to move from guides to references as easily.
1616+- APIs are mentioned without appropriate links to reference docs.
16171717-- You do want at least some cross-references, but it is cumbersome to find and copy the
1818- correct links, and even more so to maintain them.
1818+ This may be fine for tutorials and examples. However, readers of your docs will not be
1919+ able to navigate between guides and references as easily as it could have been.
19202020- Links to docs.rs often use `latest` as the version, which could become out-of-sync
2121- with your code, especially if they point to third-party or unstable APIs.
2121+- You do want at least some reference links. It could quickly become cumbersome to find
2222+ and copy the correct links by hand, and even more so to maintain them over time.
22232324`mdbook-rustdoc-link` is the tooling answer to these problems. _Effortless, correct, and
2425good practice — choose all three!_
25262626-> [!NOTE]
2727+> [!TIP]
2728>
2828-> That being said, sometimes manually specifying URLs is the best option.
2929->
3030-> Most importantly, writing links by name means they won't be rendered as such when your
3131-> Markdown source is displayed elsewhere. If your document is also intended for places
3232-> like GitHub or crates.io, then you should probably not use this preprocessor.
2929+> This style of linking is also known as "intra-doc links" — read more about it in the
3030+> [original RFC][intra-doc-link].
33313432<!-- prettier-ignore-start -->
3533
+25-41
docs/src/rustdoc-link/name-resolution.md
···11# Name resolution
2233-`mdbook-rustdoc-link` resolves items in the context of your crate's "entrypoint", which
44-is usually your `lib.rs` or `main.rs` (the [specific rules](#which-entrypoint) are
55-mentioned below).
33+The preprocessor resolves items **in the scope of your crate's "entrypoint."** This is
44+usually `lib.rs` or `main.rs` (the [exact rules](#which-entrypoint) are mentioned
55+below).
6677> [!TIP]
88>
99-> If you use Cargo workspaces, or if your source tree has special layout, see
1010-> [Workspace layout](workspace-layout.md) for more information.
1111-1212-An item must be **in scope in the entrypoint** for the proprocessor to generate a link
1313-for it.
99+> If you use Cargo workspaces, or if your source tree has a custom layout, consult
1010+> [Workspace layout](workspace-layout.md) for additional instructions.
14111512For example, with the following as `lib.rs`:
1613···2926Items in the entrypoint can be linked to with just their names:
30273128> ```md
3232-> [`Diagnostics`] encapsulates possible issues detected within Markdown sources.
2929+> [`Diagnostics`] contains issues detected within Markdown sources.
3330>
3431> This crate uses the [`Context`] trait from [`anyhow`].
3532> ```
3633>
3737-> [`Diagnostics`] encapsulates possible issues detected within Markdown sources.
3434+> [`Diagnostics`] contains issues detected within Markdown sources.
3835>
3936> This crate uses the [`Context`] trait from [`anyhow`].
4037···4643>
4744> [`FromIterator`] is in the prelude starting from Rust 2021.
48454949-Though technically not required — to make items from your crate more distinguishable
5050-from others in your Markdown source, you can write `crate::*`:
4646+To distinguish an item as being from your crate rather than from a third-party crate,
4747+you may write `crate::*`, although this is not required:
51485249> ```md
5350> The [`is_ci`][crate::error::is_ci] function detects whether the preprocessor is
···6764>
6865> [`JoinSet`][tokio::task::JoinSet] is analogous to Python's `asyncio.as_completed`.
69667070-> [!TIP]
7171->
7272-> In short, write links the way you `use` an item in your `lib.rs` or `main.rs`.
7373-7474-The preprocessor will emit a warning if an item cannot be resolved:
6767+The preprocessor emits warnings for items that cannot be resolved:
75687669<figure>
7770···8477</figcaption>
85788679</figure>
8787-8888-This is something to remember especially if you are including doc comments as part of
8989-your Markdown docs. Only rustdoc has the ability to [resolve names from where the
9090-comments are written][rustdoc-scoping], so links that work in doc comments may not work
9191-when using this preprocessor!
92809381## Feature-gated items
9482···112100>
113101> [Tutorial for clap's Derive API][clap::_derive::_tutorial]
114102115115-## Which entrypoint
103103+## Which "entrypoint"?
116104117105For this preprocessor, the "entrypoint" is usually `src/lib.rs` or `src/main.rs`.
118106···126114127115> [!NOTE]
128116>
129129-> The following are implementation details. See
130130-> [rustdoc_link/mod.rs](/crates/mdbookkit/src/bin/rustdoc_link/mod.rs).
117117+> The following are implementation details.
131118132132-`mdbook-rustdoc-link` parses your book and collects every link that looks like a Rust
133133-item. Then it synthesizes a Rust function that spells out all the items, which looks
134134-roughly like this:
119119+The preprocessor parses your book and collects every link that looks like a Rust item.
120120+Then it synthesizes a Rust function that spells out all the items, which could look
121121+something like:
135122136123```rs
137124fn __ded48f4d_0c4f_4950_b17d_55fd3b2a0c86__ () {
···144131}
145132```
146133147147-> Note that this is barely valid Rust — `Result::<T, E>;` is a type without a value, and
148148-> you wouldn't use `serde::Serialize` as a regular macro.
149149->
150150-> This is where language servers like rust-analyzer excel — they can [provide maximally
151151-> useful information out of badly-shaped code][why-lsp].
152152-153153-The preprocessor appends this fake function to your `lib.rs` or `main.rs` (in memory, it
154154-doesn't modify your file) and [sends][didOpen] it to rust-analyzer. Then, for each item
155155-that needs to be resolved, the preprocessor sends an [external documentation
156156-request][externalDocs].
134134+The preprocessor appends this fake function to your `lib.rs` or `main.rs` (in memory)
135135+and [sends][didOpen] it to rust-analyzer. Then, for each item that needs to be resolved,
136136+the preprocessor sends an [external documentation request][externalDocs].
157137158138```json
159139{
···165145 }
166146}
167147```
168168-169169-Hence item names in your book must be resolvable from your crate entrypoint!
170148171149This process is as if you had typed a name into your source file and used the "Open
172172-Docs" feature — except it's fully automated.
150150+Docs" feature — except it is automated.
173151174152<figure id="media-open-docs">
175153 <img src="media/open-docs.png" alt="the Open Docs option in VS Code">
···181159 }
182160 }
183161</style>
162162+163163+> Note that the synthesized function is barely valid Rust — `Result::<T, E>;` is a type
164164+> without a value, and you wouldn't use `serde::Serialize` as a regular macro.
165165+>
166166+> This is where language servers like rust-analyzer excel — they can [provide maximally
167167+> useful information out of badly-shaped code][why-lsp].
184168185169<!-- prettier-ignore-start -->
186170
+3-6
docs/src/rustdoc-link/standalone-usage.md
···11# Standalone usage
2233-You can use `mdbook-rustdoc-link` as a standalone Markdown processor from the command
44-line.
55-66-Simply use the `markdown` subcommand, send your Markdown through stdin, and receive the
77-result through stdout, for example:
33+You can use `mdbook-rustdoc-link` as a standalone Markdown processor via the `markdown`
44+subcommand: send your Markdown through stdin, and receive the result through stdout, for
55+example:
8697```bash
108mdbook-rustdoc-link markdown < README.md
···16141715<figure id="media-open-docs">
1816 <img src="media/standalone-usage.png" alt="example using mdbook-rustdoc-link as a command line tool">
1919- <figcaption>Use it in any text processing pipeline!</figcaption>
2017</figure>
21182219<style>
+70-99
docs/src/rustdoc-link/supported-syntax.md
···7788</div>
991010-This page showcases all the syntax supported by `mdbook-rustdoc-link`.
1111-1212-Most of the formats [supported by rustdoc][rustdoc-linking] are supported. Unsupported
1010+Most of the syntax [supported by rustdoc][rustdoc-linking] are supported. Unsupported
1311syntax and differences in behavior are emphasized below.
14121513In general, specifying items as you would when writing Rust code should "just work".
16141717-<details class="toc" open>
1818- <summary>Sections</summary>
1919-2020-- [Types, modules, and associated items](#types-modules-and-associated-items)
2121-- [Generic parameters](#generic-parameters)
2222-- [Functions and macros](#functions-and-macros)
2323-- [Implementors and fully qualified syntax](#implementors-and-fully-qualified-syntax)
2424-- [Disambiguators](#disambiguators)
2525-- [Special types](#special-types)
2626-- [Struct fields](#struct-fields)
2727-- [Markdown link syntax](#markdown-link-syntax)
2828-- [Linking to page sections](#linking-to-page-sections)
2929-3030-</details>
3131-3215> [!TIP]
3316>
3417> This page is also used for snapshot testing! To see how all the links would look like
3518> in Markdown after they have been processed, see
3636-> [supported-syntax.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.snap)
1919+> [supported-syntax.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.snap)
3720> and
3838-> [supported-syntax.stderr.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.stderr.snap).
2121+> [supported-syntax.stderr.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.stderr.snap).
39224040-## Types, modules, and associated items
2323+## Types, modules, associated items
41244225> ```md
4326> Module [`alloc`][std::alloc] — Memory allocation APIs.
···63466447## Generic parameters
65486666-Types can contain generic parameters. This is _compatible_ with rustdoc.
4949+Types may contain generic parameters. This is _compatible_ with rustdoc.
67506851> ```md
6952> [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime.
···8366> | [`&'a mut T`][std::marker::PhantomData<&'a mut T>] | **in**variant |
8467> | [`fn(T)`][std::marker::PhantomData<fn(T)>] | **contra**variant |
85688686-This includes if you use turbofish:
6969+Turbofish are also supported:
87708871> ```md
8972> `collect()` is one of the few times you’ll see the syntax affectionately known as the
···95789679## Functions and macros
97809898-To indicate that an item is a function, add `()` after the function name. To indicate
9999-that an item is a macro, add `!` after the macro name, optionally followed by `()`,
100100-`[]`, or `{}`. This is _compatible_ with rustdoc.
101101-102102-Note that there cannot be arguments within `()`, `[]`, or `{}`.
8181+Functions and macros can be linked to just like other named items. To distinguish a
8282+function from other items of the same name, add `()` after the function name. To
8383+distinguish a macro from other items of the same name, add `!` after the macro name.
8484+This is _compatible_ with rustdoc.
1038510486> ```md
105105-> [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally
106106-> use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]!
8787+> [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use
8888+> [`format`][std::fmt::format()] in place of [`format!`][std::format!]!
10789> ```
10890>
109109-> [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally
110110-> use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]!
9191+> [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use
9292+> [`format`][std::fmt::format()] in place of [`format!`][std::format!]!
11193112112-The macro syntax works for attribute and derive macros as well (even though this is not
113113-how they are invoked).
9494+Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax
9595+works for attribute and derive macros as well (even though this is not how they are
9696+invoked).
11497115115-> ```md
116116-> There is a [derive macro][serde::Serialize!] to generate implementations of the
117117-> [`Serialize`][serde::Serialize] trait.
118118-> ```
9898+> [!NOTE]
9999+>
100100+> As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no
101101+> longer disambiguate between a derive macro and its corresponding trait. For example,
119102>
120120-> There is a [derive macro][serde::Serialize!] to generate implementations of the
121121-> [`Serialize`][serde::Serialize] trait.
103103+> > ```
104104+> > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait.
105105+> > ```
106106+> >
107107+> > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait.
108108+>
109109+> To link to such derive macros, you must use paths that directly point to them, such as
110110+> `serde_derive::Serialize`.
122111123123-## Implementors and fully qualified syntax
112112+## Fully qualified paths
124113125125-Trait implementors may supply additional documentation about their implementations. To
126126-link to implemented items instead of the traits themselves, use fully qualified paths,
127127-including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not
128128-currently support.
114114+Trait implementors may supply additional documentation about the implementation. To link
115115+to such documentation instead of the traits themselves, use fully qualified paths,
116116+including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc
117117+does not currently support.
129118130119> ```md
131120> [`Result<T, E>`] implements [`IntoIterator`]; its
···146135> [!NOTE]
147136>
148137> If your type has generic parameters, you must supply concrete types for them for
149149-> rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't
138138+> rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not
150139> work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally
151140> in scope).
152141153153-## Disambiguators
154154-155155-rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
156156-ignored**:
157157-158158-> ```md
159159-> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
160160-> ```
161161->
162162-> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
163163-164164-This is largely okay because currently, duplicate names in Rust are allowed only if they
165165-correspond to items in different [namespaces], for example, between macros and modules,
166166-and between struct fields and methods — this is mostly covered by the function and macro
167167-syntax, described [above](#functions-and-macros).
168168-169169-If you encounter items that must be disambiguated using rustdoc's disambiguator syntax,
170170-other than [the "special types" listed below](#special-types), please [file an
171171-issue][gh-issues]!
172172-173173-## Special types
174174-175175-> [!WARNING]
176176-177177-There is **no support** on types whose syntax is not a path; they are currently not
178178-parsed at all:
179179-180180-> references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like
181181-> `*const T`, trait objects like `dyn Any`, and the never type `!`
182182-183183-Note that such types can still be used as generic params, just not as standalone types.
184184-185185-## Struct fields
186186-187187-> [!WARNING]
188188-189189-Linking to struct fields is **not supported** yet. This is **incompatible** with
190190-rustdoc.
191191-192192-## Markdown link syntax
142142+## Link format
193143194144All Markdown link formats supported by rustdoc are supported:
195145···225175Shortcuts are supported, and can contain inline markups:
226176227177> ```md
228228-> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro.
178178+> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro.
229179> ```
230180>
231231-> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro.
232232-233233-(The items must still be resolvable; in this case `Vec` and `vec!` come from the
234234-prelude.)
181181+> You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro.
235182236183## Linking to page sections
237184238238-To link to a known section on a page, use a URL fragment, just like a normal link. This
239239-is _compatible_ with rustdoc.
185185+To link to a known section on a page, use a URL fragment, as you would otherwise specify
186186+for an HTTP URL. This is _compatible_ with rustdoc.
240187241188<!-- prettier-ignore-start -->
242189···248195249196<!-- prettier-ignore-end -->
250197198198+## Unsupported syntax
199199+200200+### Disambiguators
201201+202202+rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but
203203+ignored.** To disambiguate functions and macros, use the
204204+[functions and macros](#functions-and-macros) syntax.
205205+206206+> ```md
207207+> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
208208+> ```
209209+>
210210+> [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_.
211211+212212+### Special types
213213+214214+There is **no support** on types whose syntax is not a path; they are currently not
215215+parsed at all:
216216+217217+> references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like
218218+> `*const T`, trait objects like `dyn Any`, and the never type `!`
219219+220220+Note that such types can still be used as generic params, just not as standalone types.
221221+222222+### Struct fields
223223+224224+Linking to struct fields is **not supported** yet. This is **incompatible** with
225225+rustdoc.
226226+251227[^1]:
252228 rust-analyzer's ability to generate links for enum variants like `Option::Some` was
253229 improved only somewhat recently: before
254230 [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants
255231 and associated items may only point to the types themselves. If linking to such
256232 items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer
257257- first!
258258-259259-[^2]:
260260- As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros
261261- don't always work. Examples include [`std::format!`] (seen above) and
262262- [`tokio::main!`]. For more info, see [Known issues](known-issues.md#macros).
233233+ first.
263234264235<!-- prettier-ignore-start -->
265236
+16-25
docs/src/rustdoc-link/workspace-layout.md
···33As mentioned in [Name resolution](name-resolution.md), the preprocessor must know where
44your crate's entrypoint is.
5566-To do that, it tries to find a `Cargo.toml` by running
66+To do that, it will try to locate the nearest `Cargo.toml` by running
77[`cargo locate-project`][locate-project], by default from the current working directory.
8899-If you have a single-crate setup, this should "just work", regardless of where your book
1010-directory is within your source tree.
99+If you have a single-package setup, this should "just work", regardless of where your
1010+book directory is within your source tree.
11111212If you are using [Cargo workspaces][workspaces], then the preprocessor may fail with the
1313message:
···1616Error: Cargo.toml does not have any lib or bin target
1717```
18181919-This means it found your workspace `Cargo.toml` instead of a member crate's. To use the
2020-preprocessor in this case, some extra setup is needed.
2121-2222-<details class="toc" open>
2323- <summary>Sections</summary>
2424-2525-- [Using the `manifest-dir` option](#using-the-manifest-dir-option)
2626-- [Placing your book inside a member crate](#placing-your-book-inside-a-member-crate)
2727-- [Documenting multiple crates](#documenting-multiple-crates)
2828-- [Using without a Cargo project](#using-without-a-cargo-project)
2929-3030-</details>
1919+In this case, the preprocessor has located the workspace `Cargo.toml` rather than that
2020+of a specific package, and some extra setup is required.
31213222## Using the `manifest-dir` option
33233424In your `book.toml`, in the `[preprocessor.rustdoc-link]` table, set the
3525[`manifest-dir`](configuration.md#manifest-dir) option to the relative path to a member
3636-crate.
2626+package.
37273828For example, if you have the following workspace layout:
3929···6252> `manifest-dir` should be a path **relative to `book.toml`**, not relative to workspace
6353> root.
64546565-## Placing your book inside a member crate
5555+## Placing your book inside a member package
66566767-If you have a "main" crate, you can also move your book directory to that crate, and run
6868-`mdbook` from there:
5757+If you have a "main" package, you can also move your book directory to that package, and
5858+run mdBook from there:
69597060```
7161my-workspace/
···8272 └── ...
8373```
84748585-## Documenting multiple crates
7575+## Documenting multiple packages
86768787-If you would like to document items from several independent crates, but still would
7777+If you would like to document items from several independent packages, but still would
8878like to centralize your book in one place — unfortunately, the preprocessor does not yet
8979have the ability to work with multiple entrypoints.
90809191-A possible workaround would be to turn your book folder into a private crate that
9292-depends on the crates you would like to document. Then you can link to them as if they
9393-were third-party crates.
8181+A possible workaround would be to turn your book folder into a private package that
8282+depends on the packages you would like to document. Then you can link to them as if they
8383+were third-party packages. The generated links will point to the original packages
8484+instead of this private package.
94859586```
9687my-workspace/
···126117(e.g. perhaps you would like to mention `std`) — unfortunately, the preprocessor does
127118not yet support running without a Cargo project.
128119129129-Instead, you can setup your book project as a private, dummy crate.
120120+Instead, you can setup your book project as a private, dummy package.
130121131122```
132123my-book/