Documentation Comments
Documentation comments (or doc comments) are special comments in Rust source code that are preserved in the compiler's Abstract Syntax Tree (AST) as #[doc = "..."] attributes rather than being discarded during lexing like ordinary // or /* ... */ comments. The rustdoc tool extracts these attributes to generate searchable HTML API reference documentation and executable documentation tests.
Source Code Comments:
|-- Regular comment: `// internal note` --> Stripped by lexer (ignored by rustdoc)
|-- Outer doc comment: `/// Returns sum` --> Desugars to `#[doc = " Returns sum"]`
+-- Inner doc comment: `//! Crate overview` --> Desugars to `#![doc = " Crate overview"]`
Regular Comments vs Documentation Comments
| Comment Syntax | Name | Desugared Attribute Form | Target Item | Processed by rustdoc? |
|---|---|---|---|---|
// ... |
Line comment | (Discarded at lexing) | None | No |
/* ... */ |
Block comment | (Discarded at lexing) | None | No |
/// ... |
Outer line doc comment | #[doc = "..."] |
The item immediately following the comment | Yes |
/** ... */ |
Outer block doc comment | #[doc = "..."] |
The item immediately following the comment | Yes |
//! ... |
Inner line doc comment | #![doc = "..."] |
The enclosing module or crate containing the comment | Yes |
/*! ... */ |
Inner block doc comment | #![doc = "..."] |
The enclosing module or crate containing the comment | Yes |
How the Compiler Desugars Doc Comments into #[doc = "..."]
Every /// line is syntactic sugar for a #[doc = "..."] attribute attached to the item below it. Multiple consecutive /// lines are concatenated with newline characters (\n) between them.
Because /// and #[doc = "..."] are identical to the compiler, you can even generate or include external Markdown files directly as documentation using #[doc = include_str!("../README.md")]:
//! Crate-level documentation for the geometry utilities module.
/// Computes the area of a rectangle.
#[doc = ""]
#[doc = "This second paragraph is written with an explicit `#[doc]` attribute,"]
#[doc = "which merges seamlessly with the `///` line above."]
pub fn rectangle_area(width: u32, height: u32) -> u64 {
(width as u64) * (height as u64)
}
fn main() {
println!("Area of 12x8 rectangle: {}", rectangle_area(12, 8));
}
Area of 12x8 rectangle: 96
Compiler Lints for Orphaned Doc Comments (unused_doc_comments)
Because a doc comment is an attribute (#[doc = "..."]), it must be attached to a valid documentable item (such as a function, struct, enum, trait, module, const, or field). Placing /// above a let statement inside a function body or at the end of a block with no item following it triggers a compiler warning or error:
// ❌ does not compile
fn main() {
/// Orphaned doc comment at the end of a block with no item following it
}
error: expected item after doc comment
--> src/main.rs:2:5
|
2 | /// Orphaned doc comment at the end of a block with no item following it
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use ordinary // comments for implementation notes inside function bodies, and reserve /// and //! for documenting module, type, and function declarations.