zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 11d8a8cc7b6984f2c79923a5e3f763003f2b558f (tree)
parent 818a0a26291cf456cfaa955401b1aa8219737d6c
Author: Andrew Kelley <superjoe30@gmail.com>
Date:   Sun,  7 May 2017 13:21:53 -0400

fix comptime switch on enum with ref payload

See #43

Diffstat:
Msrc/ir.cpp | 14+++++---------
Mtest/cases/switch.zig | 17+++++++++++++++++
2 files changed, 22 insertions(+), 9 deletions(-)

diff --git 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 @@ -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, } } +