Commit 5fd3af9dc6
Changed files (2)
src
test
cases
src/ir.cpp
@@ -10015,21 +10015,25 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_
if (value->id == IrInstructionIdLoadPtr) {
IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value;
- return load_ptr_inst->ptr;
- } else {
- IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope,
- source_instr->source_node, value, true, false);
- new_instruction->value.type = wanted_type;
+ ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type,
+ load_ptr_inst->ptr->value.type, source_instr->source_node, false);
+ if (const_cast_result.id == ConstCastResultIdInvalid)
+ return ira->codegen->invalid_instruction;
+ if (const_cast_result.id == ConstCastResultIdOk)
+ return load_ptr_inst->ptr;
+ }
+ IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, value, true, false);
+ new_instruction->value.type = wanted_type;
- ZigType *child_type = wanted_type->data.pointer.child_type;
- if (type_has_bits(child_type)) {
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- assert(fn_entry);
- fn_entry->alloca_list.append(new_instruction);
- }
- ir_add_alloca(ira, new_instruction, child_type);
- return new_instruction;
+ ZigType *child_type = wanted_type->data.pointer.child_type;
+ if (type_has_bits(child_type)) {
+ ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
+ assert(fn_entry);
+ fn_entry->alloca_list.append(new_instruction);
}
+ ir_add_alloca(ira, new_instruction, child_type);
+ return new_instruction;
}
static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) {
@@ -11057,7 +11061,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
- // enum to &const union which has the enum as the tag type
+ // enum to *const union which has the enum as the tag type
if (actual_type->id == ZigTypeIdEnum && wanted_type->id == ZigTypeIdPointer) {
ZigType *union_type = wanted_type->data.pointer.child_type;
if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
test/cases/struct.zig
@@ -437,3 +437,19 @@ test "call method with mutable reference to struct with no fields" {
assert(S.do(&s));
assert(s.do());
}
+
+test "implicit cast packed struct field to const ptr" {
+ const LevelUpMove = packed struct {
+ move_id: u9,
+ level: u7,
+
+ fn toInt(value: *const u7) u7 {
+ return value.*;
+ }
+ };
+
+ var lup: LevelUpMove = undefined;
+ lup.level = 12;
+ const res = LevelUpMove.toInt(lup.level);
+ assert(res == 12);
+}