authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2024-02-11 22:55:13+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-26 17:03:20-08:00
logf803761e13a65ccbc6a5508f2dc2d7723b010dab
treea913a11999ae074ffb5e59bfb13c973f13f659b2
parent7a045ede7ca26338dc553e1a0113d1de4daf1b95

Fix tuple default values

- Add default values to the list of comptime-known elements in `zirValidatePtrArrayInit` - In `structFieldValueComptime`, only assert `haveFieldInits` if we enter the`fieldIsComptime` branch (otherwise they are not needed).

3 files changed, 28 insertions(+), 9 deletions(-)

src/Sema.zig+13-8
...@@ -5043,22 +5043,33 @@ fn zirValidatePtrArrayInit(...@@ -5043,22 +5043,33 @@ fn zirValidatePtrArrayInit(
5043 const array_ty = sema.typeOf(array_ptr).childType(mod).optEuBaseType(mod);5043 const array_ty = sema.typeOf(array_ptr).childType(mod).optEuBaseType(mod);
5044 const array_len = array_ty.arrayLen(mod);5044 const array_len = array_ty.arrayLen(mod);
50455045
5046 // Collect the comptime element values in case the array literal ends up
5047 // being comptime-known.
5048 const element_vals = try sema.arena.alloc(
5049 InternPool.Index,
5050 try sema.usizeCast(block, init_src, array_len),
5051 );
5052
5046 if (instrs.len != array_len) switch (array_ty.zigTypeTag(mod)) {5053 if (instrs.len != array_len) switch (array_ty.zigTypeTag(mod)) {
5047 .Struct => {5054 .Struct => {
5048 var root_msg: ?*Module.ErrorMsg = null;5055 var root_msg: ?*Module.ErrorMsg = null;
5049 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);5056 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
50505057
5058 try sema.resolveStructFieldInits(array_ty);
5051 var i = instrs.len;5059 var i = instrs.len;
5052 while (i < array_len) : (i += 1) {5060 while (i < array_len) : (i += 1) {
5053 const default_val = array_ty.structFieldDefaultValue(i, mod);5061 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
5054 if (default_val.toIntern() == .unreachable_value) {5062 if (default_val == .unreachable_value) {
5055 const template = "missing tuple field with index {d}";5063 const template = "missing tuple field with index {d}";
5056 if (root_msg) |msg| {5064 if (root_msg) |msg| {
5057 try sema.errNote(block, init_src, msg, template, .{i});5065 try sema.errNote(block, init_src, msg, template, .{i});
5058 } else {5066 } else {
5059 root_msg = try sema.errMsg(block, init_src, template, .{i});5067 root_msg = try sema.errMsg(block, init_src, template, .{i});
5060 }5068 }
5069 continue;
5061 }5070 }
5071
5072 element_vals[i] = default_val;
5062 }5073 }
50635074
5064 if (root_msg) |msg| {5075 if (root_msg) |msg| {
...@@ -5105,12 +5116,6 @@ fn zirValidatePtrArrayInit(...@@ -5105,12 +5116,6 @@ fn zirValidatePtrArrayInit(
5105 var array_is_comptime = true;5116 var array_is_comptime = true;
5106 var first_block_index = block.instructions.items.len;5117 var first_block_index = block.instructions.items.len;
51075118
5108 // Collect the comptime element values in case the array literal ends up
5109 // being comptime-known.
5110 const element_vals = try sema.arena.alloc(
5111 InternPool.Index,
5112 try sema.usizeCast(block, init_src, array_len),
5113 );
5114 const air_tags = sema.air_instructions.items(.tag);5119 const air_tags = sema.air_instructions.items(.tag);
5115 const air_datas = sema.air_instructions.items(.data);5120 const air_datas = sema.air_instructions.items(.data);
51165121
src/type.zig+1-1
...@@ -3073,8 +3073,8 @@ pub const Type = struct {...@@ -3073,8 +3073,8 @@ pub const Type = struct {
3073 const ip = &mod.intern_pool;3073 const ip = &mod.intern_pool;
3074 switch (ip.indexToKey(ty.toIntern())) {3074 switch (ip.indexToKey(ty.toIntern())) {
3075 .struct_type => |struct_type| {3075 .struct_type => |struct_type| {
3076 assert(struct_type.haveFieldInits(ip));
3077 if (struct_type.fieldIsComptime(ip, index)) {3076 if (struct_type.fieldIsComptime(ip, index)) {
3077 assert(struct_type.haveFieldInits(ip));
3078 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);3078 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);
3079 } else {3079 } else {
3080 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(mod);3080 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(mod);
test/behavior/tuple.zig+14
...@@ -560,3 +560,17 @@ test "comptime fields in tuple can be initialized" {...@@ -560,3 +560,17 @@ test "comptime fields in tuple can be initialized" {
560 var a: T = .{ 0, 0 };560 var a: T = .{ 0, 0 };
561 _ = &a;561 _ = &a;
562}562}
563
564test "tuple default values" {
565 const T = struct {
566 usize,
567 usize = 123,
568 usize = 456,
569 };
570
571 const t: T = .{1};
572
573 try expectEqual(1, t[0]);
574 try expectEqual(123, t[1]);
575 try expectEqual(456, t[2]);
576}