| author | |
| committer | |
| log | 4664f793dc3fed2254863a5b6efc302c095890cb |
| tree | 1c52e0597e181d09ebf199797894945de1eb25f4 |
| parent | 1b5d1877aea6c0db7fbe6f56ffe4412ce2cffff7 |
6 files changed, 124 insertions(+), 47 deletions(-)
src/all_types.hpp+7-2| ... | @@ -429,14 +429,12 @@ enum CastOp { | ... | @@ -429,14 +429,12 @@ enum CastOp { |
| 429 | CastOpNoop, // fn call expr is a cast, but does nothing | 429 | CastOpNoop, // fn call expr is a cast, but does nothing |
| 430 | CastOpPtrToInt, | 430 | CastOpPtrToInt, |
| 431 | CastOpIntToPtr, | 431 | CastOpIntToPtr, |
| 432 | CastOpWidenOrShorten, | ||
| 433 | CastOpErrToInt, | 432 | CastOpErrToInt, |
| 434 | CastOpIntToFloat, | 433 | CastOpIntToFloat, |
| 435 | CastOpFloatToInt, | 434 | CastOpFloatToInt, |
| 436 | CastOpBoolToInt, | 435 | CastOpBoolToInt, |
| 437 | CastOpResizeSlice, | 436 | CastOpResizeSlice, |
| 438 | CastOpIntToEnum, | 437 | CastOpIntToEnum, |
| 439 | CastOpEnumToInt, | ||
| 440 | CastOpBytesToSlice, | 438 | CastOpBytesToSlice, |
| 441 | }; | 439 | }; |
| 442 | 440 | ||
| ... | @@ -1454,6 +1452,7 @@ enum IrInstructionId { | ... | @@ -1454,6 +1452,7 @@ enum IrInstructionId { |
| 1454 | IrInstructionIdTestComptime, | 1452 | IrInstructionIdTestComptime, |
| 1455 | IrInstructionIdInitEnum, | 1453 | IrInstructionIdInitEnum, |
| 1456 | IrInstructionIdPointerReinterpret, | 1454 | IrInstructionIdPointerReinterpret, |
| 1455 | IrInstructionIdWidenOrShorten, | ||
| 1457 | }; | 1456 | }; |
| 1458 | 1457 | ||
| 1459 | struct IrInstruction { | 1458 | struct IrInstruction { |
| ... | @@ -2096,6 +2095,12 @@ struct IrInstructionPointerReinterpret { | ... | @@ -2096,6 +2095,12 @@ struct IrInstructionPointerReinterpret { |
| 2096 | IrInstruction *ptr; | 2095 | IrInstruction *ptr; |
| 2097 | }; | 2096 | }; |
| 2098 | 2097 | ||
| 2098 | struct IrInstructionWidenOrShorten { | ||
| 2099 | IrInstruction base; | ||
| 2100 | |||
| 2101 | IrInstruction *target; | ||
| 2102 | }; | ||
| 2103 | |||
| 2099 | enum LValPurpose { | 2104 | enum LValPurpose { |
| 2100 | LValPurposeNone, | 2105 | LValPurposeNone, |
| 2101 | LValPurposeAssign, | 2106 | LValPurposeAssign, |
src/codegen.cpp+20-6| ... | @@ -973,9 +973,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -973,9 +973,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 973 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); | 973 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); |
| 974 | case CastOpIntToPtr: | 974 | case CastOpIntToPtr: |
| 975 | return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); | 975 | return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); |
| 976 | case CastOpWidenOrShorten: | ||
| 977 | return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base), | ||
| 978 | actual_type, wanted_type, expr_val); | ||
| 979 | case CastOpResizeSlice: | 976 | case CastOpResizeSlice: |
| 980 | { | 977 | { |
| 981 | assert(cast_instruction->tmp_ptr); | 978 | assert(cast_instruction->tmp_ptr); |
| ... | @@ -1086,9 +1083,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -1086,9 +1083,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 1086 | case CastOpIntToEnum: | 1083 | case CastOpIntToEnum: |
| 1087 | return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base), | 1084 | return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base), |
| 1088 | actual_type, wanted_type->data.enumeration.tag_type, expr_val); | 1085 | actual_type, wanted_type->data.enumeration.tag_type, expr_val); |
| 1089 | case CastOpEnumToInt: | ||
| 1090 | return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base), | ||
| 1091 | actual_type->data.enumeration.tag_type, wanted_type, expr_val); | ||
| 1092 | } | 1086 | } |
| 1093 | zig_unreachable(); | 1087 | zig_unreachable(); |
| 1094 | } | 1088 | } |
| ... | @@ -1101,6 +1095,24 @@ static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *exec | ... | @@ -1101,6 +1095,24 @@ static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *exec |
| 1101 | return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, ""); | 1095 | return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, ""); |
| 1102 | } | 1096 | } |
| 1103 | 1097 | ||
| 1098 | static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, | ||
| 1099 | IrInstructionWidenOrShorten *instruction) | ||
| 1100 | { | ||
| 1101 | TypeTableEntry *actual_type = instruction->target->value.type; | ||
| 1102 | // TODO instead of this logic, use the Noop instruction to change the type from | ||
| 1103 | // enum_tag to the underlying int type | ||
| 1104 | TypeTableEntry *int_type; | ||
| 1105 | if (actual_type->id == TypeTableEntryIdEnum) { | ||
| 1106 | TypeTableEntry *tag_type = actual_type->data.enumeration.tag_type; | ||
| 1107 | assert(tag_type->id == TypeTableEntryIdEnumTag); | ||
| 1108 | int_type = tag_type->data.enum_tag.int_type; | ||
| 1109 | } else { | ||
| 1110 | int_type = actual_type; | ||
| 1111 | } | ||
| 1112 | LLVMValueRef target_val = ir_llvm_value(g, instruction->target); | ||
| 1113 | return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base), int_type, | ||
| 1114 | instruction->base.value.type, target_val); | ||
| 1115 | } | ||
| 1104 | 1116 | ||
| 1105 | static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable, | 1117 | static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable, |
| 1106 | IrInstructionUnreachable *unreachable_instruction) | 1118 | IrInstructionUnreachable *unreachable_instruction) |
| ... | @@ -2309,6 +2321,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2309,6 +2321,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2309 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); | 2321 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); |
| 2310 | case IrInstructionIdPointerReinterpret: | 2322 | case IrInstructionIdPointerReinterpret: |
| 2311 | return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction); | 2323 | return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction); |
| 2324 | case IrInstructionIdWidenOrShorten: | ||
| 2325 | return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); | ||
| 2312 | case IrInstructionIdSwitchVar: | 2326 | case IrInstructionIdSwitchVar: |
| 2313 | zig_panic("TODO render switch var instruction to LLVM"); | 2327 | zig_panic("TODO render switch var instruction to LLVM"); |
| 2314 | case IrInstructionIdContainerInitList: | 2328 | case IrInstructionIdContainerInitList: |
src/ir.cpp+64-7| ... | @@ -455,6 +455,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpr | ... | @@ -455,6 +455,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpr |
| 455 | return IrInstructionIdPointerReinterpret; | 455 | return IrInstructionIdPointerReinterpret; |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { | ||
| 459 | return IrInstructionIdWidenOrShorten; | ||
| 460 | } | ||
| 461 | |||
| 458 | template<typename T> | 462 | template<typename T> |
| 459 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { | 463 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { |
| 460 | T *special_instruction = allocate<T>(1); | 464 | T *special_instruction = allocate<T>(1); |
| ... | @@ -1883,6 +1887,18 @@ static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, | ... | @@ -1883,6 +1887,18 @@ static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, |
| 1883 | return &instruction->base; | 1887 | return &instruction->base; |
| 1884 | } | 1888 | } |
| 1885 | 1889 | ||
| 1890 | static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, | ||
| 1891 | IrInstruction *target) | ||
| 1892 | { | ||
| 1893 | IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( | ||
| 1894 | irb, scope, source_node); | ||
| 1895 | instruction->target = target; | ||
| 1896 | |||
| 1897 | ir_ref_instruction(target); | ||
| 1898 | |||
| 1899 | return &instruction->base; | ||
| 1900 | } | ||
| 1901 | |||
| 1886 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { | 1902 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 1887 | results[ReturnKindUnconditional] = 0; | 1903 | results[ReturnKindUnconditional] = 0; |
| 1888 | results[ReturnKindError] = 0; | 1904 | results[ReturnKindError] = 0; |
| ... | @@ -4638,7 +4654,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -4638,7 +4654,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 4638 | case CastOpNoCast: | 4654 | case CastOpNoCast: |
| 4639 | zig_unreachable(); | 4655 | zig_unreachable(); |
| 4640 | case CastOpNoop: | 4656 | case CastOpNoop: |
| 4641 | case CastOpWidenOrShorten: | ||
| 4642 | *const_val = *other_val; | 4657 | *const_val = *other_val; |
| 4643 | const_val->type = new_type; | 4658 | const_val->type = new_type; |
| 4644 | break; | 4659 | break; |
| ... | @@ -4684,10 +4699,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -4684,10 +4699,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 4684 | const_val->special = ConstValSpecialStatic; | 4699 | const_val->special = ConstValSpecialStatic; |
| 4685 | break; | 4700 | break; |
| 4686 | } | 4701 | } |
| 4687 | case CastOpEnumToInt: | ||
| 4688 | bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_enum.tag); | ||
| 4689 | const_val->special = ConstValSpecialStatic; | ||
| 4690 | break; | ||
| 4691 | } | 4702 | } |
| 4692 | } | 4703 | } |
| 4693 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 4704 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| ... | @@ -5181,6 +5192,50 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s | ... | @@ -5181,6 +5192,50 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s |
| 5181 | return result; | 5192 | return result; |
| 5182 | } | 5193 | } |
| 5183 | 5194 | ||
| 5195 | static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, | ||
| 5196 | IrInstruction *target, TypeTableEntry *wanted_type) | ||
| 5197 | { | ||
| 5198 | assert(wanted_type->id == TypeTableEntryIdInt); | ||
| 5199 | |||
| 5200 | if (instr_is_comptime(target)) { | ||
| 5201 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); | ||
| 5202 | if (!val) | ||
| 5203 | return ira->codegen->invalid_instruction; | ||
| 5204 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | ||
| 5205 | source_instr->source_node, wanted_type, val->depends_on_compile_var); | ||
| 5206 | init_const_unsigned_negative(&result->value, wanted_type, val->data.x_enum.tag, false); | ||
| 5207 | return result; | ||
| 5208 | } | ||
| 5209 | |||
| 5210 | IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, | ||
| 5211 | source_instr->source_node, target); | ||
| 5212 | result->value.type = wanted_type; | ||
| 5213 | return result; | ||
| 5214 | } | ||
| 5215 | |||
| 5216 | static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, | ||
| 5217 | IrInstruction *target, TypeTableEntry *wanted_type) | ||
| 5218 | { | ||
| 5219 | assert(wanted_type->id == TypeTableEntryIdInt || wanted_type->id == TypeTableEntryIdFloat); | ||
| 5220 | |||
| 5221 | if (instr_is_comptime(target)) { | ||
| 5222 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); | ||
| 5223 | if (!val) | ||
| 5224 | return ira->codegen->invalid_instruction; | ||
| 5225 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | ||
| 5226 | source_instr->source_node, wanted_type, val->depends_on_compile_var); | ||
| 5227 | result->value = *val; | ||
| 5228 | result->value.type = wanted_type; | ||
| 5229 | return result; | ||
| 5230 | } | ||
| 5231 | |||
| 5232 | IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, | ||
| 5233 | source_instr->source_node, target); | ||
| 5234 | result->value.type = wanted_type; | ||
| 5235 | return result; | ||
| 5236 | } | ||
| 5237 | |||
| 5238 | |||
| 5184 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, | 5239 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 5185 | TypeTableEntry *wanted_type, IrInstruction *value) | 5240 | TypeTableEntry *wanted_type, IrInstruction *value) |
| 5186 | { | 5241 | { |
| ... | @@ -5233,7 +5288,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -5233,7 +5288,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 5233 | (wanted_type_canon->id == TypeTableEntryIdFloat && | 5288 | (wanted_type_canon->id == TypeTableEntryIdFloat && |
| 5234 | actual_type_canon->id == TypeTableEntryIdFloat)) | 5289 | actual_type_canon->id == TypeTableEntryIdFloat)) |
| 5235 | { | 5290 | { |
| 5236 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpWidenOrShorten, false); | 5291 | return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); |
| 5237 | } | 5292 | } |
| 5238 | 5293 | ||
| 5239 | // explicit cast from int to float | 5294 | // explicit cast from int to float |
| ... | @@ -5411,7 +5466,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -5411,7 +5466,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 5411 | actual_type->id == TypeTableEntryIdEnum && | 5466 | actual_type->id == TypeTableEntryIdEnum && |
| 5412 | actual_type->data.enumeration.gen_field_count == 0) | 5467 | actual_type->data.enumeration.gen_field_count == 0) |
| 5413 | { | 5468 | { |
| 5414 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpEnumToInt, false); | 5469 | return ir_analyze_enum_to_int(ira, source_instr, value, wanted_type); |
| 5415 | } | 5470 | } |
| 5416 | 5471 | ||
| 5417 | // explicit cast from undefined to anything | 5472 | // explicit cast from undefined to anything |
| ... | @@ -9882,6 +9937,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -9882,6 +9937,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 9882 | switch (instruction->id) { | 9937 | switch (instruction->id) { |
| 9883 | case IrInstructionIdInvalid: | 9938 | case IrInstructionIdInvalid: |
| 9884 | case IrInstructionIdPointerReinterpret: | 9939 | case IrInstructionIdPointerReinterpret: |
| 9940 | case IrInstructionIdWidenOrShorten: | ||
| 9885 | case IrInstructionIdStructInit: | 9941 | case IrInstructionIdStructInit: |
| 9886 | case IrInstructionIdStructFieldPtr: | 9942 | case IrInstructionIdStructFieldPtr: |
| 9887 | case IrInstructionIdEnumFieldPtr: | 9943 | case IrInstructionIdEnumFieldPtr: |
| ... | @@ -10188,6 +10244,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -10188,6 +10244,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 10188 | case IrInstructionIdTestComptime: | 10244 | case IrInstructionIdTestComptime: |
| 10189 | case IrInstructionIdInitEnum: | 10245 | case IrInstructionIdInitEnum: |
| 10190 | case IrInstructionIdPointerReinterpret: | 10246 | case IrInstructionIdPointerReinterpret: |
| 10247 | case IrInstructionIdWidenOrShorten: | ||
| 10191 | return false; | 10248 | return false; |
| 10192 | case IrInstructionIdAsm: | 10249 | case IrInstructionIdAsm: |
| 10193 | { | 10250 | { |
src/ir_print.cpp+10-1| ... | @@ -923,11 +923,17 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) | ... | @@ -923,11 +923,17 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) |
| 923 | } | 923 | } |
| 924 | 924 | ||
| 925 | static void ir_print_pointer_reinterpret(IrPrint *irp, IrInstructionPointerReinterpret *instruction) { | 925 | static void ir_print_pointer_reinterpret(IrPrint *irp, IrInstructionPointerReinterpret *instruction) { |
| 926 | fprintf(irp->f, "(%s)(", buf_ptr(&instruction->base.value.type->name)); | 926 | fprintf(irp->f, "@pointerReinterpret("); |
| 927 | ir_print_other_instruction(irp, instruction->ptr); | 927 | ir_print_other_instruction(irp, instruction->ptr); |
| 928 | fprintf(irp->f, ")"); | 928 | fprintf(irp->f, ")"); |
| 929 | } | 929 | } |
| 930 | 930 | ||
| 931 | static void ir_print_widen_or_shorten(IrPrint *irp, IrInstructionWidenOrShorten *instruction) { | ||
| 932 | fprintf(irp->f, "@widenOrShorten("); | ||
| 933 | ir_print_other_instruction(irp, instruction->target); | ||
| 934 | fprintf(irp->f, ")"); | ||
| 935 | } | ||
| 936 | |||
| 931 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 937 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 932 | ir_print_prefix(irp, instruction); | 938 | ir_print_prefix(irp, instruction); |
| 933 | switch (instruction->id) { | 939 | switch (instruction->id) { |
| ... | @@ -1170,6 +1176,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1170,6 +1176,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1170 | case IrInstructionIdPointerReinterpret: | 1176 | case IrInstructionIdPointerReinterpret: |
| 1171 | ir_print_pointer_reinterpret(irp, (IrInstructionPointerReinterpret *)instruction); | 1177 | ir_print_pointer_reinterpret(irp, (IrInstructionPointerReinterpret *)instruction); |
| 1172 | break; | 1178 | break; |
| 1179 | case IrInstructionIdWidenOrShorten: | ||
| 1180 | ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction); | ||
| 1181 | break; | ||
| 1173 | } | 1182 | } |
| 1174 | fprintf(irp->f, "\n"); | 1183 | fprintf(irp->f, "\n"); |
| 1175 | } | 1184 | } |
test/cases/enum_to_int.zig deleted-31| ... | @@ -1,31 +0,0 @@ | ||
| 1 | const assert = @import("std").debug.assert; | ||
| 2 | |||
| 3 | enum Number { | ||
| 4 | Zero, | ||
| 5 | One, | ||
| 6 | Two, | ||
| 7 | Three, | ||
| 8 | Four, | ||
| 9 | } | ||
| 10 | |||
| 11 | fn enumToInt() { | ||
| 12 | @setFnTest(this, true); | ||
| 13 | |||
| 14 | shouldEqual(false, Number.Zero, 0); | ||
| 15 | shouldEqual(false, Number.One, 1); | ||
| 16 | shouldEqual(false, Number.Two, 2); | ||
| 17 | shouldEqual(false, Number.Three, 3); | ||
| 18 | shouldEqual(false, Number.Four, 4); | ||
| 19 | |||
| 20 | shouldEqual(true, Number.Zero, 0); | ||
| 21 | shouldEqual(true, Number.One, 1); | ||
| 22 | shouldEqual(true, Number.Two, 2); | ||
| 23 | shouldEqual(true, Number.Three, 3); | ||
| 24 | shouldEqual(true, Number.Four, 4); | ||
| 25 | } | ||
| 26 | |||
| 27 | fn shouldEqual(inline static_eval: bool, n: Number, expected: usize) { | ||
| 28 | @setFnStaticEval(this, static_eval); | ||
| 29 | |||
| 30 | assert(usize(n) == expected); | ||
| 31 | } | ||
test/cases3/enum.zig+23| ... | @@ -73,6 +73,29 @@ const AnEnumWithPayload = enum { | ... | @@ -73,6 +73,29 @@ const AnEnumWithPayload = enum { |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | 75 | ||
| 76 | const Number = enum { | ||
| 77 | Zero, | ||
| 78 | One, | ||
| 79 | Two, | ||
| 80 | Three, | ||
| 81 | Four, | ||
| 82 | }; | ||
| 83 | |||
| 84 | fn enumToInt() { | ||
| 85 | @setFnTest(this); | ||
| 86 | |||
| 87 | shouldEqual(Number.Zero, 0); | ||
| 88 | shouldEqual(Number.One, 1); | ||
| 89 | shouldEqual(Number.Two, 2); | ||
| 90 | shouldEqual(Number.Three, 3); | ||
| 91 | shouldEqual(Number.Four, 4); | ||
| 92 | } | ||
| 93 | |||
| 94 | fn shouldEqual(n: Number, expected: usize) { | ||
| 95 | assert(usize(n) == expected); | ||
| 96 | } | ||
| 97 | |||
| 98 | // TODO import from std | ||
| 76 | fn assert(ok: bool) { | 99 | fn assert(ok: bool) { |
| 77 | if (!ok) | 100 | if (!ok) |
| 78 | @unreachable(); | 101 | @unreachable(); |