Skip to content

Commit

Permalink
implement implicit cast from enum literal to enum
Browse files Browse the repository at this point in the history
See #683
  • Loading branch information
andrewrk committed Mar 24, 2019
1 parent d0551db commit a736dfe
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down
12 changes: 12 additions & 0 deletions test/stage1/behavior/enum.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit a736dfe

Please sign in to comment.