| ... | ... | @@ -14138,7 +14138,7 @@ static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr, |
| 14138 | 14138 | // If there is only 1 possible tag, then we know at comptime what it is. |
| 14139 | 14139 | if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && |
| 14140 | 14140 | wanted_type->data.enumeration.src_field_count == 1 && |
| 14141 | | !wanted_type->data.enumeration.non_exhaustive) // TODO are non-exhaustive union tag types supposed to be allowed? |
| 14141 | !wanted_type->data.enumeration.non_exhaustive) |
| 14142 | 14142 | { |
| 14143 | 14143 | IrInstGen *result = ir_const(ira, source_instr, wanted_type); |
| 14144 | 14144 | result->value->special = ConstValSpecialStatic; |
| ... | ... | @@ -23816,7 +23816,6 @@ static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 23816 | 23816 | bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); |
| 23817 | 23817 | return result; |
| 23818 | 23818 | } |
| 23819 | | // TODO are non-exhaustive union tag types supposed to be allowed? |
| 23820 | 23819 | if (tag_type->data.enumeration.src_field_count == 1 && !tag_type->data.enumeration.non_exhaustive) { |
| 23821 | 23820 | IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); |
| 23822 | 23821 | TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; |
| ... | ... | @@ -28839,6 +28838,10 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28839 | 28838 | if (type_is_invalid(switch_type)) |
| 28840 | 28839 | return ira->codegen->invalid_inst_gen; |
| 28841 | 28840 | |
| 28841 | ZigValue *original_value = ((IrInstSrcSwitchTarget *)(instruction->target_value))->target_value_ptr->child->value; |
| 28842 | bool target_is_originally_union = original_value->type->id == ZigTypeIdPointer && |
| 28843 | original_value->type->data.pointer.child_type->id == ZigTypeIdUnion; |
| 28844 | |
| 28842 | 28845 | if (switch_type->id == ZigTypeIdEnum) { |
| 28843 | 28846 | HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; |
| 28844 | 28847 | field_prev_uses.init(switch_type->data.enumeration.src_field_count); |
| ... | ... | @@ -28894,9 +28897,12 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28894 | 28897 | } |
| 28895 | 28898 | } |
| 28896 | 28899 | if (instruction->have_underscore_prong) { |
| 28897 | | if (!switch_type->data.enumeration.non_exhaustive){ |
| 28900 | if (!switch_type->data.enumeration.non_exhaustive) { |
| 28901 | ir_add_error(ira, &instruction->base.base, |
| 28902 | buf_sprintf("switch on exhaustive enum has `_` prong")); |
| 28903 | } else if (target_is_originally_union) { |
| 28898 | 28904 | ir_add_error(ira, &instruction->base.base, |
| 28899 | | buf_sprintf("switch on non-exhaustive enum has `_` prong")); |
| 28905 | buf_sprintf("`_` prong not allowed when switching on tagged union")); |
| 28900 | 28906 | } |
| 28901 | 28907 | for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { |
| 28902 | 28908 | TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; |
| ... | ... | @@ -28911,7 +28917,7 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, |
| 28911 | 28917 | } |
| 28912 | 28918 | } |
| 28913 | 28919 | } else if (instruction->else_prong == nullptr) { |
| 28914 | | if (switch_type->data.enumeration.non_exhaustive) { |
| 28920 | if (switch_type->data.enumeration.non_exhaustive && !target_is_originally_union) { |
| 28915 | 28921 | ir_add_error(ira, &instruction->base.base, |
| 28916 | 28922 | buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); |
| 28917 | 28923 | } |