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:
25
src/Sema.zig
25
src/Sema.zig
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user