zig

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

commit a736dfe6a1c7a43c9cb9474255ec34261e5f80ab (tree)
parent d0551db5cd29e4c7f361ef40a37486138a4e8b1e
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Sun, 24 Mar 2019 00:55:55 -0400

implement implicit cast from enum literal to enum

See #683

Diffstat:
Msrc/ir.cpp | 16++++++++++++++++
Mtest/stage1/behavior/enum.zig | 12++++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/src/ir.cpp b/src/ir.cpp @@ -11579,6 +11579,22 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); } + // cast from enum literal to enum with matching field name + if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) { + if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + + TypeEnumField *field = find_enum_type_field(wanted_type, value->value.data.x_enum_literal); + if (field == nullptr) { + ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", + buf_ptr(&wanted_type->name), buf_ptr(value->value.data.x_enum_literal))); + return ira->codegen->invalid_instruction; + } + IrInstruction *result = ir_const(ira, source_instr, wanted_type); + bigint_init_bigint(&result->value.data.x_enum_tag, &field->value); + return result; + } + // cast from union to the enum type of the union if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig @@ -901,3 +901,15 @@ test "enum literal equality" { expect(x != y); expect(x == z); } + +test "enum literal cast to enum" { + const Color = enum { + Auto, + Off, + On, + }; + + var color1: Color = .Auto; + var color2 = Color.Auto; + expect(color1 == color2); +}