zig
zig copied to clipboard
Cannot use a struct literal in for loop else branch
Zig Version
0.11.0-dev.3387+f04e65bc0
Steps to Reproduce and Observed Behavior
This doesn't compile
pub fn main() void {
const S = struct { x: u8 };
var x = for ([_]S{.{ .x = 42 }}) |s| {
break s;
} else S{ .x = 42 };
_ = x;
}
and the compiler error is this
src\main.zig:3:13: error: incompatible types: 'main.main.S' and 'void'
var x = for ([_]S{.{ .x = 42 }}) |s| {
^~~
src\main.zig:4:15: note: type 'main.main.S' here
break s;
The weird thing is if we annotate x
:
pub fn main() void {
const S = struct { x: u8 };
var x: S = for ([_]S{.{ .x = 42 }}) |s| {
break s;
} else S{ .x = 42 };
_ = x;
}
It compiles fine.
Expected Behavior
Both of these code snippets should compile.
Probably an AstGen
bug:
# Source bytes: 155B
# Tokens: 59 (319B)
# AST Nodes: 26 (458B)
# Total ZIR bytes: 1.19921875KiB
# Instructions: 65 (585B)
# String Table Bytes: 15B
# Extra Data Items: 141 (564B)
%0 = extended(struct_decl(parent, Auto, {
[133] export entry line(0) hash(34fbe0545d7f84aec7615dcececb4dd0): %1 = block_inline({
%63 = func([email protected]_type, body={
%2 = block({
%3 = dbg_block_begin()
%4 = dbg_stmt(2, 5)
%5 = extended(struct_decl(known_non_opv, dbg_var, Auto, {}, {
x: @Zir.Inst.Ref.u8_type,
}) node_offset:2:15 to :2:31
%6 = dbg_var_val(%5, "S")
%7 = dbg_stmt(3, 5)
%8 = alloc_inferred_mut() node_offset:3:5 to :3:8
%9 = alloc(@Zir.Inst.Ref.usize_type) node_offset:3:13 to :3:16
%10 = store(%9, @Zir.Inst.Ref.zero_usize)
%11 = dbg_stmt(3, 18)
%12 = int(1)
%13 = block_comptime({
%14 = break(%13, %5)
}) node_offset:3:21 to :3:22
%15 = array_type(%12, %13) node_offset:3:18 to :3:22
%16 = field_type(%13, x) node_offset:3:31 to :3:33
%17 = int(42)
%18 = as_node(%16, %17) node_offset:3:31 to :3:33
%19 = struct_init_anon([x=%18]) node_offset:3:23 to :3:35
%20 = array_init(%15{%19}) node_offset:3:18 to :3:36
%21 = for_len({%20}) node_offset:3:13 to :3:16
%22 = loop({
%23 = load(%9) node_offset:3:13 to :3:16
%26 = block({
%24 = cmp_lt(%23, %21) node_offset:3:13 to :3:16
%25 = condbr(%24, {
%30 = dbg_block_begin()
%31 = elem_val(%20, %23) node_offset:3:18 to :3:36
%32 = dbg_var_val(%31, "s")
%33 = block({
%34 = dbg_block_begin()
%35 = dbg_stmt(4, 9)
%36 = store_to_block_ptr(%8, %31)
%37 = restore_err_ret_index(%22, @Zir.Inst.Ref.none)
- %38 = break(%22, %31)
+ %38 = break(%22, @Zir.Inst.Ref.void_value)
%39 = dbg_block_end()
%40 = restore_err_ret_index(%33, @Zir.Inst.Ref.none)
%41 = break(%33, @Zir.Inst.Ref.void_value)
}) node_offset:3:42 to :3:43
%42 = dbg_block_end()
%51 = break(%26, @Zir.Inst.Ref.void_value)
}, {
%43 = block_comptime({
%44 = break(%43, %5)
}) node_offset:5:12 to :5:13
%45 = validate_struct_init_ty(%43) node_offset:5:12 to :5:24
%46 = coerce_result_ptr(%43, %8) node_offset:5:12 to :5:24
%47 = field_ptr_init(%46, "x") node_offset:5:20 to :5:22
%48 = int(42)
%49 = store_node(%47, %48) node_offset:5:20 to :5:22
%50 = validate_struct_init({
%47 = field_ptr_init(%46, "x") node_offset:5:20 to :5:22
}) node_offset:5:12 to :5:24
%52 = break(%22, @Zir.Inst.Ref.void_value)
}) node_offset:3:13 to :3:16
}) node_offset:3:13 to :3:16
%27 = add_unsafe(%23, @Zir.Inst.Ref.one_usize) node_offset:3:13 to :3:16
%28 = store(%9, %27)
%29 = repeat() node_offset:3:13 to :3:16
}) node_offset:3:13 to :3:16
%53 = resolve_inferred_alloc(%8) node_offset:3:5 to :3:8
%54 = dbg_var_ptr(%8, "x")
%55 = dbg_stmt(6, 5)
%56 = load(%8) node_offset:6:9 to :6:10
%57 = ensure_result_non_error(%56) node_offset:6:9 to :6:10
%58 = dbg_block_end()
%59 = restore_err_ret_index(%2, @Zir.Inst.Ref.none)
%60 = break(%2, @Zir.Inst.Ref.void_value)
}) node_offset:1:24 to :1:25
%61 = restore_err_ret_index(@Zir.Inst.Ref.none, @Zir.Inst.Ref.none)
%62 = ret_implicit(@Zir.Inst.Ref.void_value) token_offset:7:1 to :7:2
}) (lbrace=1:24,rbrace=7:1) node_offset:1:1 to :1:10
%64 = break_inline(%1, %63)
}) node_offset:1:1 to :1:23
}, {}, {})
%31
and @Zir.Inst.Ref.void_value
do not PTR
Related to my complaint about inferred alloc using both block ptr and block result in #13410