compiler: implement destructuring syntax

This change implements the following syntax into the compiler:

```zig
const x: u32, var y, foo.bar = .{ 1, 2, 3 };
```

A destructure expression may only appear within a block (i.e. not at
comtainer scope). The LHS consists of a sequence of comma-separated var
decls and/or lvalue expressions. The RHS is a normal expression.

A new result location type, `destructure`, is used, which contains
result pointers for each component of the destructure. This means that
when the RHS is a more complicated expression, peer type resolution is
not used: each result value is individually destructured and written to
the result pointers. RLS is always used for destructure expressions,
meaning every `const` on the LHS of such an expression creates a true
stack allocation.

Aside from anonymous array literals, Sema is capable of destructuring
the following types:
* Tuples
* Arrays
* Vectors

A destructure may be prefixed with the `comptime` keyword, in which case
the entire destructure is evaluated at comptime: this means all `var`s
in the LHS are `comptime var`s, every lvalue expression is evaluated at
comptime, and the RHS is evaluated at comptime. If every LHS is a
`const`, this is not allowed: as with single declarations, the user
should instead mark the RHS as `comptime`.

There are a few subtleties in the grammar changes here. For one thing,
if every LHS is an lvalue expression (rather than a var decl), a
destructure is considered an expression. This makes, for instance,
`if (cond) x, y = .{ 1, 2 };` valid Zig code. A destructure is allowed
in almost every context where a standard assignment expression is
permitted. The exception is `switch` prongs, which cannot be
destructures as the comma is ambiguous with the end of the prong.

A follow-up commit will begin utilizing this syntax in the Zig compiler.

Resolves: #498
This commit is contained in:
mlugg
2023-08-31 14:30:58 +01:00
committed by Andrew Kelley
parent 50ef10eb49
commit 88f5315ddf
16 changed files with 1103 additions and 131 deletions

View File

@@ -4348,12 +4348,12 @@ test "zig fmt: invalid else branch statement" {
\\ for ("") |_| {} else defer {}
\\}
, &[_]Error{
.expected_statement,
.expected_statement,
.expected_statement,
.expected_statement,
.expected_statement,
.expected_statement,
.expected_expr_or_assignment,
.expected_expr_or_assignment,
.expected_expr_or_assignment,
.expected_expr_or_assignment,
.expected_expr_or_assignment,
.expected_expr_or_assignment,
});
}
@@ -6078,7 +6078,7 @@ test "recovery: missing for payload" {
try testError(
\\comptime {
\\ const a = for(a) {};
\\ const a: for(a) blk: {};
\\ const a: for(a) blk: {} = {};
\\ for(a) {}
\\}
, &[_]Error{