Commit 45f4a1124f

Tadeo Kondrak <me@tadeo.ca>
2020-04-26 07:39:28
implement @Type() for more types
1 parent 0df8288
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -25267,6 +25267,19 @@ static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node,
     return value->data.x_type;
 }
 
+static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *source_node,
+    ZigValue *struct_value, const char *name, size_t field_index)
+{
+    ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index);
+    if (value == nullptr)
+        return ira->codegen->invalid_inst_gen->value->type;
+    assert(value->type->id == ZigTypeIdOptional);
+    assert(value->type->data.maybe.child_type == ira->codegen->builtin_types.entry_type);
+    if (value->data.x_optional == nullptr)
+        return nullptr;
+    return value->data.x_optional->data.x_type;
+}
+
 static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) {
     Error err;
     switch (tagTypeId) {
@@ -25388,14 +25401,42 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
             return ira->codegen->builtin_types.entry_undef;
         case ZigTypeIdNull:
             return ira->codegen->builtin_types.entry_null;
-        case ZigTypeIdOptional:
-        case ZigTypeIdErrorUnion:
+        case ZigTypeIdOptional: {
+            assert(payload->special == ConstValSpecialStatic);
+            assert(payload->type == ir_type_info_get_type(ira, "Optional", nullptr));
+            ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 0);
+            return get_optional_type(ira->codegen, child_type);
+        }
+        case ZigTypeIdErrorUnion: {
+            assert(payload->special == ConstValSpecialStatic);
+            assert(payload->type == ir_type_info_get_type(ira, "ErrorUnion", nullptr));
+            ZigType *err_set_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "error_set", 0);
+            ZigType *payload_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "payload", 1);
+            return get_error_union_type(ira->codegen, err_set_type, payload_type);
+        }
+        case ZigTypeIdOpaque: {
+            Buf *bare_name = buf_alloc();
+            Buf *full_name = get_anon_type_name(ira->codegen,
+                ira->old_irb.exec, "opaque", source_instr->scope, source_instr->source_node, bare_name);
+            return get_opaque_type(ira->codegen,
+                source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name);
+        }
+        case ZigTypeIdVector: {
+            assert(payload->special == ConstValSpecialStatic);
+            assert(payload->type == ir_type_info_get_type(ira, "Vector", nullptr));
+            BigInt *len = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0);
+            ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1);
+            return get_vector_type(ira->codegen, bigint_as_u32(len), child_type);
+        }
+        case ZigTypeIdAnyFrame: {
+            assert(payload->special == ConstValSpecialStatic);
+            assert(payload->type == ir_type_info_get_type(ira, "AnyFrame", nullptr));
+            ZigType *child_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "child", 0);
+            return get_any_frame_type(ira->codegen, child_type);
+        }
         case ZigTypeIdErrorSet:
         case ZigTypeIdEnum:
-        case ZigTypeIdOpaque:
         case ZigTypeIdFnFrame:
-        case ZigTypeIdAnyFrame:
-        case ZigTypeIdVector:
         case ZigTypeIdEnumLiteral:
             ir_add_error(ira, source_instr, buf_sprintf(
                 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
test/stage1/behavior/type.zig
@@ -171,3 +171,42 @@ test "@Type picks up the sentinel value from TypeInfo" {
         [:4]allowzero align(4) volatile u8,  [:4]allowzero align(4) const volatile u8,
     });
 }
+
+test "Type.Optional" {
+    testTypes(&[_]type{
+        ?u8,
+        ?*u8,
+        ?[]u8,
+        ?[*]u8,
+        ?[*c]u8,
+    });
+}
+
+test "Type.ErrorUnion" {
+    testTypes(&[_]type{
+        error{}!void,
+        error{Error}!void,
+    });
+}
+
+test "Type.Opaque" {
+    testing.expect(@OpaqueType() != @Type(.Opaque));
+    testing.expect(@Type(.Opaque) != @Type(.Opaque));
+    testing.expect(@typeInfo(@Type(.Opaque)) == .Opaque);
+}
+
+test "Type.Vector" {
+    testTypes(&[_]type{
+        @Vector(0, u8),
+        @Vector(4, u8),
+        @Vector(8, *u8),
+    });
+}
+
+test "Type.AnyFrame" {
+    testTypes(&[_]type{
+        anyframe,
+        anyframe->u8,
+        anyframe->anyframe->u8,
+    });
+}