Sema: fix inline break from a non-comptime scope to outer one

Prior to this, the compiler would hit an assertion because the
break_inline would not successfully move the compile-time control flow.
This commit is contained in:
Andrew Kelley
2022-02-20 00:08:26 -07:00
parent 01638c250f
commit 7d9e3840bb
3 changed files with 23 additions and 6 deletions

View File

@@ -964,7 +964,14 @@ fn analyzeBodyInner(
break sema.zirBreak(block, inst);
}
},
.break_inline => break inst,
.break_inline => {
if (block.is_comptime) {
break inst;
} else {
sema.comptime_break_inst = inst;
return error.ComptimeBreak;
}
},
.repeat => {
if (block.is_comptime) {
// Send comptime control flow back to the beginning of this block.
@@ -3572,8 +3579,20 @@ fn resolveBlockBody(
if (child_block.is_comptime) {
return sema.resolveBody(child_block, body, body_inst);
} else {
_ = try sema.analyzeBody(child_block, body);
return sema.analyzeBlockBody(parent_block, src, child_block, merges);
if (sema.analyzeBodyInner(child_block, body)) |_| {
return sema.analyzeBlockBody(parent_block, src, child_block, merges);
} else |err| switch (err) {
error.ComptimeBreak => {
const break_inst = sema.comptime_break_inst;
const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
if (break_data.block_inst == body_inst) {
return sema.resolveInst(break_data.operand);
} else {
return error.ComptimeBreak;
}
},
else => |e| return e,
}
}
}

View File

@@ -2986,7 +2986,7 @@ pub const Type = extern union {
pub fn containerLayout(ty: Type) std.builtin.TypeInfo.ContainerLayout {
return switch (ty.tag()) {
.tuple => .Auto,
.tuple, .empty_struct_literal => .Auto,
.@"struct" => ty.castTag(.@"struct").?.data.layout,
.@"union" => ty.castTag(.@"union").?.data.layout,
.union_tagged => ty.castTag(.union_tagged).?.data.layout,

View File

@@ -763,8 +763,6 @@ fn scalar(x: u32) u32 {
}
test "comptime assign int to optional int" {
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
comptime {
var x: ?i32 = null;
x = 2;