Commit 25ac2fe8cd

Andrew Kelley <andrew@ziglang.org>
2019-03-31 18:43:21
fix anon enum literal used with switch on union(enum)
closes #2141 closes #2142
1 parent 62af701
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -17188,11 +17188,18 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
     assert(target_value_ptr->value.type->id == ZigTypeIdPointer);
     ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type;
     if (target_type->id == ZigTypeIdUnion) {
-        ConstExprValue *prong_val = ir_resolve_const(ira, prong_value, UndefBad);
+        ZigType *enum_type = target_type->data.unionation.tag_type;
+        assert(enum_type != nullptr);
+        assert(enum_type->id == ZigTypeIdEnum);
+
+        IrInstruction *casted_prong_value = ir_implicit_cast(ira, prong_value, enum_type);
+        if (type_is_invalid(casted_prong_value->value.type))
+            return ira->codegen->invalid_instruction;
+
+        ConstExprValue *prong_val = ir_resolve_const(ira, casted_prong_value, UndefBad);
         if (!prong_val)
             return ira->codegen->invalid_instruction;
 
-        assert(prong_value->value.type->id == ZigTypeIdEnum);
         TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag);
 
         if (instr_is_comptime(target_value_ptr)) {
test/stage1/behavior/switch.zig
@@ -283,3 +283,16 @@ test "undefined.u0" {
         0 => expect(val == 0),
     }
 }
+
+test "anon enum literal used in switch on union enum" {
+    const Foo = union(enum) {
+        a: i32,
+    };
+
+    var foo = Foo{ .a = 1234 };
+    switch (foo) {
+        .a => |x| {
+            expect(x == 1234);
+        },
+    }
+}