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) {...@@ -5769,6 +5769,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5769 type_entry->one_possible_value = OnePossibleValueNo;5769 type_entry->one_possible_value = OnePossibleValueNo;
5770 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {5770 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
5771 TypeStructField *field = type_entry->data.structure.fields[i];5771 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 }
5772 OnePossibleValue opv = (field->type_entry != nullptr) ?5776 OnePossibleValue opv = (field->type_entry != nullptr) ?
5773 type_has_one_possible_value(g, field->type_entry) :5777 type_has_one_possible_value(g, field->type_entry) :
5774 type_val_resolve_has_one_possible_value(g, field->type_val);5778 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) {...@@ -5825,6 +5829,10 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
5825 result->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);5829 result->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
5826 for (size_t i = 0; i < field_count; i += 1) {5830 for (size_t i = 0; i < field_count; i += 1) {
5827 TypeStructField *field = struct_type->data.structure.fields[i];5831 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 }
5828 ZigType *field_type = resolve_struct_field_type(g, field);5836 ZigType *field_type = resolve_struct_field_type(g, field);
5829 assert(field_type != nullptr);5837 assert(field_type != nullptr);
5830 result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);5838 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" {...@@ -36,7 +36,7 @@ test "tuple concatenation" {
36 consume_tuple(.{} ++ .{}, 0);36 consume_tuple(.{} ++ .{}, 0);
37 consume_tuple(.{0} ++ .{}, 1);37 consume_tuple(.{0} ++ .{}, 1);
38 consume_tuple(.{0} ++ .{1}, 2);38 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);
40 consume_tuple(t2 ++ t1, 1);40 consume_tuple(t2 ++ t1, 1);
41 consume_tuple(t1 ++ t2, 1);41 consume_tuple(t1 ++ t2, 1);
42 consume_tuple(t2 ++ t2, 2);42 consume_tuple(t2 ++ t2, 2);
...@@ -54,3 +54,17 @@ test "tuple concatenation" {...@@ -54,3 +54,17 @@ test "tuple concatenation" {
54 T.doTheTest();54 T.doTheTest();
55 comptime T.doTheTest();55 comptime T.doTheTest();
56}56}
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}