Variable Declarations and Assignment¶
Overview¶
Local variables are declared with let and initialized with an expression. Assignment updates the value of an existing variable.
Syntax¶
Rules¶
Mandatory Initialization¶
Variable declarations MUST include an initializer.
Type Inference¶
The type MUST be inferred from the initializer expression. Explicit type annotations on local variable declarations MUST NOT be supported. Function parameters and return types are the only declarations that MUST be explicitly typed.
Local variables MUST NOT infer a raw struct value type. A local variable type MUST be a primitive type, function pointer type, handle type, or capability type.
Assignment¶
Assignment updates the value of an existing lvalue. Lvalues include variables, struct member access results, and slice index results. The type of the assigned expression MUST be implicitly convertible to the lvalue's type. All primitive types MUST be implicitly convertible to all other primitive types during assignment. Capability values and function pointer values MUST be copyable when the source and destination types are identical. A handle-bearing lvalue MUST be transferred with move; a handle-bearing rvalue, as defined in Move Semantics, MAY be assigned directly. Handles MUST NOT be implicitly converted. Function pointers MUST NOT be implicitly converted between distinct function pointer types.
Shadowing Prohibition¶
Redeclaring a variable MUST produce a compile error. Shadowing is STRICTLY PROHIBITED.
Variable Scope¶
Variables declared with let MUST be block-scoped. A variable MUST only be accessible within the braced block in which it is declared. A variable MUST NOT be accessible outside its declaring block.
Primitive Conversion Semantics¶
When a primitive value is converted to bool, zero or 0.0 MUST become false and any non-zero value MUST become true. When a primitive value is converted between integer types, widening MUST preserve the numeric value when representable, signed types MUST sign-extend, unsigned types MUST zero-extend, and narrowing MUST truncate the high bits. When a signed integer is converted to an unsigned integer of the same width, the bit pattern MUST be preserved. When an unsigned integer is converted to a signed integer of the same width, the bit pattern MUST be preserved. When a floating-point value is converted to an integer, the fractional part MUST be discarded (truncation toward zero). When an integer is converted to a floating-point type, the value MUST be rounded to the nearest representable value. When a floating-point value is converted to another floating-point type, the value MUST be rounded to the nearest representable value. Runtime integer overflow during conversion MUST wrap according to two's complement arithmetic.