不稳定特性

Rustdoc 正在积极开发中,与 Rust 编译器一样,某些特性仅在 nightly 版本中可用。其中一些特性是新的,需要更多测试才能发布到全世界,而另一些特性则与 Rust 编译器中不稳定的特性相关联。这里有几个特性需要匹配的 #![feature(...)] 属性来启用,因此在 不稳定手册 中有更完整的文档。这些部分将在必要时链接到那里。

Nightly 限制的功能

这些特性只需要 nightly 构建才能运行。与本页上的其他特性不同,这些特性不需要使用命令行标志或在您的板条箱中使用 #![feature(...)] 属性来“打开”。这可以为它们提供一些在稳定版本上使用时的微妙回退模式,因此请谨慎!

compile-fail doctests 的错误号

文档测试章节 中所述,您可以向 doctest 添加 compile_fail 属性,以声明该测试应该编译失败。但是,在 nightly 上,您可以选择添加一个错误号,以声明 doctest 应该发出特定的错误号

```compile_fail,E0044
extern { fn some_func<T>(x: T); }
```

这由错误索引使用,以确保与给定错误号相对应的示例正确发出该错误代码。但是,这些错误代码不能保证是代码片段从版本到版本发出的唯一内容,因此这不太可能在将来稳定下来。

尝试在稳定版本上使用这些错误号会导致代码示例被解释为纯文本。

missing_doc_code_examples lint

如果项目在文档中没有代码示例,则此 lint 会发出警告。可以使用以下方法启用它

#![deny(rustdoc::missing_doc_code_examples)]

#[doc] 属性的扩展

这些特性通过扩展 #[doc] 属性来运行,因此可以被编译器捕获并使用您的板条箱中的 #![feature(...)] 属性启用。

#[doc(cfg)]:记录代码存在所需的平台或特性

您可以使用 #[doc(cfg(...))] 来告诉 Rustdoc 确切地哪些平台项目出现在哪些平台上。这有两个效果

  1. doctests 仅在适当的平台上运行,以及
  2. 当 Rustdoc 渲染该项目的文档时,它将伴随着一个横幅,解释该项目仅在某些平台上可用。

#[doc(cfg)] 旨在与 #[cfg(doc)] 一起使用。例如,#[cfg(any(windows, doc))] 将在 Windows 上或在文档过程中保留该项目。然后,添加一个新的属性 #[doc(cfg(windows))] 将告诉 Rustdoc 该项目应该在 Windows 上使用。例如

#![allow(unused)]
#![feature(doc_cfg)]

fn main() {
/// Token struct that can only be used on Windows.
#[cfg(any(windows, doc))]
#[doc(cfg(windows))]
pub struct WindowsToken;

/// Token struct that can only be used on Unix.
#[cfg(any(unix, doc))]
#[doc(cfg(unix))]
pub struct UnixToken;

/// Token struct that is only available with the `serde` feature
#[cfg(feature = "serde")]
#[doc(cfg(feature = "serde"))]
#[derive(serde::Deserialize)]
pub struct SerdeToken;
}

在这个示例中,令牌仅在其各自的平台上出现,但它们都将出现在文档中。

#[doc(cfg(...))] 是为了被标准库使用而引入的,目前需要 #![feature(doc_cfg)] 特性门。有关更多信息,请参阅 不稳定手册中的章节其跟踪问题

doc_auto_cfg:自动生成 #[doc(cfg)]

doc_auto_cfg#[doc(cfg)] 特性的扩展。有了它,您不再需要添加 #[doc(cfg(...)],除非您想覆盖默认行为。因此,如果我们采用前面的源代码

#![allow(unused)]
#![feature(doc_auto_cfg)]

fn main() {
/// Token struct that can only be used on Windows.
#[cfg(any(windows, doc))]
pub struct WindowsToken;

/// Token struct that can only be used on Unix.
#[cfg(any(unix, doc))]
pub struct UnixToken;

/// Token struct that is only available with the `serde` feature
#[cfg(feature = "serde")]
#[derive(serde::Deserialize)]
pub struct SerdeToken;
}

它将渲染几乎相同的内容,区别在于 doc 也将被显示。要解决此问题,您可以使用 doc_cfg_hide

#![allow(unused)]
#![feature(doc_cfg_hide)]
#![doc(cfg_hide(doc))]
fn main() {
}

doc 将不再显示!

将您的特征添加到“著名特征”对话框中

Rustdoc 保持一个被认为对实现它们的类型“基本”的特征列表。这些特征旨在成为其实现者的主要接口,并且通常是其类型上可供记录的 API 的大部分。出于这个原因,Rustdoc 会跟踪给定类型何时实现这些特征之一,并在函数返回这些类型之一时对其特别关注。这是“著名特征”对话框,可以通过函数旁边的带圆圈的 i 按钮访问,单击该按钮会显示对话框。

在标准库中,此列表中的一些特征是 IteratorFutureio::Readio::Write。但是,它们不是作为硬编码列表实现的,而是具有一个特殊的标记属性:#[doc(notable_trait)]。这意味着您可以将此属性应用于您自己的特征,以将其包含在文档中的“著名特征”对话框中。

#[doc(notable_trait)] 属性目前需要 #![feature(doc_notable_trait)] 特性门。有关更多信息,请参阅 不稳定手册中的章节其跟踪问题

从文档中排除某些依赖项

标准库使用几个依赖项,这些依赖项反过来又使用标准库中的几个类型和特征。此外,还有几个编译器内部板条箱不被认为是官方标准库的一部分,因此将它们包含在文档中会分散注意力。仅仅排除它们的板条箱文档是不够的,因为关于特征实现的信息会出现在类型和特征的页面上,而这些页面可能在不同的板条箱中!

为了防止内部类型包含在文档中,标准库将其 extern crate 声明中添加了一个属性:#[doc(masked)]。这会导致 Rustdoc 在构建特征实现列表时“屏蔽”来自这些板条箱的类型。

#[doc(masked)] 属性旨在用于内部,并且需要 #![feature(doc_masked)] 特性门。有关更多信息,请参阅 不稳定手册中的章节其跟踪问题

记录基本类型

这仅供 Rust 编译器内部使用。

由于基本类型是在编译器中定义的,因此没有地方可以附加文档属性。#[rustc_doc_primitive = "..."] 属性由标准库使用,以提供一种为基本类型生成文档的方法,并且需要 #![feature(rustc_attrs)] 来启用。

记录关键字

这仅供 Rust 编译器内部使用。

Rust 关键字在标准库中记录(例如,查找 match)。

为此,使用 #[doc(keyword = "...")] 属性。示例

#![allow(unused)]
#![feature(rustdoc_internals)]
#![allow(internal_features)]

fn main() {
/// Some documentation about the keyword.
#[doc(keyword = "keyword")]
mod empty_mod {}
}

这仅供官方 Rust 项目使用。

像 settings.html 和 scrape-examples-help.html 这样的内部 Rustdoc 页面显示 Rust 徽标。此徽标被跟踪为静态资源。#![doc(rust_logo)] 属性使此相同的内置资源充当主徽标。

#![allow(unused)]
#![feature(rustdoc_internals)]
#![allow(internal_features)]
#![doc(rust_logo)]
fn main() {
//! This crate has the Rust(tm) branding on it.
}

其他 nightly 特性的影响

这些仅限 nightly 的特性与 Rustdoc 的关系不大,但对生成的文档有方便的影响。

fundamental 类型

#[fundamental] 注释类型主要影响关于泛型类型的连贯性规则,即它们会改变其他板条箱是否可以为该类型提供实现。不稳定手册 链接到更多信息

对于文档,这有一个额外的副作用:如果在 F<T>(或 F<&T>)上实现了方法,其中 F 是一个基本类型,那么该方法不仅在关于 F 的页面上记录,而且还在关于 T 的页面上记录。从某种意义上说,它使类型对 Rustdoc 透明。这对于充当注释指针的类型(例如 Pin<&mut T>)特别方便,因为它确保了仅通过这些注释指针实现的方法仍然可以在它们作用的类型上找到。

如果 fundamental 特性对连贯性的影响并非预期,则可以通过引入自定义特性并将 fundamental 的使用限制在构建文档时,将此类类型标记为仅用于文档目的的基本类型。

不稳定的命令行参数

这些特性通过将命令行标志传递给 Rustdoc 来启用,但这些标志本身被标记为不稳定。要使用任何这些选项,请将 -Z unstable-options 以及要查询的标志传递给命令行上的 Rustdoc。要从 Cargo 中执行此操作,您可以使用 RUSTDOCFLAGS 环境变量或 cargo rustdoc 命令。

--markdown-before-content:在内容之前包含渲染的 Markdown

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --markdown-before-content extra.md
$ rustdoc README.md -Z unstable-options --markdown-before-content extra.md

就像 --html-before-content 一样,这允许您在 <body> 标签内但 rustdoc 通常在渲染的文档中生成的其他内容之前插入额外的内容。但是,rustdoc 不会直接插入文件,而是会将文件通过 Markdown 渲染器传递,然后将结果插入文件。

--markdown-after-content:在内容之后包含渲染的 Markdown

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --markdown-after-content extra.md
$ rustdoc README.md -Z unstable-options --markdown-after-content extra.md

就像 --html-after-content 一样,这允许您在 </body> 标签之前但 rustdoc 通常在渲染的文档中生成的其他内容之后插入额外的内容。但是,rustdoc 不会直接插入文件,而是会将文件通过 Markdown 渲染器传递,然后将结果插入文件。

--playground-url:控制游乐场的地址

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --playground-url https://play.rust-lang.org/

渲染板条箱文档时,此标志提供 Rust 游乐场的基地址,用于生成 Run 按钮。与 --markdown-playground-url 不同,此参数适用于独立的 Markdown 文件 *和* Rust 板条箱。这与在板条箱根目录中添加 #![doc(html_playground_url = "url")] 的方式相同,如 关于 #[doc] 属性的章节 中所述。请注意,https://play.rust-lang.org 上的官方 Rust 游乐场并不提供所有板条箱,因此,如果您的示例需要您的板条箱,请确保您提供的游乐场提供您的板条箱。

如果在渲染独立的 Markdown 文件时同时存在 --playground-url--markdown-playground-url,则传递给 --markdown-playground-url 的 URL 将优先。如果在渲染板条箱文档时同时存在 --playground-url#![doc(html_playground_url = "url")],则属性将优先。

--sort-modules-by-appearance:控制模块页面上项目排序的方式

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --sort-modules-by-appearance

通常,当 rustdoc 在模块页面中打印项目时,它会按字母顺序对它们进行排序(考虑它们的稳定性以及以数字结尾的名称)。将此标志传递给 rustdoc 将禁用此排序,而是使其按它们在源代码中出现的顺序打印项目。

--show-type-layout:在每个类型的文档中添加一个部分,描述其内存布局

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --show-type-layout

如果传递此标志,rustdoc 将在每个类型的文档页面底部添加一个“布局”部分,其中包含 rustc 计算出的类型内存布局的摘要。例如,rustdoc 将显示该类型的值在内存中占用的字节大小。

请注意,大多数布局信息是**完全不稳定的**,甚至可能在编译之间有所不同。

--resource-suffix:修改箱子文档中 CSS/JavaScript 的名称

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --resource-suffix suf

在渲染文档时,rustdoc 会创建几个 CSS 和 JavaScript 文件作为输出的一部分。由于所有这些文件都从每个页面链接,因此如果您需要专门缓存它们,更改它们的位置可能会很麻烦。此标志将重命名输出中的所有这些文件,以在文件名中包含后缀。例如,light.css 将使用上面的命令变为 light-suf.css

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --extern-html-root-url some-crate=https://example.com/some-crate/1.0.1

通常,当 rustdoc 想要链接到来自不同箱子的类型时,它会在两个地方查找:输出目录中已存在的文档,或在另一个箱子中设置的 #![doc(doc_html_root)]。但是,如果您想链接到这两个地方都不存在的文档,可以使用这些标志来控制这种行为。当 --extern-html-root-url 标志与您的依赖项之一的名称匹配时,rustdoc 将使用该 URL 作为这些文档的 URL。请记住,如果这些文档存在于输出目录中,这些本地文档将仍然覆盖此标志。

-Z force-unstable-if-unmarked

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z force-unstable-if-unmarked

这是一个针对标准库和编译器的内部标志,它将 #[unstable] 属性应用于任何没有其他稳定性属性的依赖箱子。这允许 rustdoc 能够为编译器箱子和标准库生成文档,因为在构建这些箱子时会向 rustc 提供一个等效的命令行参数。

--index-page:为文档提供一个顶级登录页面

此功能允许您使用给定的 Markdown 文件生成一个索引页面。一个很好的例子是 Rust 文档索引

有了它,您将拥有一个页面,您可以在箱子顶部尽可能地自定义它。

使用 index-page 选项也会启用 enable-index-page 选项。

--enable-index-page:为文档生成一个默认的索引页面

此功能允许生成一个默认的索引页面,其中列出了生成的箱子。

--nocapture:禁用测试的输出捕获

当此标志与 --test 一起使用时,测试的输出(stdout 和 stderr)不会被 rustdoc 捕获。相反,输出将被定向到您的终端,就像您手动运行测试可执行文件一样。这对于调试测试特别有用!

--check:仅检查文档

当提供此标志时,rustdoc 将对您的代码进行类型检查和 lint,但不会生成任何文档或运行您的 doctest。

使用此标志看起来像

rustdoc -Z unstable-options --check src/lib.rs

--static-root-path:控制静态文件如何在 HTML 输出中加载

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --static-root-path '/cache/'

此标志控制 rustdoc 如何在 HTML 页面上链接到其静态文件。如果您托管了许多由相同版本的 rustdoc 生成的箱子文档,则可以使用此标志将 rustdoc 的 CSS、JavaScript 和字体文件缓存到一个位置,而不是在每个“文档根目录”(将箱子文档分组到同一个输出目录中,例如使用 cargo doc)中复制一次。每个箱子的文件(如搜索索引)仍然会从文档根目录加载,但任何使用 --resource-suffix 重命名的文件都将从给定的路径加载。

--persist-doctests:在运行后保留 doctest 可执行文件

使用此标志看起来像这样

$ rustdoc src/lib.rs --test -Z unstable-options --persist-doctests target/rustdoctest

此标志允许您在编译或运行 doctest 可执行文件后保留它们。通常,rustdoc 会在测试完编译后的 doctest 后立即将其丢弃,但使用此选项,您可以保留这些二进制文件以进行进一步测试。

--show-coverage:计算有文档的项目的百分比

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --show-coverage

它会生成类似这样的内容

+-------------------------------------+------------+------------+------------+------------+
| File                                | Documented | Percentage |   Examples | Percentage |
+-------------------------------------+------------+------------+------------+------------+
| lib.rs                              |          4 |     100.0% |          1 |      25.0% |
+-------------------------------------+------------+------------+------------+------------+
| Total                               |          4 |     100.0% |          1 |      25.0% |
+-------------------------------------+------------+------------+------------+------------+

如果您想确定箱子中有多少项目有文档,请将此标志传递给 rustdoc。当它收到此标志时,它将计算箱子中具有文档的公共项目,并打印出计数和百分比,而不是生成文档。

关于 rustdoc 在此指标中计算的内容的一些方法说明

  • rustdoc 只会计算来自您箱子的项目(即从其他箱子重新导出的项目不计入)。
  • 直接写入内在实现块的文档不计入,即使它们的文档注释被显示,因为 Rust 代码中的常见模式是将所有内在方法写入同一个实现块。
  • 特征实现中的项目不计入,因为这些实现将继承特征本身的任何文档。
  • 默认情况下,只计算公共项目。要同时计算私有项目,请传递 --document-private-items

可以使用内置的 missing_docs lint 查看没有文档的公共项目。可以使用 Clippy 的 missing_docs_in_private_items lint 查看没有文档的私有项目。

计算代码示例遵循以下规则

  1. 这些项目默认情况下不计入
  • 结构体/联合体字段
  • 枚举变体
  • 常量
  • 静态变量
  • 类型定义
  1. 如果先前列出的项目之一有代码示例,则它将被计入。

JSON 输出

当使用 --output-format json 以及此选项时,它将以 JSON 格式显示覆盖率信息。例如,以下是包含一个有文档的项目和一个没有文档的项目的 JSON

#![allow(unused)]
fn main() {
/// This item has documentation
pub fn foo() {}

pub fn no_documentation() {}
}
{"no_std.rs":{"total":3,"with_docs":1,"total_examples":3,"with_examples":0}}

请注意,第三个项目是箱子根目录,在本例中没有文档。

-w/--output-format:输出格式

--output-format json 以实验性的 JSON 格式 导出文档。--output-format html 没有效果,并且在稳定版工具链上也被接受。

工具链箱子(stdalloccoretestproc_macro)的 JSON 输出可通过 rust-docs-json rustup 组件获得。

rustup component add --toolchain nightly rust-docs-json

然后 JSON 文件将出现在 rustup 工具链目录的 share/doc/rust/json/ 目录中。

它也可以与 --show-coverage 一起使用。查看其 文档 以获取更多信息。

--enable-per-target-ignores:允许 ignore-foo 样式的过滤器用于 doctest

使用此标志看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores

此标志允许您使用 compiletest 样式的 ignore-foo 过滤器标记 doctest,如果目标三元组字符串包含 foo,则阻止 rustdoc 运行该测试。例如

#![allow(unused)]
fn main() {
///```ignore-foo,ignore-bar
///assert!(2 == 2);
///```
struct Foo;
}

当构建目标为 super-awesome-fooless-bar-awesome 时,这将不会运行。如果未启用此标志,则 rustdoc 将使用该过滤器,但不会对其进行任何操作,并且上面的示例将在所有目标上运行。如果您想为旧版本的 rustdoc 保留向后兼容性,可以使用

#![allow(unused)]
fn main() {
///```ignore,ignore-foo
///assert!(2 == 2);
///```
struct Foo;
}

在旧版本中,这将在所有目标上被忽略,但在新版本中,ignore-gnu 将覆盖 ignore

--runtool--runtool-arg:用于运行测试的程序;要传递给它的参数

使用这些选项看起来像这样

$ rustdoc src/lib.rs -Z unstable-options --runtool runner --runtool-arg --do-thing --runtool-arg --do-other-thing

这些选项可用于在程序下运行 doctest,并将参数传递给该程序。例如,如果您想在 valgrind 下运行 doctest,您可能会运行

$ rustdoc src/lib.rs -Z unstable-options --runtool valgrind

另一个用例是在模拟器中或通过虚拟机运行测试。

--with-examples:将项目的用法示例作为文档包含进来

此选项与 --scrape-examples-target-crate--scrape-examples-output-path 结合使用,用于实现 RFC #3123 中的功能。在箱子及其反向依赖项中找到项目的用法(目前是函数/调用站点),然后将这些用法作为该项目的文档包含进来。此功能旨在通过 cargo doc --scrape-examples 使用,但仅 rustdoc 的工作流程看起来像

$ rustdoc examples/ex.rs -Z unstable-options \
    --extern foobar=target/deps/libfoobar.rmeta \
    --scrape-examples-target-crate foobar \
    --scrape-examples-output-path output.calls
$ rustdoc src/lib.rs -Z unstable-options --with-examples output.calls

首先,必须检查库以生成 rmeta。然后,将像 examples/ex.rs 这样的反向依赖项传递给 rustdoc,目标箱子是正在记录的箱子(foobar),以及一个输出调用的路径(output.calls)。然后,生成的调用文件可以通过 --with-examples 传递给 foobar 的后续文档。

要从测试代码中抓取示例,例如标记为 #[test] 的函数,请添加 --scrape-tests 标志。

此标志启用在源代码页面中生成链接,允许读者跳转到类型定义。

代码块的自定义 CSS 类

#![allow(unused)]
#![feature(custom_code_classes_in_docs)]

fn main() {
/// ```custom,{class=language-c}
/// int main(void) { return 0; }
/// ```
pub struct Bar;
}

文本 int main(void) { return 0; } 在具有 language-c 类的代码块中渲染时没有突出显示。这可用于通过 JavaScript 库等突出显示其他语言。

如果没有 `custom` 属性,它将被生成为一个 Rust 代码示例,并附加一个 `language-C` CSS 类。因此,如果您明确不希望它成为一个 Rust 代码示例,请不要忘记添加 `custom` 属性。

需要注意的是,您可以用 `.` 替换 `class=` 来达到相同的效果。

#![allow(unused)]
#![feature(custom_code_classes_in_docs)]

fn main() {
/// ```custom,{.language-c}
/// int main(void) { return 0; }
/// ```
pub struct Bar;
}

需要注意的是,`rust` 和 `.rust`/`class=rust` 的效果不同:`rust` 表示这是一个 Rust 代码块,而另外两个则在代码块上添加一个 "rust" CSS 类。

您也可以使用双引号。

#![allow(unused)]
#![feature(custom_code_classes_in_docs)]

fn main() {
/// ```"not rust" {."hello everyone"}
/// int main(void) { return 0; }
/// ```
pub struct Bar;
}