From e2dc63644ab3d8e5cdaec2d58dc57c587295081f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 5 Apr 2020 17:09:01 -0400 Subject: [PATCH] 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. --- src/analyze.cpp | 8 ++++++++ test/stage1/behavior/tuple.zig | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index e627eaf91b..14b9c25c07 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -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); diff --git a/test/stage1/behavior/tuple.zig b/test/stage1/behavior/tuple.zig index 686a9ad83e..3c467baaa4 100644 --- a/test/stage1/behavior/tuple.zig +++ b/test/stage1/behavior/tuple.zig @@ -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(); +}