Hello World and Program Structure

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