| ... | @@ -8993,6 +8993,13 @@ static bool slice_is_const(ZigType *type) { | ... | @@ -8993,6 +8993,13 @@ static bool slice_is_const(ZigType *type) { |
| 8993 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; | 8993 | return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| 8994 | } | 8994 | } |
| 8995 | | 8995 | |
| | 8996 | static bool is_tagged_union(ZigType *type) { |
| | 8997 | if (type->id != ZigTypeIdUnion) |
| | 8998 | return false; |
| | 8999 | return (type->data.unionation.decl_node->data.container_decl.auto_enum || |
| | 9000 | type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); |
| | 9001 | } |
| | 9002 | |
| 8996 | static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { | 9003 | static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { |
| 8997 | assert(set->id == ZigTypeIdErrorSet); | 9004 | assert(set->id == ZigTypeIdErrorSet); |
| 8998 | for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { | 9005 | for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { |
| ... | @@ -9676,6 +9683,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9676,6 +9683,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9676 | continue; | 9683 | continue; |
| 9677 | } | 9684 | } |
| 9678 | } | 9685 | } |
| | 9686 | if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { |
| | 9687 | TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value.data.x_enum_literal); |
| | 9688 | if (field != nullptr) { |
| | 9689 | continue; |
| | 9690 | } |
| | 9691 | } |
| 9679 | | 9692 | |
| 9680 | if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { | 9693 | if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { |
| 9681 | TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value.data.x_enum_literal); | 9694 | TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value.data.x_enum_literal); |
| ... | @@ -9685,6 +9698,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -9685,6 +9698,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9685 | } | 9698 | } |
| 9686 | } | 9699 | } |
| 9687 | | 9700 | |
| | 9701 | if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { |
| | 9702 | TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value.data.x_enum_literal); |
| | 9703 | if (field != nullptr) { |
| | 9704 | prev_inst = cur_inst; |
| | 9705 | continue; |
| | 9706 | } |
| | 9707 | } |
| | 9708 | |
| 9688 | if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && | 9709 | if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && |
| 9689 | (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) | 9710 | (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) |
| 9690 | { | 9711 | { |
| ... | @@ -10907,11 +10928,17 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc | ... | @@ -10907,11 +10928,17 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc |
| 10907 | } | 10928 | } |
| 10908 | | 10929 | |
| 10909 | static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, | 10930 | static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, |
| 10910 | IrInstruction *target, ZigType *wanted_type) | 10931 | IrInstruction *uncasted_target, ZigType *wanted_type) |
| 10911 | { | 10932 | { |
| 10912 | Error err; | 10933 | Error err; |
| 10913 | assert(wanted_type->id == ZigTypeIdUnion); | 10934 | assert(wanted_type->id == ZigTypeIdUnion); |
| 10914 | assert(target->value.type->id == ZigTypeIdEnum); | 10935 | |
| | 10936 | if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) |
| | 10937 | return ira->codegen->invalid_instruction; |
| | 10938 | |
| | 10939 | IrInstruction *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); |
| | 10940 | if (type_is_invalid(target->value.type)) |
| | 10941 | return ira->codegen->invalid_instruction; |
| 10915 | | 10942 | |
| 10916 | if (instr_is_comptime(target)) { | 10943 | if (instr_is_comptime(target)) { |
| 10917 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); | 10944 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); |
| ... | @@ -11788,17 +11815,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -11788,17 +11815,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 11788 | } | 11815 | } |
| 11789 | } | 11816 | } |
| 11790 | | 11817 | |
| 11791 | // enum to union which has the enum as the tag type | 11818 | // enum to union which has the enum as the tag type, or |
| 11792 | if (wanted_type->id == ZigTypeIdUnion && actual_type->id == ZigTypeIdEnum && | 11819 | // enum literal to union which has a matching enum as the tag type |
| 11793 | (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || | 11820 | if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || |
| 11794 | wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) | 11821 | actual_type->id == ZigTypeIdEnumLiteral)) |
| 11795 | { | 11822 | { |
| 11796 | if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) | 11823 | return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); |
| 11797 | return ira->codegen->invalid_instruction; | | |
| 11798 | | | |
| 11799 | if (wanted_type->data.unionation.tag_type == actual_type) { | | |
| 11800 | return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); | | |
| 11801 | } | | |
| 11802 | } | 11824 | } |
| 11803 | | 11825 | |
| 11804 | // cast from *T to *[1]T | 11826 | // cast from *T to *[1]T |