Comments
Comments are human-readable annotations in source code that the compiler ignores during code generation. Rust supports two styles of regular (non-documentation) comments: line comments starting with // and block comments enclosed between /* and */.
Comment Syntax Overview
| Syntax | Name | Scope | Nestable? |
|---|---|---|---|
// text |
Line comment | From // to the end of the current line |
N/A |
/* text */ |
Block comment | From /* to the matching */ (single-line or multi-line) |
Yes |
Note: Comments starting with three slashes (
///),//!,/**, or/*!are documentation comments, which are parsed into#[doc = "..."]attributes rather than discarded. Regular comments use strictly two slashes (//) or a single asterisk (/* ... */).
Line Comments (//)
A line comment begins with // and continues until the end of the line. It can occupy its own line or appear at the end of a line of code:
fn main() {
// Compute the perimeter of a rectangle.
// Idiomatic Rust uses `//` for both single-line and multi-line comments.
let width = 12; // width in centimeters
let height = 8; // height in centimeters
let perimeter = 2 * (width + height);
println!("Perimeter: {perimeter} cm");
}
Perimeter: 40 cm
In Rust style conventions (and rustfmt), // is the preferred comment style for almost all code comments, even when a comment spans multiple consecutive lines. Leave a single space after // for readability (// comment rather than //comment).
Block Comments (/* ... */)
A block comment begins with /* and ends with */. It can span multiple lines or sit inline between tokens on a single line:
fn main() {
/*
This is a multi-line block comment.
Everything between the opening and closing delimiters
is ignored by the compiler.
*/
let base = 10;
let multiplier = /* inline comment */ 3;
println!("Result: {}", base * multiplier);
}
Result: 30
Inline block comments are occasionally useful for temporarily commenting out a parameter or sub-expression inside a single line:
fn compute_total(price: u32, /* discount: u32, */ tax: u32) -> u32 {
price + tax
}
fn main() {
println!("Total: {}", compute_total(100, /* 15, */ 8));
}
Total: 108
Nested Block Comments
Unlike C, C++, Java, and JavaScript—where the very first */ closes a block comment and makes commenting out a region containing an existing /* ... */ comment a syntax error—Rust fully supports nested block comments.
The compiler counts opening /* and closing */ pairs and only ends the comment when the outer /* is matched:
fn main() {
/*
Outer block comment starts here.
let x = /* inner inline block comment */ 42;
/*
Second nested block comment.
*/
Outer block comment ends on the next line.
*/
println!("Nested block comments compile cleanly!");
}
Nested block comments compile cleanly!
/* Outer comment (depth = 1)
/* Inner comment (depth = 2) */ (depth returns to 1)
*/ Outer comment closes (depth = 0)
Because block comments nest cleanly, you can wrap any section of Rust source code in /* ... */ during debugging without worrying about existing /* ... */ comments inside that block.
Comment Delimiters Inside String Literals
Comment sequences (// and /* */) have no special meaning when they appear inside a string literal ("...") or raw string literal (r#"..."#). Inside quotes, they are treated as ordinary characters:
fn main() {
let url = "https://www.rust-lang.org";
let glob = "src/*/*.rs";
println!("URL: {url}");
println!("Glob: {glob}");
}
URL: https://www.rust-lang.org
Glob: src/*/*.rs
Conversely, string quotes inside a comment are ignored, even if a quote character is unmatched (such as an apostrophe in "don't"):
fn main() {
// Don't worry about unmatched single quotes or "double quotes inside a line comment.
/* Or an unmatched " double quote inside a block comment. */
println!("Quotes in comments are ignored.");
}
Quotes in comments are ignored.
Commenting Out Code vs #[cfg(false)]
While // or /* ... */ removes code at the lexical stage (meaning the commented-out text does not even have to be valid syntax), Rust also allows disabling syntactically valid code blocks or items using conditional compilation (#[cfg(any())] or if false):
| Technique | Syntax | Checked for Valid Syntax? | Type-Checked by rustc? |
|---|---|---|---|
| Line / block comment | // ... or /* ... */ |
No (raw text ignored by lexer) | No |
| Conditional compilation | #[cfg(any())] |
Yes (must parse as valid Rust syntax) | No |
| Dead branch | if false { ... } |
Yes | Yes (keeps code from bit-rotting) |
Common Errors
Unterminated Block Comment
Every opening /*—including nested ones—must have a matching closing */ before the end of the file:
// ❌ does not compile
fn main() {
/* Outer comment
/* Inner comment closed here: */
Missing the second closing delimiter!
println!("Hello");
}
error: unterminated block comment
--> src/main.rs:2:5
|
2 | / /* Outer comment
3 | | /* Inner comment closed here: */
4 | | Missing the second closing delimiter!
5 | | println!("Hello");
6 | | }
| |_^
error: aborting due to 1 previous error
Accidental Three-Slash (///) or /** Comment
Adding a third slash (///) or a second asterisk (/** ... */) turns a regular comment into a doc comment. If a doc comment is placed at the end of a block or before a statement that cannot take documentation attributes, the compiler emits an unused_doc_comments warning or syntax error:
fn main() {
/// Accidental three-slash comment inside a function body
let x = 10;
println!("{x}");
}
warning: unused doc comment
--> src/main.rs:2:5
|
2 | /// Accidental three-slash comment inside a function body
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for statements
3 | let x = 10;
| -----------
|
= help: use `//` for a plain comment
= note: `#[warn(unused_doc_comments)]` on by default