mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
astgen: fill result location with void value if no other value
With this change, `break` and `break :blk` will fill the result location with `.void_value`, ensuring that the value will be type checked. The same will happen for a for loop that contains no `break`s in it's body. Closes https://github.com/ziglang/zig/issues/14686.
This commit is contained in:
parent
fea14c78d1
commit
ecc0108cea
@ -1960,7 +1960,10 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
||||
else
|
||||
.@"break";
|
||||
|
||||
block_gz.break_count += 1;
|
||||
if (rhs == 0) {
|
||||
_ = try rvalue(parent_gz, block_gz.break_result_info, .void_value, node);
|
||||
|
||||
try genDefers(parent_gz, scope, parent_scope, .normal_only);
|
||||
|
||||
// As our last action before the break, "pop" the error trace if needed
|
||||
@ -1970,7 +1973,6 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
||||
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
|
||||
return Zir.Inst.Ref.unreachable_value;
|
||||
}
|
||||
block_gz.break_count += 1;
|
||||
|
||||
const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node);
|
||||
const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
|
||||
@ -6584,6 +6586,9 @@ fn forExpr(
|
||||
cond_block,
|
||||
break_tag,
|
||||
);
|
||||
if (ri.rl.strategy(&loop_scope).tag == .break_void and loop_scope.break_count == 0) {
|
||||
_ = try rvalue(parent_gz, ri, .void_value, node);
|
||||
}
|
||||
if (is_statement) {
|
||||
_ = try parent_gz.addUnNode(.ensure_result_used, result, node);
|
||||
}
|
||||
@ -8525,16 +8530,6 @@ fn builtinCall(
|
||||
}
|
||||
}
|
||||
|
||||
fn simpleNoOpVoid(
|
||||
gz: *GenZir,
|
||||
ri: ResultInfo,
|
||||
node: Ast.Node.Index,
|
||||
tag: Zir.Inst.Tag,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
_ = try gz.addNode(tag, node);
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
}
|
||||
|
||||
fn hasDeclOrField(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
|
||||
32
test/cases/compile_errors/break_void_result_location.zig
Normal file
32
test/cases/compile_errors/break_void_result_location.zig
Normal file
@ -0,0 +1,32 @@
|
||||
export fn f1() void {
|
||||
const x: usize = for ("hello") |_| {};
|
||||
_ = x;
|
||||
}
|
||||
export fn f2() void {
|
||||
const x: usize = for ("hello") |_| {
|
||||
break;
|
||||
};
|
||||
_ = x;
|
||||
}
|
||||
export fn f3() void {
|
||||
var t: bool = true;
|
||||
const x: usize = while (t) {
|
||||
break;
|
||||
};
|
||||
_ = x;
|
||||
}
|
||||
export fn f4() void {
|
||||
const x: usize = blk: {
|
||||
break :blk;
|
||||
};
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:22: error: expected type 'usize', found 'void'
|
||||
// :7:9: error: expected type 'usize', found 'void'
|
||||
// :14:9: error: expected type 'usize', found 'void'
|
||||
// :18:1: error: expected type 'usize', found 'void'
|
||||
Loading…
x
Reference in New Issue
Block a user