| author | |
| committer | |
| log | b728cb6d4e882592129eef2e37f8fcd8fda78822 |
| tree | 9929bf826b52e9c29dfaa8c8eee930504d788a3f |
| parent | 77a5f888be664f9ef09e2c93f52338448e992e00 |
7 files changed, 364 insertions(+), 0 deletions(-)
src/all_types.hpp+8| ... | ... | @@ -1534,6 +1534,7 @@ enum BuiltinFnId { |
| 1534 | 1534 | BuiltinFnIdMemberName, |
| 1535 | 1535 | BuiltinFnIdField, |
| 1536 | 1536 | BuiltinFnIdTypeInfo, |
| 1537 | BuiltinFnIdType, | |
| 1537 | 1538 | BuiltinFnIdHasField, |
| 1538 | 1539 | BuiltinFnIdTypeof, |
| 1539 | 1540 | BuiltinFnIdAddWithOverflow, |
| ... | ... | @@ -2436,6 +2437,7 @@ enum IrInstructionId { |
| 2436 | 2437 | IrInstructionIdByteOffsetOf, |
| 2437 | 2438 | IrInstructionIdBitOffsetOf, |
| 2438 | 2439 | IrInstructionIdTypeInfo, |
| 2440 | IrInstructionIdType, | |
| 2439 | 2441 | IrInstructionIdHasField, |
| 2440 | 2442 | IrInstructionIdTypeId, |
| 2441 | 2443 | IrInstructionIdSetEvalBranchQuota, |
| ... | ... | @@ -3472,6 +3474,12 @@ struct IrInstructionTypeInfo { |
| 3472 | 3474 | IrInstruction *type_value; |
| 3473 | 3475 | }; |
| 3474 | 3476 | |
| 3477 | struct IrInstructionType { | |
| 3478 | IrInstruction base; | |
| 3479 | ||
| 3480 | IrInstruction *type_info; | |
| 3481 | }; | |
| 3482 | ||
| 3475 | 3483 | struct IrInstructionHasField { |
| 3476 | 3484 | IrInstruction base; |
| 3477 | 3485 |
src/codegen.cpp+2| ... | ... | @@ -5770,6 +5770,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5770 | 5770 | case IrInstructionIdByteOffsetOf: |
| 5771 | 5771 | case IrInstructionIdBitOffsetOf: |
| 5772 | 5772 | case IrInstructionIdTypeInfo: |
| 5773 | case IrInstructionIdType: | |
| 5773 | 5774 | case IrInstructionIdHasField: |
| 5774 | 5775 | case IrInstructionIdTypeId: |
| 5775 | 5776 | case IrInstructionIdSetEvalBranchQuota: |
| ... | ... | @@ -7597,6 +7598,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 7597 | 7598 | create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2); |
| 7598 | 7599 | create_builtin_fn(g, BuiltinFnIdField, "field", 2); |
| 7599 | 7600 | create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1); |
| 7601 | create_builtin_fn(g, BuiltinFnIdType, "Type", 1); | |
| 7600 | 7602 | create_builtin_fn(g, BuiltinFnIdHasField, "hasField", 2); |
| 7601 | 7603 | create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf |
| 7602 | 7604 | create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4); |
src/ir.cpp+179| ... | ... | @@ -912,6 +912,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { |
| 912 | 912 | return IrInstructionIdTypeInfo; |
| 913 | 913 | } |
| 914 | 914 | |
| 915 | static constexpr IrInstructionId ir_instruction_id(IrInstructionType *) { | |
| 916 | return IrInstructionIdType; | |
| 917 | } | |
| 918 | ||
| 915 | 919 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { |
| 916 | 920 | return IrInstructionIdHasField; |
| 917 | 921 | } |
| ... | ... | @@ -2907,6 +2911,15 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode * |
| 2907 | 2911 | return &instruction->base; |
| 2908 | 2912 | } |
| 2909 | 2913 | |
| 2914 | static IrInstruction *ir_build_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_info) { | |
| 2915 | IrInstructionType *instruction = ir_build_instruction<IrInstructionType>(irb, scope, source_node); | |
| 2916 | instruction->type_info = type_info; | |
| 2917 | ||
| 2918 | ir_ref_instruction(type_info, irb->current_basic_block); | |
| 2919 | ||
| 2920 | return &instruction->base; | |
| 2921 | } | |
| 2922 | ||
| 2910 | 2923 | static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2911 | 2924 | IrInstruction *type_value) |
| 2912 | 2925 | { |
| ... | ... | @@ -5046,6 +5059,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5046 | 5059 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); |
| 5047 | 5060 | return ir_lval_wrap(irb, scope, type_info, lval, result_loc); |
| 5048 | 5061 | } |
| 5062 | case BuiltinFnIdType: | |
| 5063 | { | |
| 5064 | AstNode *arg_node = node->data.fn_call_expr.params.at(0); | |
| 5065 | IrInstruction *arg = ir_gen_node(irb, arg_node, scope); | |
| 5066 | if (arg == irb->codegen->invalid_instruction) | |
| 5067 | return arg; | |
| 5068 | ||
| 5069 | IrInstruction *type = ir_build_type(irb, scope, node, arg); | |
| 5070 | return ir_lval_wrap(irb, scope, type, lval, result_loc); | |
| 5071 | } | |
| 5049 | 5072 | case BuiltinFnIdBreakpoint: |
| 5050 | 5073 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); |
| 5051 | 5074 | case BuiltinFnIdReturnAddress: |
| ... | ... | @@ -20104,6 +20127,18 @@ static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) { |
| 20104 | 20127 | zig_unreachable(); |
| 20105 | 20128 | } |
| 20106 | 20129 | |
| 20130 | static PtrLen size_enum_index_to_ptr_len(uint32_t size_enum_index) { | |
| 20131 | switch (size_enum_index) { | |
| 20132 | case 0: | |
| 20133 | return PtrLenSingle; | |
| 20134 | case 1: | |
| 20135 | return PtrLenUnknown; | |
| 20136 | case 3: | |
| 20137 | return PtrLenC; | |
| 20138 | } | |
| 20139 | zig_unreachable(); | |
| 20140 | } | |
| 20141 | ||
| 20107 | 20142 | static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { |
| 20108 | 20143 | Error err; |
| 20109 | 20144 | ZigType *attrs_type; |
| ... | ... | @@ -20789,6 +20824,147 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, |
| 20789 | 20824 | return result; |
| 20790 | 20825 | } |
| 20791 | 20826 | |
| 20827 | static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) | |
| 20828 | { | |
| 20829 | ensure_field_index(struct_value->type, name, field_index); | |
| 20830 | assert(struct_value->data.x_struct.fields[field_index].special == ConstValSpecialStatic); | |
| 20831 | return &struct_value->data.x_struct.fields[field_index]; | |
| 20832 | } | |
| 20833 | ||
| 20834 | static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) | |
| 20835 | { | |
| 20836 | ConstExprValue *value = get_const_field(ira, struct_value, name, field_index); | |
| 20837 | assert(value->type == ira->codegen->builtin_types.entry_bool); | |
| 20838 | return value->data.x_bool; | |
| 20839 | } | |
| 20840 | ||
| 20841 | static BigInt *get_const_field_lit_int(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) | |
| 20842 | { | |
| 20843 | ConstExprValue *value = get_const_field(ira, struct_value, name, field_index); | |
| 20844 | assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); | |
| 20845 | return &value->data.x_bigint; | |
| 20846 | } | |
| 20847 | ||
| 20848 | static ZigType *get_const_field_meta_type(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) | |
| 20849 | { | |
| 20850 | ConstExprValue *value = get_const_field(ira, struct_value, name, field_index); | |
| 20851 | assert(value->type == ira->codegen->builtin_types.entry_type); | |
| 20852 | return value->data.x_type; | |
| 20853 | } | |
| 20854 | ||
| 20855 | static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, ZigTypeId tagTypeId, ConstExprValue *payload) { | |
| 20856 | switch (tagTypeId) { | |
| 20857 | case ZigTypeIdInvalid: | |
| 20858 | zig_unreachable(); | |
| 20859 | case ZigTypeIdMetaType: | |
| 20860 | return ira->codegen->builtin_types.entry_type; | |
| 20861 | case ZigTypeIdVoid: | |
| 20862 | return ira->codegen->builtin_types.entry_void; | |
| 20863 | case ZigTypeIdBool: | |
| 20864 | return ira->codegen->builtin_types.entry_bool; | |
| 20865 | case ZigTypeIdUnreachable: | |
| 20866 | return ira->codegen->builtin_types.entry_unreachable; | |
| 20867 | case ZigTypeIdInt: | |
| 20868 | assert(payload->special == ConstValSpecialStatic); | |
| 20869 | assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); | |
| 20870 | return get_int_type(ira->codegen, | |
| 20871 | get_const_field_bool(ira, payload, "is_signed", 0), | |
| 20872 | bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 1))); | |
| 20873 | case ZigTypeIdFloat: | |
| 20874 | { | |
| 20875 | assert(payload->special == ConstValSpecialStatic); | |
| 20876 | assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); | |
| 20877 | uint32_t bits = bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 0)); | |
| 20878 | switch (bits) { | |
| 20879 | case 16: return ira->codegen->builtin_types.entry_f16; | |
| 20880 | case 32: return ira->codegen->builtin_types.entry_f32; | |
| 20881 | case 64: return ira->codegen->builtin_types.entry_f64; | |
| 20882 | case 128: return ira->codegen->builtin_types.entry_f128; | |
| 20883 | } | |
| 20884 | ir_add_error(ira, instruction, | |
| 20885 | buf_sprintf("%d-bit float unsupported", bits)); | |
| 20886 | return nullptr; | |
| 20887 | } | |
| 20888 | case ZigTypeIdPointer: | |
| 20889 | { | |
| 20890 | ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); | |
| 20891 | assert(payload->special == ConstValSpecialStatic); | |
| 20892 | assert(payload->type == type_info_pointer_type); | |
| 20893 | ConstExprValue *size_value = get_const_field(ira, payload, "size", 0); | |
| 20894 | assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); | |
| 20895 | uint32_t size_enum_index = bigint_as_u32(&size_value->data.x_enum_tag); | |
| 20896 | PtrLen ptr_len; | |
| 20897 | if (size_enum_index == 2) { | |
| 20898 | ptr_len = PtrLenUnknown; // TODO: is this right? | |
| 20899 | } else { | |
| 20900 | ptr_len = size_enum_index_to_ptr_len(size_enum_index); | |
| 20901 | } | |
| 20902 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, | |
| 20903 | get_const_field_meta_type(ira, payload, "child", 4), | |
| 20904 | get_const_field_bool(ira, payload, "is_const", 1), | |
| 20905 | get_const_field_bool(ira, payload, "is_volatile", 2), | |
| 20906 | ptr_len, | |
| 20907 | bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), | |
| 20908 | 0, // bit_offset_in_host??? | |
| 20909 | 0, // host_int_bytes??? | |
| 20910 | get_const_field_bool(ira, payload, "is_allowzero", 5) | |
| 20911 | ); | |
| 20912 | if (size_enum_index != 2) | |
| 20913 | return ptr_type; | |
| 20914 | return get_slice_type(ira->codegen, ptr_type); | |
| 20915 | } | |
| 20916 | case ZigTypeIdComptimeFloat: | |
| 20917 | return ira->codegen->builtin_types.entry_num_lit_float; | |
| 20918 | case ZigTypeIdComptimeInt: | |
| 20919 | return ira->codegen->builtin_types.entry_num_lit_int; | |
| 20920 | case ZigTypeIdUndefined: | |
| 20921 | return ira->codegen->builtin_types.entry_undef; | |
| 20922 | case ZigTypeIdNull: | |
| 20923 | return ira->codegen->builtin_types.entry_null; | |
| 20924 | case ZigTypeIdArray: | |
| 20925 | case ZigTypeIdOptional: | |
| 20926 | case ZigTypeIdErrorUnion: | |
| 20927 | case ZigTypeIdErrorSet: | |
| 20928 | case ZigTypeIdEnum: | |
| 20929 | case ZigTypeIdOpaque: | |
| 20930 | case ZigTypeIdFnFrame: | |
| 20931 | case ZigTypeIdAnyFrame: | |
| 20932 | case ZigTypeIdVector: | |
| 20933 | case ZigTypeIdEnumLiteral: | |
| 20934 | ir_add_error(ira, instruction, buf_sprintf( | |
| 20935 | "TODO implement @Type forr 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907\n", type_id_name(tagTypeId))); | |
| 20936 | return nullptr; | |
| 20937 | case ZigTypeIdUnion: | |
| 20938 | case ZigTypeIdFn: | |
| 20939 | case ZigTypeIdBoundFn: | |
| 20940 | case ZigTypeIdArgTuple: | |
| 20941 | case ZigTypeIdStruct: | |
| 20942 | ir_add_error(ira, instruction, buf_sprintf( | |
| 20943 | "@Type not availble for 'TypeInfo.%s'\n", type_id_name(tagTypeId))); | |
| 20944 | return nullptr; | |
| 20945 | } | |
| 20946 | zig_unreachable(); | |
| 20947 | } | |
| 20948 | ||
| 20949 | static IrInstruction *ir_analyze_instruction_type(IrAnalyze *ira, IrInstructionType *instruction) { | |
| 20950 | IrInstruction *type_info_ir = instruction->type_info->child; | |
| 20951 | if (type_is_invalid(type_info_ir->value.type)) | |
| 20952 | return ira->codegen->invalid_instruction; | |
| 20953 | ||
| 20954 | IrInstruction *casted_ir = ir_implicit_cast(ira, type_info_ir, ir_type_info_get_type(ira, nullptr, nullptr)); | |
| 20955 | if (type_is_invalid(casted_ir->value.type)) | |
| 20956 | return ira->codegen->invalid_instruction; | |
| 20957 | ||
| 20958 | ConstExprValue *type_info_value = ir_resolve_const(ira, casted_ir, UndefBad); | |
| 20959 | if (!type_info_value) | |
| 20960 | return ira->codegen->invalid_instruction; | |
| 20961 | ZigTypeId typeId = type_id_at_index(bigint_as_usize(&type_info_value->data.x_union.tag)); | |
| 20962 | ZigType *type = type_info_to_type(ira, type_info_ir, typeId, type_info_value->data.x_union.payload); | |
| 20963 | if (!type) | |
| 20964 | return ira->codegen->invalid_instruction; | |
| 20965 | return ir_const_type(ira, &instruction->base, type); | |
| 20966 | } | |
| 20967 | ||
| 20792 | 20968 | static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, |
| 20793 | 20969 | IrInstructionTypeId *instruction) |
| 20794 | 20970 | { |
| ... | ... | @@ -25295,6 +25471,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25295 | 25471 | return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); |
| 25296 | 25472 | case IrInstructionIdTypeInfo: |
| 25297 | 25473 | return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); |
| 25474 | case IrInstructionIdType: | |
| 25475 | return ir_analyze_instruction_type(ira, (IrInstructionType *)instruction); | |
| 25298 | 25476 | case IrInstructionIdHasField: |
| 25299 | 25477 | return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); |
| 25300 | 25478 | case IrInstructionIdTypeId: |
| ... | ... | @@ -25598,6 +25776,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25598 | 25776 | case IrInstructionIdByteOffsetOf: |
| 25599 | 25777 | case IrInstructionIdBitOffsetOf: |
| 25600 | 25778 | case IrInstructionIdTypeInfo: |
| 25779 | case IrInstructionIdType: | |
| 25601 | 25780 | case IrInstructionIdHasField: |
| 25602 | 25781 | case IrInstructionIdTypeId: |
| 25603 | 25782 | case IrInstructionIdAlignCast: |
src/ir_print.cpp+11| ... | ... | @@ -280,6 +280,8 @@ static const char* ir_instruction_type_str(IrInstruction* instruction) { |
| 280 | 280 | return "BitOffsetOf"; |
| 281 | 281 | case IrInstructionIdTypeInfo: |
| 282 | 282 | return "TypeInfo"; |
| 283 | case IrInstructionIdType: | |
| 284 | return "Type"; | |
| 283 | 285 | case IrInstructionIdHasField: |
| 284 | 286 | return "HasField"; |
| 285 | 287 | case IrInstructionIdTypeId: |
| ... | ... | @@ -1627,6 +1629,12 @@ static void ir_print_type_info(IrPrint *irp, IrInstructionTypeInfo *instruction) |
| 1627 | 1629 | fprintf(irp->f, ")"); |
| 1628 | 1630 | } |
| 1629 | 1631 | |
| 1632 | static void ir_print_type(IrPrint *irp, IrInstructionType *instruction) { | |
| 1633 | fprintf(irp->f, "@Type("); | |
| 1634 | ir_print_other_instruction(irp, instruction->type_info); | |
| 1635 | fprintf(irp->f, ")"); | |
| 1636 | } | |
| 1637 | ||
| 1630 | 1638 | static void ir_print_has_field(IrPrint *irp, IrInstructionHasField *instruction) { |
| 1631 | 1639 | fprintf(irp->f, "@hasField("); |
| 1632 | 1640 | ir_print_other_instruction(irp, instruction->container_type); |
| ... | ... | @@ -2258,6 +2266,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool |
| 2258 | 2266 | case IrInstructionIdTypeInfo: |
| 2259 | 2267 | ir_print_type_info(irp, (IrInstructionTypeInfo *)instruction); |
| 2260 | 2268 | break; |
| 2269 | case IrInstructionIdType: | |
| 2270 | ir_print_type(irp, (IrInstructionType *)instruction); | |
| 2271 | break; | |
| 2261 | 2272 | case IrInstructionIdHasField: |
| 2262 | 2273 | ir_print_has_field(irp, (IrInstructionHasField *)instruction); |
| 2263 | 2274 | break; |
test/compile_errors.zig+52| ... | ... | @@ -2,6 +2,58 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | ||
| 6 | cases.add( | |
| 7 | "wrong type for @Type", | |
| 8 | \\export fn entry() void { | |
| 9 | \\ _ = @Type(0); | |
| 10 | \\} | |
| 11 | , | |
| 12 | "tmp.zig:2:15: error: expected type 'builtin.TypeInfo', found 'comptime_int'", | |
| 13 | ); | |
| 14 | ||
| 15 | cases.add( | |
| 16 | "@Type with non-constant expression", | |
| 17 | \\const builtin = @import("builtin"); | |
| 18 | \\var globalTypeInfo : builtin.TypeInfo = undefined; | |
| 19 | \\export fn entry() void { | |
| 20 | \\ _ = @Type(globalTypeInfo); | |
| 21 | \\} | |
| 22 | , | |
| 23 | "tmp.zig:4:15: error: unable to evaluate constant expression", | |
| 24 | ); | |
| 25 | ||
| 26 | cases.add( | |
| 27 | "@Type with TypeInfo.Int", | |
| 28 | \\const builtin = @import("builtin"); | |
| 29 | \\export fn entry() void { | |
| 30 | \\ _ = @Type(builtin.TypeInfo.Int { | |
| 31 | \\ .is_signed = true, | |
| 32 | \\ .bits = 8, | |
| 33 | \\ }); | |
| 34 | \\} | |
| 35 | , | |
| 36 | "tmp.zig:3:36: error: expected type 'builtin.TypeInfo', found 'builtin.Int'", | |
| 37 | ); | |
| 38 | ||
| 39 | cases.add( | |
| 40 | "Struct unavailable for @Type", | |
| 41 | \\export fn entry() void { | |
| 42 | \\ _ = @Type(@typeInfo(struct { })); | |
| 43 | \\} | |
| 44 | , | |
| 45 | "tmp.zig:2:15: error: @Type not availble for 'TypeInfo.Struct'", | |
| 46 | ); | |
| 47 | ||
| 48 | cases.add( | |
| 49 | "array not implemented for @Type", | |
| 50 | \\export fn entry() void { | |
| 51 | \\ _ = @Type(@typeInfo(enum{x})); | |
| 52 | \\} | |
| 53 | , | |
| 54 | "tmp.zig:2:15: error: TODO implement @Type forr 'TypeInfo.Enum': see https://github.com/ziglang/zig/issues/2907", | |
| 55 | ); | |
| 56 | ||
| 5 | 57 | cases.add( |
| 6 | 58 | "wrong type for result ptr to @asyncCall", |
| 7 | 59 | \\export fn entry() void { |
test/stage1/behavior.zig+1| ... | ... | @@ -93,6 +93,7 @@ comptime { |
| 93 | 93 | _ = @import("behavior/this.zig"); |
| 94 | 94 | _ = @import("behavior/truncate.zig"); |
| 95 | 95 | _ = @import("behavior/try.zig"); |
| 96 | _ = @import("behavior/type.zig"); | |
| 96 | 97 | _ = @import("behavior/type_info.zig"); |
| 97 | 98 | _ = @import("behavior/typename.zig"); |
| 98 | 99 | _ = @import("behavior/undefined.zig"); |
test/stage1/behavior/type.zig created+111| ... | ... | @@ -0,0 +1,111 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const TypeInfo = builtin.TypeInfo; | |
| 3 | ||
| 4 | const std = @import("std"); | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | fn testTypes(comptime types: []const type) void { | |
| 8 | inline for (types) |testType| { | |
| 9 | testing.expect(testType == @Type(@typeInfo(testType))); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | test "Type.MetaType" { | |
| 14 | testing.expect(type == @Type(TypeInfo { .Type = undefined })); | |
| 15 | testTypes([_]type {type}); | |
| 16 | } | |
| 17 | ||
| 18 | test "Type.Void" { | |
| 19 | testing.expect(void == @Type(TypeInfo { .Void = undefined })); | |
| 20 | testTypes([_]type {void}); | |
| 21 | } | |
| 22 | ||
| 23 | test "Type.Bool" { | |
| 24 | testing.expect(bool == @Type(TypeInfo { .Bool = undefined })); | |
| 25 | testTypes([_]type {bool}); | |
| 26 | } | |
| 27 | ||
| 28 | test "Type.NoReturn" { | |
| 29 | testing.expect(noreturn == @Type(TypeInfo { .NoReturn = undefined })); | |
| 30 | testTypes([_]type {noreturn}); | |
| 31 | } | |
| 32 | ||
| 33 | test "Type.Int" { | |
| 34 | testing.expect(u1 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = false, .bits = 1 } })); | |
| 35 | testing.expect(i1 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = true, .bits = 1 } })); | |
| 36 | testing.expect(u8 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = false, .bits = 8 } })); | |
| 37 | testing.expect(i8 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = true, .bits = 8 } })); | |
| 38 | testing.expect(u64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = false, .bits = 64 } })); | |
| 39 | testing.expect(i64 == @Type(TypeInfo { .Int = TypeInfo.Int { .is_signed = true, .bits = 64 } })); | |
| 40 | testTypes([_]type {u8,u32,i64}); | |
| 41 | // TODO: should this work? | |
| 42 | //testing.expect(u1 == @Type(TypeInfo.Int { .is_signed = false, .bits = 1 } )); | |
| 43 | } | |
| 44 | ||
| 45 | test "Type.Float" { | |
| 46 | testing.expect(f16 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 16 } })); | |
| 47 | testing.expect(f32 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 32 } })); | |
| 48 | testing.expect(f64 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 64 } })); | |
| 49 | testing.expect(f128 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 128 } })); | |
| 50 | testTypes([_]type {f16, f32, f64, f128}); | |
| 51 | // error: 17-bit float unsupported | |
| 52 | //testing.expect(f16 == @Type(TypeInfo { .Float = TypeInfo.Float { .bits = 17 } })); | |
| 53 | } | |
| 54 | ||
| 55 | test "Type.Pointer" { | |
| 56 | testTypes([_]type { | |
| 57 | // One Value Pointer Types | |
| 58 | *u8, *const u8, | |
| 59 | *volatile u8, *const volatile u8, | |
| 60 | *align(4) u8, *const align(4) u8, | |
| 61 | *volatile align(4) u8, *const volatile align(4) u8, | |
| 62 | *align(8) u8, *const align(8) u8, | |
| 63 | *volatile align(8) u8, *const volatile align(8) u8, | |
| 64 | *allowzero u8, *const allowzero u8, | |
| 65 | *volatile allowzero u8, *const volatile allowzero u8, | |
| 66 | *align(4) allowzero u8, *const align(4) allowzero u8, | |
| 67 | *volatile align(4) allowzero u8, *const volatile align(4) allowzero u8, | |
| 68 | // Many Values Pointer Types | |
| 69 | [*]u8, [*]const u8, | |
| 70 | [*]volatile u8, [*]const volatile u8, | |
| 71 | [*]align(4) u8, [*]const align(4) u8, | |
| 72 | [*]volatile align(4) u8, [*]const volatile align(4) u8, | |
| 73 | [*]align(8) u8, [*]const align(8) u8, | |
| 74 | [*]volatile align(8) u8, [*]const volatile align(8) u8, | |
| 75 | [*]allowzero u8, [*]const allowzero u8, | |
| 76 | [*]volatile allowzero u8, [*]const volatile allowzero u8, | |
| 77 | [*]align(4) allowzero u8, [*]const align(4) allowzero u8, | |
| 78 | [*]volatile align(4) allowzero u8, [*]const volatile align(4) allowzero u8, | |
| 79 | // Slice Types | |
| 80 | []u8, []const u8, | |
| 81 | []volatile u8, []const volatile u8, | |
| 82 | []align(4) u8, []const align(4) u8, | |
| 83 | []volatile align(4) u8, []const volatile align(4) u8, | |
| 84 | []align(8) u8, []const align(8) u8, | |
| 85 | []volatile align(8) u8, []const volatile align(8) u8, | |
| 86 | []allowzero u8, []const allowzero u8, | |
| 87 | []volatile allowzero u8, []const volatile allowzero u8, | |
| 88 | []align(4) allowzero u8, []const align(4) allowzero u8, | |
| 89 | []volatile align(4) allowzero u8, []const volatile align(4) allowzero u8, | |
| 90 | // C Pointer Types | |
| 91 | [*c]u8, [*c]const u8, | |
| 92 | [*c]volatile u8, [*c]const volatile u8, | |
| 93 | [*c]align(4) u8, [*c]const align(4) u8, | |
| 94 | [*c]volatile align(4) u8, [*c]const volatile align(4) u8, | |
| 95 | [*c]align(8) u8, [*c]const align(8) u8, | |
| 96 | [*c]volatile align(8) u8, [*c]const volatile align(8) u8, | |
| 97 | }); | |
| 98 | } | |
| 99 | ||
| 100 | test "Type.ComptimeFloat" { | |
| 101 | testTypes([_]type {comptime_float}); | |
| 102 | } | |
| 103 | test "Type.ComptimeInt" { | |
| 104 | testTypes([_]type {comptime_int}); | |
| 105 | } | |
| 106 | test "Type.Undefined" { | |
| 107 | testTypes([_]type {@typeOf(undefined)}); | |
| 108 | } | |
| 109 | test "Type.Null" { | |
| 110 | testTypes([_]type {@typeOf(null)}); | |
| 111 | } |