authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 12:59:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 12:59:30-04:00
log21ed9391179a9e472b25c80eaec5eebc9d08aca8
treec25253450faa5b0ce2dbf21f096e759f8ff90abd
parent163a8e98bc04ea955ee54d5905436ffac34c93a2
signaturelock-open Commit is signed but in an unrecognized format.

support enum literals implicit casting to tagged unions


2 files changed, 57 insertions(+), 15 deletions(-)

src/ir.cpp+34-12
...@@ -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}
89958995
8996static 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
8996static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) {9003static 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 }
96799692
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 }
96879700
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}
1090810929
10909static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr,10930static 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;
1091510942
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 }
1179011817
11791 // enum to union which has the enum as the tag type11818 // 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 }
1180311825
11804 // cast from *T to *[1]T11826 // cast from *T to *[1]T
test/stage1/behavior/enum.zig+23-3
...@@ -930,9 +930,9 @@ test "enum literal in array literal" {...@@ -930,9 +930,9 @@ test "enum literal in array literal" {
930 two,930 two,
931 };931 };
932932
933 const array = []Items {933 const array = []Items{
934 .one,934 .one,
935 .two,935 .two,
936 };936 };
937937
938 expect(array[0] == .one);938 expect(array[0] == .one);
...@@ -962,3 +962,23 @@ test "enum value allocation" {...@@ -962,3 +962,23 @@ test "enum value allocation" {
962 expect(@enumToInt(LargeEnum.A1) == 0x80000001);962 expect(@enumToInt(LargeEnum.A1) == 0x80000001);
963 expect(@enumToInt(LargeEnum.A2) == 0x80000002);963 expect(@enumToInt(LargeEnum.A2) == 0x80000002);
964}964}
965
966test "enum literal casting to tagged union" {
967 const Arch = union(enum) {
968 x86_64,
969 arm: Arm32,
970
971 const Arm32 = enum {
972 v8_5a,
973 v8_4a,
974 };
975 };
976
977 var t = true;
978 var x: Arch = .x86_64;
979 var y = if (t) x else .x86_64;
980 switch (y) {
981 .x86_64 => {},
982 else => @panic("fail"),
983 }
984}