Block expressions - The Rust Reference

# Block expressions

> Syntax
> BlockExpression :
> `{`
> InnerAttribute\*
> Statements?
> `}`

> Statements :
> Statement\+
> | Statement\+ ExpressionWithoutBlock
> | ExpressionWithoutBlock

A block expression, or block, is a control flow expression and anonymous namespace scope for items and variable declarations. As a control flow expression, a block sequentially executes its component non-item declaration statements and then its final optional expression. As an anonymous namespace scope, item declarations are only in scope inside the block itself and variables declared by `let` statements are in scope from the next statement until the end of the block.

Blocks are written as `{`, then any inner attributes, then statements, then an optional expression, and finally a `}`. Statements are usually required to be followed a semicolon, with two exceptions. Item declaration statements do not need to be followed by a semicolon. Expression statements usually require a following semicolon except if its outer expression is a flow control expression. Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics.

> Note: The semicolon following a statement is not a part of the statement itself. They are invalid when using the `stmt` macro matcher.

When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially. Then the final expression is executed, if given.

The type of a block is the type of the final expression, or `()` if the final expression is omitted.

    # #![allow(unused_variables)]
    #fn main() {
    # fn fn_call() {}
    let _: () = {
        fn_call();
    };

    let five: i32 = {
        fn_call();
        5
    };

    assert_eq!(5, five);
    #}

> Note: As a control flow expression, if a block expression is the outer expression of an expression statement, the expected type is `()` unless it is followed immediately by a semicolon.

Blocks are always value expressions and evaluate the last expression in value expression context. This can be used to force moving a value if really needed. For example, the following example fails on the call to `consume_self` because the struct was moved out of `s` in the block expression.

    # #![allow(unused_variables)]
    #fn main() {
    struct Struct;

    impl Struct {
        fn consume_self(self) {}
        fn borrow_self(&self) {}
    }

    fn move_by_block_expression() {
        let s = Struct;

        // Move the value out of `s` in the block expression.
        (&{ s }).borrow_self();

        // Fails to execute because `s` is moved out of.
        s.consume_self();
    }
    #}

## `unsafe` blocks

> Syntax
> UnsafeBlockExpression :
> `unsafe` BlockExpression

See `unsafe` block for more information on when to use `unsafe`

A block of code can be prefixed with the `unsafe` keyword to permit unsafe operations. Examples:

    # #![allow(unused_variables)]
    #fn main() {
    unsafe {
        let b = [13u8, 17u8];
        let a = &b[0] as *const u8;
        assert_eq!(*a, 13);
        assert_eq!(*a.offset(1), 17);
    }

    # unsafe fn an_unsafe_fn() -> i32 { 10 }
    let a = unsafe { an_unsafe_fn() };
    #}

## Attributes on block expressions

Inner attributes are allowed directly after the opening brace of a block expression in the following situations:

- Function and method bodies.
- Loop bodies (`loop`, `while`, `while let`, and `for`).
- Block expressions used as a statement.
- Block expressions as elements of array expressions, tuple expressions, call expressions, tuple-style struct and enum variant expressions.
- A block expression as the tail expression of another block expression.

The attributes that have meaning on a block expression are `cfg` and the lint check attributes.

For example, this function returns `true` on unix platforms and `false` on other platforms.

    # #![allow(unused_variables)]
    #fn main() {
    fn is_unix_platform() -> bool {
        #[cfg(unix)] { true }
        #[cfg(not(unix))] { false }
    }
    #}