RustDocumentation & rustdoc

Documentation & rustdoc

Rust treats documentation as a core part of the language toolchain. The rustdoc tool ships with every Rust installation and can generate polished HTML documentation directly from your source code. The convention of keeping docs and code together means your documentation never drifts out of sync — and the doc tests ensure the examples actually compile and run.

Outer Doc Comments with ///

Lines that begin with /// are outer doc comments — they document the item that immediately follows. You can place them on functions, structs, enums, traits, type aliases, modules, and more.

RUST
/// Returns the sum of two integers.
///
/// Both values must fit within `i32`. For larger numbers use `i64`.
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// A point in two-dimensional space.
pub struct Point {
    /// The horizontal position.
    pub x: f64,
    /// The vertical position.
    pub y: f64,
}
Tip
Field-level doc comments (/// ... above a struct field) appear in the generated HTML alongside the field name and type. Document your public fields — users will thank you.
Inner Doc Comments with //!

Lines that begin with //! are inner doc comments — they document the item they are inside, rather than the item that follows. Place them at the very top of a file to document the whole module or crate.

RUST
//! # my_crate
//!
//! A collection of math utilities for everyday arithmetic.
//!
//! ## Quick start
//!
//! ```
//! use my_crate::add;
//! assert_eq!(add(1, 2), 3);
//! ```

pub mod arithmetic;
pub mod geometry;
Note
The //! comments at the top of lib.rs become the crate-level documentation visible on docs.rs — the first thing users read. Invest in a clear overview, a quick-start example, and links to the main types.
Markdown in Doc Comments

rustdoc renders all doc comments as Markdown. You can use headings, code spans, bold, italic, bulleted lists, numbered lists, tables, and links — all the standard Markdown syntax.

RUST
/// Parses a configuration file and returns the settings.
///
/// ## Supported formats
///
/// - `TOML` (recommended)
/// - `JSON`
///
/// ## Format
///
/// The file must contain a `[server]` section with at least a `port` key.
///
/// | Key    | Type   | Default |
/// |--------|--------|---------|
/// | port   | u16    | 8080    |
/// | host   | String | "localhost" |
///
/// **Note:** unknown keys are silently ignored.
pub fn parse_config(path: &str) -> Config {
    todo!()
}
The # Examples Section

The # Examples heading is a widely recognised convention in the Rust ecosystem. rustdoc renders it prominently near the top of the item's documentation page, and code blocks inside it are automatically run as doc tests by cargo test.

RUST
/// Divides two numbers.
///
/// # Examples
///
/// ```
/// use my_crate::divide;
/// assert_eq!(divide(10, 2), 5.0);
/// ```
pub fn divide(a: f64, b: f64) -> f64 {
    a / b
}
Success
Every code example under # Examples is a live test. If you refactor the function signature later and forget to update the docs, the doc test will catch it immediately.
The # Panics Section

Document every condition under which a function can panic. Users who call your code need to know what invariants to uphold so they can avoid unexpected runtime crashes.

RUST
/// Returns the element at the given index.
///
/// # Panics
///
/// Panics if `index` is out of bounds (greater than or equal to the slice length).
pub fn get_element(slice: &[i32], index: usize) -> i32 {
    slice[index]
}
The # Errors Section

For functions that return Result, document the error variants callers may encounter and under what conditions each is returned.

RUST
use std::io;

/// Reads the entire contents of a file into a string.
///
/// # Errors
///
/// Returns `io::Error` if:
/// - The file does not exist (`ErrorKind::NotFound`)
/// - The process lacks read permission (`ErrorKind::PermissionDenied`)
/// - The file contains invalid UTF-8 bytes
pub fn read_file(path: &str) -> Result<String, io::Error> {
    std::fs::read_to_string(path)
}
The # Safety Section

Any function marked unsafe must include a # Safety section that describes exactly what invariants the caller must uphold to avoid undefined behaviour.

RUST
/// Dereferences a raw pointer and returns the value.
///
/// # Safety
///
/// The caller must ensure that:
/// - `ptr` is non-null.
/// - `ptr` points to a valid, initialised `T`.
/// - No other code mutates the pointed-to value while this reference is live.
pub unsafe fn deref_raw<T>(ptr: *const T) -> &'static T {
    &*ptr
}
Warning
Skipping the # Safety section on an unsafe fn is considered a serious documentation bug in the Rust community. Tools like Clippy can warn about missing safety documentation.
Doc Tests

Code blocks inside /// comments that are fenced with triple backticks are automatically compiled and executed by cargo test. This makes it impossible for your examples to silently go stale.

RUST
/// ```
/// let x = my_crate::add(2, 3);
/// assert_eq!(x, 5);
/// ```

To hide a line from the rendered docs while still running it in the test, prefix the line with # (hash followed by a space):

RUST
/// ```
/// # use my_crate::Config;   // hidden setup — not shown in docs
/// let cfg = Config::default();
/// assert_eq!(cfg.port, 8080);
/// ```
Tip
Mark a doc-test block as no_run to compile it but not execute it — useful for examples that require a running database or network connection: ```rust,no_run. Use ```rust,ignoreto skip compilation entirely (last resort — the example may rot).
Linking to Other Items

rustdoc supports intra-doc links: wrap an item name in square brackets and rustdoc generates a hyperlink to that item's documentation page automatically.

RUST
/// Converts a `Config` into a `Server`.
///
/// See also: [Config], [Server::run], [crate::utils::validate]
pub fn build_server(cfg: Config) -> Server {
    todo!()
}
Note
If the link target is ambiguous (e.g. a function and a struct share a name), disambiguate with a prefix: [fn@name], [struct@name],[trait@name], and so on.
Generating Docs with cargo doc

Bash
cargo doc               # generate docs into target/doc/
cargo doc --open        # generate and open in your browser
cargo doc --no-deps     # only document your crate (skip dependencies)

The generated HTML is placed in target/doc/&lt;crate_name&gt;/index.html. The --no-deps flag is especially useful in large workspaces where generating docs for every transitive dependency would take minutes.

docs.rs: Automatic Hosting

When you publish a crate to crates.io, docs.rs automatically builds and hosts the documentation for every version. The URL follows a predictable pattern:

https://docs.rs/&lt;crate_name&gt;/&lt;version&gt;

docs.rs also builds docs for all feature combinations and target platforms, and it retains docs for every published version of your crate.

The #[doc] Attribute

Under the hood, /// doc comments are syntactic sugar for the #[doc = "..."] attribute. You rarely need this directly, but it is useful when generating doc strings programmatically via macros.

RUST
#[doc = "Returns the absolute value of a number."]
#[doc = ""]
#[doc = "# Examples"]
#[doc = ""]
#[doc = "```"]
#[doc = "assert_eq!(my_crate::abs(-5), 5);"]
#[doc = "```"]
pub fn abs(n: i32) -> i32 {
    n.abs()
}
pub use Re-exports and Docs

When you re-export an item with pub use, rustdoc includes that item in the documentation of the re-exporting module. This is a common technique for creating a clean, flat public API from a deeply nested internal module structure.

RUST
// src/lib.rs
//! This crate exposes `Server` and `Config` at the top level.

mod server;
mod config;

pub use server::Server;   // re-exported — appears in lib docs
pub use config::Config;   // re-exported — appears in lib docs
Tip
Keep your re-exports consistent with your public API story. If users are expected to type \`use my_crate::Server\`, make sure \`Server\` is re-exported at the crate root — even if it lives deep in the module tree internally.