Skip to content

Commit ecc0108

Browse files
schmeeVexu
authored andcommitted
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 #14686.
1 parent fea14c7 commit ecc0108

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

src/AstGen.zig

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,7 +1960,10 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
19601960
else
19611961
.@"break";
19621962

1963+
block_gz.break_count += 1;
19631964
if (rhs == 0) {
1965+
_ = try rvalue(parent_gz, block_gz.break_result_info, .void_value, node);
1966+
19641967
try genDefers(parent_gz, scope, parent_scope, .normal_only);
19651968

19661969
// 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
19701973
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
19711974
return Zir.Inst.Ref.unreachable_value;
19721975
}
1973-
block_gz.break_count += 1;
19741976

19751977
const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node);
19761978
const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
@@ -6584,6 +6586,9 @@ fn forExpr(
65846586
cond_block,
65856587
break_tag,
65866588
);
6589+
if (ri.rl.strategy(&loop_scope).tag == .break_void and loop_scope.break_count == 0) {
6590+
_ = try rvalue(parent_gz, ri, .void_value, node);
6591+
}
65876592
if (is_statement) {
65886593
_ = try parent_gz.addUnNode(.ensure_result_used, result, node);
65896594
}
@@ -8525,16 +8530,6 @@ fn builtinCall(
85258530
}
85268531
}
85278532

8528-
fn simpleNoOpVoid(
8529-
gz: *GenZir,
8530-
ri: ResultInfo,
8531-
node: Ast.Node.Index,
8532-
tag: Zir.Inst.Tag,
8533-
) InnerError!Zir.Inst.Ref {
8534-
_ = try gz.addNode(tag, node);
8535-
return rvalue(gz, ri, .void_value, node);
8536-
}
8537-
85388533
fn hasDeclOrField(
85398534
gz: *GenZir,
85408535
scope: *Scope,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export fn f1() void {
2+
const x: usize = for ("hello") |_| {};
3+
_ = x;
4+
}
5+
export fn f2() void {
6+
const x: usize = for ("hello") |_| {
7+
break;
8+
};
9+
_ = x;
10+
}
11+
export fn f3() void {
12+
var t: bool = true;
13+
const x: usize = while (t) {
14+
break;
15+
};
16+
_ = x;
17+
}
18+
export fn f4() void {
19+
const x: usize = blk: {
20+
break :blk;
21+
};
22+
_ = x;
23+
}
24+
25+
// error
26+
// backend=stage2
27+
// target=native
28+
//
29+
// :2:22: error: expected type 'usize', found 'void'
30+
// :7:9: error: expected type 'usize', found 'void'
31+
// :14:9: error: expected type 'usize', found 'void'
32+
// :18:1: error: expected type 'usize', found 'void'

0 commit comments

Comments
 (0)