assignDestructure
Handles destructure assignments where no LHS is a const or var decl.
Function parameters
Parameters
- gz:*GenZir
- scope:*Scope
- node:Ast.Node.Index
Functions in this namespace
Functions
Source
Implementation
fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!void {
try emitDbgNode(gz, node);
const astgen = gz.astgen;
const tree = astgen.tree;
const full = tree.assignDestructure(node);
if (full.comptime_token != null and gz.is_comptime) {
return astgen.appendErrorNode(node, "redundant comptime keyword in already comptime scope", .{});
}
// If this expression is marked comptime, we must wrap the whole thing in a comptime block.
var gz_buf: GenZir = undefined;
const inner_gz = if (full.comptime_token) |_| bs: {
gz_buf = gz.makeSubBlock(scope);
gz_buf.is_comptime = true;
break :bs &gz_buf;
} else gz;
defer if (full.comptime_token) |_| inner_gz.unstack();
const rl_components = try astgen.arena.alloc(ResultInfo.Loc.DestructureComponent, full.ast.variables.len);
for (rl_components, full.ast.variables) |*variable_rl, variable_node| {
if (tree.nodeTag(variable_node) == .identifier) {
// This intentionally does not support `@"_"` syntax.
const ident_name = tree.tokenSlice(tree.nodeMainToken(variable_node));
if (mem.eql(u8, ident_name, "_")) {
variable_rl.* = .discard;
continue;
}
}
variable_rl.* = .{ .typed_ptr = .{
.inst = try lvalExpr(inner_gz, scope, variable_node),
.src_node = variable_node,
} };
}
const ri: ResultInfo = .{ .rl = .{ .destructure = .{
.src_node = node,
.components = rl_components,
} } };
_ = try expr(inner_gz, scope, ri, full.ast.value_expr);
if (full.comptime_token) |_| {
const comptime_block_inst = try gz.makeBlockInst(.block_comptime, node);
_ = try inner_gz.addBreak(.break_inline, comptime_block_inst, .void_value);
try inner_gz.setBlockComptimeBody(comptime_block_inst, .comptime_keyword);
try gz.instructions.append(gz.astgen.gpa, comptime_block_inst);
}
}