authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-11-27 16:04:09+11:00
committergravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2024-01-09 14:42:12+11:00
loga175a6438400d3e8842b4a4ac6a8cb76f53976a0
treed22c73800bc0dcd2cad5c17a6d8167e9dc735aea
parent6bf319ebbb0bce945e9598a03783bc5a26f70e15

sema: implement runtime switch_block_err_union


1 files changed, 62 insertions(+), 3 deletions(-)

src/Sema.zig+62-3
......@@ -11179,7 +11179,6 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1117911179 // AstGen guarantees that the instruction immediately preceding
1118011180 // switch_block_err_union is a dbg_stmt
1118111181 const cond_dbg_node_index: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);
11182 _ = cond_dbg_node_index;
1118311182
1118411183 var header_extra_index: usize = extra.end;
1118511184
......@@ -11340,13 +11339,73 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1134011339 }
1134111340
1134211341 if (child_block.is_comptime) {
11343 _ = try sema.resolveConstDefinedValue(&child_block, operand_src, operand, .{
11342 _ = try sema.resolveConstDefinedValue(&child_block, operand_src, raw_operand_val, .{
1134411343 .needed_comptime_reason = "condition in comptime switch must be comptime-known",
1134511344 .block_comptime_reason = child_block.comptime_reason,
1134611345 });
1134711346 unreachable;
1134811347 }
11349 return sema.fail(block, src, "TODO: implement more of switch_block_err_union", .{});
11348
11349 const cond = try sema.analyzeIsNonErr(block, src, raw_operand_val);
11350
11351 var sub_block = child_block.makeSubBlock();
11352 sub_block.runtime_loop = null;
11353 sub_block.runtime_cond = operand_src;
11354 sub_block.runtime_index.increment();
11355 defer sub_block.instructions.deinit(gpa);
11356
11357 try sema.analyzeBodyRuntimeBreak(&sub_block, non_error_case.body);
11358 const true_instructions = try sub_block.instructions.toOwnedSlice(gpa);
11359 defer gpa.free(true_instructions);
11360
11361 spa.operand = try sema.analyzeErrUnionCode(&sub_block, operand_src, raw_operand_val);
11362 _ = try sema.analyzeSwitchRuntimeBlock(
11363 spa,
11364 &sub_block,
11365 src,
11366 try sema.switchCond(block, operand_src, spa.operand),
11367 operand_err_set_ty,
11368 operand_src,
11369 case_vals,
11370 .{
11371 .body = else_case.body,
11372 .end = else_case.end,
11373 .capture = if (else_case.has_capture) .by_val else .none,
11374 .is_inline = else_case.is_inline,
11375 .has_tag_capture = false,
11376 },
11377 scalar_cases_len,
11378 multi_cases_len,
11379 false,
11380 undefined,
11381 true,
11382 src_node_offset,
11383 else_prong_src,
11384 undefined,
11385 seen_errors,
11386 undefined,
11387 undefined,
11388 undefined,
11389 cond_dbg_node_index,
11390 );
11391
11392 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
11393 true_instructions.len + sub_block.instructions.items.len);
11394
11395 _ = try child_block.addInst(.{
11396 .tag = .cond_br,
11397 .data = .{ .pl_op = .{
11398 .operand = cond,
11399 .payload = sema.addExtraAssumeCapacity(Air.CondBr{
11400 .then_body_len = @intCast(true_instructions.len),
11401 .else_body_len = @intCast(sub_block.instructions.items.len),
11402 }),
11403 } },
11404 });
11405 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));
11406 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));
11407
11408 return sema.analyzeBlockBody(block, src, &child_block, merges);
1135011409}
1135111410
1135211411fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref {