R
RUSTY YELLOW PAGES

/// (outer line doc comment)Comment


Explanation

/// documents the item immediately following it, and — unlike a plain // comment — is not discarded by the compiler: it's collected as a #[doc = "..."] attribute and rendered into generated documentation (cargo doc), as in /// Adds two numbers together. placed directly above the function it describes.

The content supports Markdown, and any fenced code block inside it is, by default, compiled and run as a doc test by cargo test — making /// double as both documentation and an executable example in one place. /// attaches to the item that follows it; intervening code or another item breaks the association (blank lines alone don't — a doc comment desugars to an outer #[doc = "..."] attribute, and whitespace between an attribute and its item is insignificant).

Usage examples

Documenting a function

/// <- this doc comment documents the function immediately below it
/// Adds two numbers together.
fn add(a: i32, b: i32) -> i32 {
    a + b
}

Restriction: /// documents the next item that follows it — any unrelated code or another item in between redirects (or breaks) the association. Blank lines alone are harmless.

Documenting an API

A well-formed /// comment leads with a one-line summary (used in listings/search), then expands with usage details — the shape cargo doc and IDE hover tooltips both render well.

/// Parses a duration string like `"5s"` or `"10m"` into whole seconds.
///
/// # Errors
///
/// Returns [`ParseError`] if `input` has no trailing unit character or
/// the numeric portion doesn't parse as an integer.
pub fn parse_duration(input: &str) -> Result<u64, ParseError> {
    // <- everything above is `///`; it documents this fn, not the body below
    todo!()
}

pub struct ParseError;

The summary-then-detail shape and the # Errors section heading are conventions from the rustdoc book and the API Guidelines' C-FAILURE — callers scanning generated docs expect failure conditions called out explicitly, not buried in prose.

Testing

By default, a fenced code block inside a /// comment on a library item is compiled and executed as a doc test by cargo test (annotations like no_run or ignore opt out) — making the documentation double as a regression test that fails loudly if the example ever stops compiling or returns something different.

/// Adds two numbers together.
///
/// ```
/// assert_eq!(my_crate::add(2, 3), 5); // <- this block runs under `cargo test`
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

A doc test is the one kind of example guaranteed to stay accurate — if add's behavior changes and the example wasn't updated, cargo test fails instead of leaving stale documentation on the page.

Designing a public API

Cross-referencing related items with an intra-doc link ([`Type`]) lets a reader jump straight from one API's docs to another's, without hand-written URLs that rot as the crate evolves.

/// The parsed result of [`parse_duration`].
///
/// See also [`Duration`](std::time::Duration) for the standard-library
/// equivalent once parsing is done.
pub struct ParsedDuration {
    pub seconds: u64,
}

Intra-doc links are resolved and checked by rustdoc itself — a broken reference becomes a build-time warning instead of a silently dead link, which the rustdoc book recommends over manual markdown links whenever the target is another item in the same doc set.

Explanation

Embedded support: Full

/// documents the following item identically under #![no_std]#[doc = "..."] generation is a host-side, compile-time step with no dependency on the target having std, a heap, or an OS. The one thing that does change in embedded code is doc tests: by default they compile and execute on the host, not on the microcontroller the crate targets — fine for a pure parsing function, but a doc test that calls into real registers has no hardware to run against and needs to opt out of execution.

Usage examples

Documenting a HAL function's safety contract

Embedded APIs lean on ///'s # Safety/# Errors conventions even more than hosted code, since the failure mode of an undocumented precondition is often silent hardware misbehavior rather than a caught error.

/// Sets GPIOA pin 5 high.
///
/// # Safety
///
/// Must not be called before `clocks::init()` — GPIOA is unclocked until
/// then and writes are silently ignored, not rejected.
pub unsafe fn set_pin_5_high() {
    // <- everything above is `///`; documents this fn's precondition, not its body
    // ...
}

Writing a doc test that can't run on the host

/// Reads the current tick count since boot.
///
/// ```no_run
/// // <- `no_run`: this compiles under `cargo test` but doesn't execute —
/// //    the host has no XYZ-100 timer peripheral to read from
/// let ticks = my_crate::tick_count::now();
/// assert!(ticks > 0);
/// ```
pub fn now() -> u64 {
    todo!()
}

Per the rustdoc book, no_run is exactly the tool for this: it still catches the example going stale at compile time (a signature change breaks the build) without requiring the doc test's host process to actually own the peripheral the real code depends on.