Assignment Statements

An assignment statement assigns a new value to a mutable variable.

assign_stmt = IDENT "=" expression ";"
            | IDENT "[" expression "]" "=" expression ";"
            | expression "." IDENT "=" expression ";" ;

Variable Assignment

The variable MUST have been declared with let mut.

The expression type MUST be compatible with the variable's type.

fn main() -> i32 {
    let mut x = 0;
    x = 42;
    x
}

Array Element Assignment

Array element assignment requires a mutable array.

fn main() -> i32 {
    let mut arr: [i32; 2] = [0, 0];
    arr[0] = 20;
    arr[1] = 22;
    arr[0] + arr[1]
}

Struct Field Assignment

Struct field assignment requires a mutable struct value.

struct Point { x: i32, y: i32 }

fn main() -> i32 {
    let mut p = Point { x: 0, y: 0 };
    p.x = 42;
    p.x
}

Nested Field Assignment

Fields of nested structs can be assigned through chained field access.

All struct values in the chain MUST be part of a mutable binding.

struct Inner { value: i32 }
struct Outer { inner: Inner }

fn main() -> i32 {
    let mut o = Outer { inner: Inner { value: 0 } };
    o.inner.value = 42;
    o.inner.value
}

Drop Semantics on Assignment

When a mutable variable is reassigned, if the previous value has not been moved, the previous value is dropped before the new value is written.

When a struct field or array element is assigned, the previous value at that location is dropped before the new value is written.

struct Data { value: i32 }

drop fn Data(self) {
    @dbg(self.value);
}

fn main() -> i32 {
    let mut x = Data { value: 1 };
    x = Data { value: 2 };  // Data { value: 1 } is dropped here, prints "1"
    0
}  // Data { value: 2 } is dropped here, prints "2"

Assignment is Not an Expression

Assignment is a statement, not an expression. It MUST NOT be used in expression position.