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.
This commit is contained in:
Andrew Kelley 2020-04-05 17:09:01 -04:00
parent 6ef15fc8d0
commit e2dc63644a
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 23 additions and 1 deletions

View File

@ -5769,6 +5769,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
type_entry->one_possible_value = OnePossibleValueNo;
for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
TypeStructField *field = type_entry->data.structure.fields[i];
if (field->is_comptime) {
// If this field is comptime then the field can only be one possible value
continue;
}
OnePossibleValue opv = (field->type_entry != nullptr) ?
type_has_one_possible_value(g, field->type_entry) :
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) {
result->data.x_struct.fields = alloc_const_vals_ptrs(g, field_count);
for (size_t i = 0; i < field_count; i += 1) {
TypeStructField *field = struct_type->data.structure.fields[i];
if (field->is_comptime) {
copy_const_val(g, result->data.x_struct.fields[i], field->init_val);
continue;
}
ZigType *field_type = resolve_struct_field_type(g, field);
assert(field_type != nullptr);
result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);

View File

@ -36,7 +36,7 @@ test "tuple concatenation" {
consume_tuple(.{} ++ .{}, 0);
consume_tuple(.{0} ++ .{}, 1);
consume_tuple(.{0} ++ .{1}, 2);
consume_tuple(.{0, 1, 2} ++ .{u8, 1, noreturn}, 6);
consume_tuple(.{ 0, 1, 2 } ++ .{ u8, 1, noreturn }, 6);
consume_tuple(t2 ++ t1, 1);
consume_tuple(t1 ++ t2, 1);
consume_tuple(t2 ++ t2, 2);
@ -54,3 +54,17 @@ test "tuple concatenation" {
T.doTheTest();
comptime T.doTheTest();
}
test "pass tuple to comptime var parameter" {
const S = struct {
fn Foo(comptime args: var) void {
expect(args[0] == 1);
}
fn doTheTest() void {
Foo(.{1});
}
};
S.doTheTest();
comptime S.doTheTest();
}