Commit 11d8a8cc7b

Andrew Kelley <superjoe30@gmail.com>
2017-05-07 19:21:53
fix comptime switch on enum with ref payload
See #43
1 parent 818a0a2
Changed files (2)
src
test
src/ir.cpp
@@ -11202,15 +11202,11 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
                 return ira->codegen->builtin_types.entry_invalid;
 
             ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, target_val_ptr);
-            if (pointee_val->type->id == TypeTableEntryIdEnum) {
-                ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
-                out_val->data.x_ptr.special = ConstPtrSpecialRef;
-                out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_enum.payload;
-                return get_pointer_to_type(ira->codegen, pointee_val->type,
-                        target_value_ptr->value.type->data.pointer.is_const);
-            } else {
-                zig_panic("TODO comptime switch var");
-            }
+            ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
+            out_val->data.x_ptr.special = ConstPtrSpecialRef;
+            out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut;
+            out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_enum.payload;
+            return get_pointer_to_type(ira->codegen, field->type_entry, target_val_ptr->type->data.pointer.is_const);
         }
 
         ir_build_enum_field_ptr_from(&ira->new_irb, &instruction->base, target_value_ptr, field);
test/cases/switch.zig
@@ -106,6 +106,22 @@ fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) {
     }
 }
 
+test "switch on enum using pointer capture" {
+    testSwitchEnumPtrCapture();
+    comptime testSwitchEnumPtrCapture();
+}
+
+fn testSwitchEnumPtrCapture() {
+    var value = SwitchProngWithVarEnum.One { 1234 };
+    switch (value) {
+        SwitchProngWithVarEnum.One => |*x| *x += 1,
+        else => unreachable,
+    }
+    switch (value) {
+        SwitchProngWithVarEnum.One => |x| assert(x == 1235),
+        else => unreachable,
+    }
+}
 
 test "switch with multiple expressions" {
     const x = switch (returnsFive()) {
@@ -188,3 +204,4 @@ fn testSwitchHandleAllCasesRange(x: u8) -> u8 {
         204 ... 255 => 3,
     }
 }
+