Skip to content

Commit bece97e

Browse files
authored
Sema: ensure tuple fields is resolved and fix internal out-of-bounds access
1 parent 2fefc0b commit bece97e

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

src/Sema.zig

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19705,20 +19705,24 @@ fn zirArrayInit(
1970519705
},
1970619706
else => return err,
1970719707
};
19708-
if (is_tuple) if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19709-
const init_val = try sema.resolveValue(dest.*) orelse {
19710-
const decl = mod.declPtr(block.src_decl);
19711-
const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19712-
return sema.failWithNeededComptime(block, elem_src, .{
19713-
.needed_comptime_reason = "value stored in comptime field must be comptime-known",
19714-
});
19715-
};
19716-
if (!field_val.eql(init_val, elem_ty, mod)) {
19717-
const decl = mod.declPtr(block.src_decl);
19718-
const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19719-
return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
19708+
if (is_tuple) {
19709+
if (array_ty.structFieldIsComptime(i, mod))
19710+
try sema.resolveStructFieldInits(array_ty);
19711+
if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
19712+
const init_val = try sema.resolveValue(dest.*) orelse {
19713+
const decl = mod.declPtr(block.src_decl);
19714+
const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19715+
return sema.failWithNeededComptime(block, elem_src, .{
19716+
.needed_comptime_reason = "value stored in comptime field must be comptime-known",
19717+
});
19718+
};
19719+
if (!field_val.eql(init_val, elem_ty, mod)) {
19720+
const decl = mod.declPtr(block.src_decl);
19721+
const elem_src = mod.initSrc(src.node_offset.x, decl, i);
19722+
return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
19723+
}
1972019724
}
19721-
};
19725+
}
1972219726
}
1972319727

1972419728
if (root_msg) |msg| {
@@ -31481,7 +31485,10 @@ fn coerceTupleToTuple(
3148131485
anon_struct_type.names.get(ip)[field_i]
3148231486
else
3148331487
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
31484-
.struct_type => |struct_type| struct_type.field_names.get(ip)[field_i],
31488+
.struct_type => |struct_type| if (struct_type.field_names.len > 0)
31489+
struct_type.field_names.get(ip)[field_i]
31490+
else
31491+
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
3148531492
else => unreachable,
3148631493
};
3148731494

test/behavior/struct.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,3 +1881,12 @@ test "field calls do not force struct field init resolution" {
18811881
_ = &s;
18821882
try expect(s.x == 123);
18831883
}
1884+
1885+
test "tuple with comptime-only field" {
1886+
const x = getTuple();
1887+
try expect(x.@"0" == 0);
1888+
}
1889+
1890+
fn getTuple() struct { comptime_int } {
1891+
return struct { comptime comptime_int = 0 }{0};
1892+
}

0 commit comments

Comments
 (0)