From 11d8a8cc7b6984f2c79923a5e3f763003f2b558f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 7 May 2017 13:21:53 -0400 Subject: [PATCH] fix comptime switch on enum with ref payload See #43 --- src/ir.cpp | 14 +++++--------- test/cases/switch.zig | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 6f8322c9d9..f5ced359ba 100644 --- a/src/ir.cpp +++ b/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); diff --git a/test/cases/switch.zig b/test/cases/switch.zig index ccacbd1c78..dfec42ea87 100644 --- a/test/cases/switch.zig +++ b/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, } } +