@@ -8993,6 +8993,13 @@ static bool slice_is_const(ZigType *type) {
8993
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
9003
static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) {
8997
9004
assert(set->id == ZigTypeIdErrorSet);
8998
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
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
9693
if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) {
9681
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
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
9709
if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC &&
9689
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
10928
}
10908
10929
10909
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
10933
Error err;
10913
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
10943
if (instr_is_comptime(target)) {
10917
10944
ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
@@ -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
11792
- if (wanted_type->id == ZigTypeIdUnion && actual_type->id == ZigTypeIdEnum &&
11793
- (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||
11794
- wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr ))
11818
+ // enum to union which has the enum as the tag type, or
11819
+ // enum literal to union which has a matching enum as the tag type
11820
+ if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum ||
11821
+ actual_type->id == ZigTypeIdEnumLiteral ))
11795
11822
{
11796
- if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown)))
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
- }
11823
+ return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type);
11802
11824
}
11803
11825
11804
11826
// cast from *T to *[1]T
0 commit comments