mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
add implicit cast from enum tag type of union to const ptr to the union
closes #654
This commit is contained in:
parent
3577a80bb6
commit
756a218e27
34
src/ir.cpp
34
src/ir.cpp
@ -7492,6 +7492,19 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
||||
}
|
||||
}
|
||||
|
||||
// implicit enum to &const union which has the enum as the tag type
|
||||
if (actual_type->id == TypeTableEntryIdEnum && expected_type->id == TypeTableEntryIdPointer) {
|
||||
TypeTableEntry *union_type = expected_type->data.pointer.child_type;
|
||||
if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
|
||||
union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
|
||||
{
|
||||
type_ensure_zero_bits_known(ira->codegen, union_type);
|
||||
if (union_type->data.unionation.tag_type == actual_type) {
|
||||
return ImplicitCastMatchResultYes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implicit undefined literal to anything
|
||||
if (actual_type->id == TypeTableEntryIdUndefLit) {
|
||||
return ImplicitCastMatchResultYes;
|
||||
@ -9079,6 +9092,27 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
||||
}
|
||||
}
|
||||
|
||||
// explicit enum to &const union which has the enum as the tag type
|
||||
if (actual_type->id == TypeTableEntryIdEnum && wanted_type->id == TypeTableEntryIdPointer) {
|
||||
TypeTableEntry *union_type = wanted_type->data.pointer.child_type;
|
||||
if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
|
||||
union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
|
||||
{
|
||||
type_ensure_zero_bits_known(ira->codegen, union_type);
|
||||
if (union_type->data.unionation.tag_type == actual_type) {
|
||||
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, union_type, value);
|
||||
if (type_is_invalid(cast1->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
|
||||
if (type_is_invalid(cast2->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
return cast2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// explicit cast from undefined to anything
|
||||
if (actual_type->id == TypeTableEntryIdUndefLit) {
|
||||
return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
|
||||
|
||||
@ -206,3 +206,17 @@ test "implicit cast union to its tag type" {
|
||||
fn giveMeLetterB(x: Letter2) {
|
||||
assert(x == Value2.B);
|
||||
}
|
||||
|
||||
test "implicit cast from @EnumTagType(TheUnion) to &const TheUnion" {
|
||||
assertIsTheUnion2Item1(TheUnion2.Item1);
|
||||
}
|
||||
|
||||
const TheUnion2 = union(enum) {
|
||||
Item1,
|
||||
Item2: i32,
|
||||
};
|
||||
|
||||
fn assertIsTheUnion2Item1(value: &const TheUnion2) {
|
||||
assert(*value == TheUnion2.Item1);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user