mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:24:49 +01:00
AstGen: allow labels to provide separate break and continue targets
Enhances `GenZir` to allow labels to provide separate `break` and `continue`
target blocks and adds some more information on continue targets to
communicate whether the target is a switch block or cannot be targeted by
`continue` at all.
The main motivation is enabling this:
```
const result: u32 = operand catch |err| label: switch (err) {
else => continue :label error.MyError,
error.MyError => break :label 1,
};
```
to be lowered to something like this:
```
%1 = block({
%2 = is_non_err(%operand)
%3 = condbr(%2, {
%4 = err_union_payload_unsafe(%operand)
%5 = break(%1, result) // targets enclosing `block`
}, {
%6 = err_union_code(%operand)
%7 = switch_block(%6,
else => {
%8 = switch_continue(%7, "error.MyError") // targets `switch_block`
},
"error.MyError" => {
%9 = break(%1, @one) // targets enclosing `block`
},
)
%10 = break(%1, @void_value)
})
})
```
which makes the non-error case and all breaks from switch prongs, but not
continues from switch prongs, peers.
This is required to avoid the problems described in gh#11957 for labeled
switches without having to introduce a fairly complex special case to the
`switch_block_err_union` logic. Since this construct is very rare in practice,
introducing this additional complexity just to save a few ZIR bytes is
likely not worth it, so the simplified lowering described above will be
used instead.
As a nice bonus, AstGen can now also detect a `continue` trying to target
a labeled block and emit an appropriate error message.
This commit is contained in:
parent
aa2b178029
commit
e0108dec54
2 changed files with 235 additions and 188 deletions
10
test/cases/compile_errors/labeled_block_continue.zig
Normal file
10
test/cases/compile_errors/labeled_block_continue.zig
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export fn foo() void {
|
||||
const result: u32 = b: {
|
||||
continue :b 123;
|
||||
};
|
||||
_ = result;
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:9: error: continue cannot target labeled block
|
||||
Loading…
Add table
Add a link
Reference in a new issue