authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-05 17:09:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-05 17:09:01-04:00
loge2dc63644ab3d8e5cdaec2d58dc57c587295081f
tree776b9916ec8911cee97f7992e7255acf6331fc70
parent6ef15fc8d00c06bc767b91515e2c919448948e6f
signaturelock-open Commit is signed but in an unrecognized format.

type_has_one_possible_value takes comptime struct fields into account

Before, type_has_one_possible_value would return false for the value `.{1}`. But actually, that type is a tuple with a single comptime field. Such a type, in fact, has one possible value. This plus the corresponding adjustment to get_the_one_possible_value solves #3878.

2 files changed, 23 insertions(+), 1 deletions(-)

src/analyze.cpp+8
......@@ -5769,6 +5769,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
57695769 type_entry->one_possible_value = OnePossibleValueNo;
57705770 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
57715771 TypeStructField *field = type_entry->data.structure.fields[i];
5772 if (field->is_comptime) {
5773 // If this field is comptime then the field can only be one possible value
5774 continue;
5775 }
57725776 OnePossibleValue opv = (field->type_entry != nullptr) ?
57735777 type_has_one_possible_value(g, field->type_entry) :
57745778 type_val_resolve_has_one_possible_value(g, field->type_val);
......@@ -5825,6 +5829,10 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
58255829 result->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
58265830 for (size_t i = 0; i < field_count; i += 1) {
58275831 TypeStructField *field = struct_type->data.structure.fields[i];
5832 if (field->is_comptime) {
5833 copy_const_val(g, result->data.x_struct.fields[i], field->init_val);
5834 continue;
5835 }
58285836 ZigType *field_type = resolve_struct_field_type(g, field);
58295837 assert(field_type != nullptr);
58305838 result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);
test/stage1/behavior/tuple.zig+15-1
......@@ -36,7 +36,7 @@ test "tuple concatenation" {
3636 consume_tuple(.{} ++ .{}, 0);
3737 consume_tuple(.{0} ++ .{}, 1);
3838 consume_tuple(.{0} ++ .{1}, 2);
39 consume_tuple(.{0, 1, 2} ++ .{u8, 1, noreturn}, 6);
39 consume_tuple(.{ 0, 1, 2 } ++ .{ u8, 1, noreturn }, 6);
4040 consume_tuple(t2 ++ t1, 1);
4141 consume_tuple(t1 ++ t2, 1);
4242 consume_tuple(t2 ++ t2, 2);
......@@ -54,3 +54,17 @@ test "tuple concatenation" {
5454 T.doTheTest();
5555 comptime T.doTheTest();
5656}
57
58test "pass tuple to comptime var parameter" {
59 const S = struct {
60 fn Foo(comptime args: var) void {
61 expect(args[0] == 1);
62 }
63
64 fn doTheTest() void {
65 Foo(.{1});
66 }
67 };
68 S.doTheTest();
69 comptime S.doTheTest();
70}