| ... | ... | @@ -4230,6 +4230,13 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 4230 | 4230 | return ImplicitCastMatchResultYes; |
| 4231 | 4231 | } |
| 4232 | 4232 | |
| 4233 | // implicitly take a const pointer to something |
| 4234 | { |
| 4235 | TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); |
| 4236 | if (types_match_const_cast_only(expected_type, const_ptr_actual)) { |
| 4237 | return ImplicitCastMatchResultYes; |
| 4238 | } |
| 4239 | } |
| 4233 | 4240 | |
| 4234 | 4241 | return ImplicitCastMatchResultNo; |
| 4235 | 4242 | } |
| ... | ... | @@ -4721,6 +4728,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so |
| 4721 | 4728 | return result; |
| 4722 | 4729 | } |
| 4723 | 4730 | |
| 4731 | static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) { |
| 4732 | if (instr_is_comptime(value)) { |
| 4733 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 4734 | if (!val) |
| 4735 | return ira->codegen->invalid_instruction; |
| 4736 | |
| 4737 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, |
| 4738 | source_instr->scope, source_instr->source_node); |
| 4739 | const_instruction->base.type_entry = wanted_type; |
| 4740 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 4741 | const_instruction->base.static_value.depends_on_compile_var = val->depends_on_compile_var; |
| 4742 | const_instruction->base.static_value.data.x_ptr.base_ptr = val; |
| 4743 | const_instruction->base.static_value.data.x_ptr.index = SIZE_MAX; |
| 4744 | return &const_instruction->base; |
| 4745 | } |
| 4746 | |
| 4747 | if (value->id == IrInstructionIdLoadPtr) { |
| 4748 | IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; |
| 4749 | return load_ptr_inst->ptr; |
| 4750 | } else { |
| 4751 | zig_panic("TODO more ways to cast to const pointer"); |
| 4752 | } |
| 4753 | } |
| 4754 | |
| 4724 | 4755 | static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) { |
| 4725 | 4756 | assert(wanted_type->id == TypeTableEntryIdMaybe); |
| 4726 | 4757 | assert(instr_is_comptime(value)); |
| ... | ... | @@ -4974,6 +5005,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 4974 | 5005 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 4975 | 5006 | } |
| 4976 | 5007 | |
| 5008 | // explicit cast from something to const pointer of it |
| 5009 | { |
| 5010 | TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); |
| 5011 | if (types_match_const_cast_only(wanted_type, const_ptr_actual)) { |
| 5012 | return ir_analyze_cast_ref(ira, source_instr, value, wanted_type); |
| 5013 | } |
| 5014 | } |
| 5015 | |
| 4977 | 5016 | add_node_error(ira->codegen, source_instr->source_node, |
| 4978 | 5017 | buf_sprintf("invalid cast from type '%s' to '%s'", |
| 4979 | 5018 | buf_ptr(&actual_type->name), |