implement @Type() for more types

master
Tadeo Kondrak 2020-04-25 23:39:28 -06:00 committed by Andrew Kelley
parent 0df82889cf
commit 45f4a1124f
2 changed files with 85 additions and 5 deletions

View File

@ -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)));

View File

@ -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,
});
}