authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-13 11:04:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-13 11:04:09-04:00
log8dd24796c43b5241a5dcd5508e4be00483ebc25b
tree7946e31a2aff825ee4016ed1f5be46df64726b0b
parent86adc1ef39ed12ebe9eb6d3b7cf8eea481dd060d

disallow implicit casts that break rules for optionals

closes #1102

2 files changed, 197 insertions(+), 148 deletions(-)

src/ir.cpp+184-148
...@@ -7647,23 +7647,24 @@ static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry...@@ -7647,23 +7647,24 @@ static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry
7647}7647}
76487648
76497649
7650static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *expected_type,7650static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *wanted_type,
7651 TypeTableEntry *actual_type, AstNode *source_node)7651 TypeTableEntry *actual_type, AstNode *source_node, bool wanted_is_mutable)
7652{7652{
7653 CodeGen *g = ira->codegen;7653 CodeGen *g = ira->codegen;
7654 ConstCastOnly result = {};7654 ConstCastOnly result = {};
7655 result.id = ConstCastResultIdOk;7655 result.id = ConstCastResultIdOk;
76567656
7657 if (expected_type == actual_type)7657 if (wanted_type == actual_type)
7658 return result;7658 return result;
76597659
7660 // * and [*] can do a const-cast-only to ?* and ?[*], respectively7660 // * and [*] can do a const-cast-only to ?* and ?[*], respectively
7661 if (expected_type->id == TypeTableEntryIdOptional &&7661 // but not if there is a mutable parent pointer
7662 expected_type->data.maybe.child_type->id == TypeTableEntryIdPointer &&7662 if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional &&
7663 wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer &&
7663 actual_type->id == TypeTableEntryIdPointer)7664 actual_type->id == TypeTableEntryIdPointer)
7664 {7665 {
7665 ConstCastOnly child = types_match_const_cast_only(ira,7666 ConstCastOnly child = types_match_const_cast_only(ira,
7666 expected_type->data.maybe.child_type, actual_type, source_node);7667 wanted_type->data.maybe.child_type, actual_type, source_node, wanted_is_mutable);
7667 if (child.id != ConstCastResultIdOk) {7668 if (child.id != ConstCastResultIdOk) {
7668 result.id = ConstCastResultIdNullWrapPtr;7669 result.id = ConstCastResultIdNullWrapPtr;
7669 result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1);7670 result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1);
...@@ -7673,16 +7674,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7673,16 +7674,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7673 }7674 }
76747675
7675 // pointer const7676 // pointer const
7676 if (expected_type->id == TypeTableEntryIdPointer &&7677 if (wanted_type->id == TypeTableEntryIdPointer &&
7677 actual_type->id == TypeTableEntryIdPointer &&7678 actual_type->id == TypeTableEntryIdPointer &&
7678 (actual_type->data.pointer.ptr_len == expected_type->data.pointer.ptr_len) &&7679 (actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
7679 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) &&7680 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
7680 (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) &&7681 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
7681 actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset &&7682 actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
7682 actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count &&7683 actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
7683 actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment)7684 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
7684 {7685 {
7685 ConstCastOnly child = types_match_const_cast_only(ira, expected_type->data.pointer.child_type, actual_type->data.pointer.child_type, source_node);7686 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
7687 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
7686 if (child.id != ConstCastResultIdOk) {7688 if (child.id != ConstCastResultIdOk) {
7687 result.id = ConstCastResultIdPointerChild;7689 result.id = ConstCastResultIdPointerChild;
7688 result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1);7690 result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1);
...@@ -7692,17 +7694,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7692,17 +7694,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7692 }7694 }
76937695
7694 // slice const7696 // slice const
7695 if (is_slice(expected_type) && is_slice(actual_type)) {7697 if (is_slice(wanted_type) && is_slice(actual_type)) {
7696 TypeTableEntry *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry;7698 TypeTableEntry *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry;
7697 TypeTableEntry *expected_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry;7699 TypeTableEntry *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
7698 if ((!actual_ptr_type->data.pointer.is_const || expected_ptr_type->data.pointer.is_const) &&7700 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
7699 (!actual_ptr_type->data.pointer.is_volatile || expected_ptr_type->data.pointer.is_volatile) &&7701 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
7700 actual_ptr_type->data.pointer.bit_offset == expected_ptr_type->data.pointer.bit_offset &&7702 actual_ptr_type->data.pointer.bit_offset == wanted_ptr_type->data.pointer.bit_offset &&
7701 actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count &&7703 actual_ptr_type->data.pointer.unaligned_bit_count == wanted_ptr_type->data.pointer.unaligned_bit_count &&
7702 actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment)7704 actual_ptr_type->data.pointer.alignment >= wanted_ptr_type->data.pointer.alignment)
7703 {7705 {
7704 ConstCastOnly child = types_match_const_cast_only(ira, expected_ptr_type->data.pointer.child_type,7706 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
7705 actual_ptr_type->data.pointer.child_type, source_node);7707 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
7706 if (child.id != ConstCastResultIdOk) {7708 if (child.id != ConstCastResultIdOk) {
7707 result.id = ConstCastResultIdSliceChild;7709 result.id = ConstCastResultIdSliceChild;
7708 result.data.slice_child = allocate_nonzero<ConstCastOnly>(1);7710 result.data.slice_child = allocate_nonzero<ConstCastOnly>(1);
...@@ -7713,8 +7715,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7713,8 +7715,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7713 }7715 }
77147716
7715 // maybe7717 // maybe
7716 if (expected_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) {7718 if (wanted_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) {
7717 ConstCastOnly child = types_match_const_cast_only(ira, expected_type->data.maybe.child_type, actual_type->data.maybe.child_type, source_node);7719 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type,
7720 actual_type->data.maybe.child_type, source_node, wanted_is_mutable);
7718 if (child.id != ConstCastResultIdOk) {7721 if (child.id != ConstCastResultIdOk) {
7719 result.id = ConstCastResultIdOptionalChild;7722 result.id = ConstCastResultIdOptionalChild;
7720 result.data.optional_child = allocate_nonzero<ConstCastOnly>(1);7723 result.data.optional_child = allocate_nonzero<ConstCastOnly>(1);
...@@ -7724,15 +7727,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7724,15 +7727,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7724 }7727 }
77257728
7726 // error union7729 // error union
7727 if (expected_type->id == TypeTableEntryIdErrorUnion && actual_type->id == TypeTableEntryIdErrorUnion) {7730 if (wanted_type->id == TypeTableEntryIdErrorUnion && actual_type->id == TypeTableEntryIdErrorUnion) {
7728 ConstCastOnly payload_child = types_match_const_cast_only(ira, expected_type->data.error_union.payload_type, actual_type->data.error_union.payload_type, source_node);7731 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type,
7732 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable);
7729 if (payload_child.id != ConstCastResultIdOk) {7733 if (payload_child.id != ConstCastResultIdOk) {
7730 result.id = ConstCastResultIdErrorUnionPayload;7734 result.id = ConstCastResultIdErrorUnionPayload;
7731 result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1);7735 result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1);
7732 *result.data.error_union_payload = payload_child;7736 *result.data.error_union_payload = payload_child;
7733 return result;7737 return result;
7734 }7738 }
7735 ConstCastOnly error_set_child = types_match_const_cast_only(ira, expected_type->data.error_union.err_set_type, actual_type->data.error_union.err_set_type, source_node);7739 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type,
7740 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable);
7736 if (error_set_child.id != ConstCastResultIdOk) {7741 if (error_set_child.id != ConstCastResultIdOk) {
7737 result.id = ConstCastResultIdErrorUnionErrorSet;7742 result.id = ConstCastResultIdErrorUnionErrorSet;
7738 result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1);7743 result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1);
...@@ -7743,9 +7748,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7743,9 +7748,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7743 }7748 }
77447749
7745 // error set7750 // error set
7746 if (expected_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) {7751 if (wanted_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) {
7747 TypeTableEntry *contained_set = actual_type;7752 TypeTableEntry *contained_set = actual_type;
7748 TypeTableEntry *container_set = expected_type;7753 TypeTableEntry *container_set = wanted_type;
77497754
7750 // if the container set is inferred, then this will always work.7755 // if the container set is inferred, then this will always work.
7751 if (container_set->data.error_set.infer_fn != nullptr) {7756 if (container_set->data.error_set.infer_fn != nullptr) {
...@@ -7786,36 +7791,37 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7786,36 +7791,37 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7786 return result;7791 return result;
7787 }7792 }
77887793
7789 if (expected_type == ira->codegen->builtin_types.entry_promise &&7794 if (wanted_type == ira->codegen->builtin_types.entry_promise &&
7790 actual_type->id == TypeTableEntryIdPromise)7795 actual_type->id == TypeTableEntryIdPromise)
7791 {7796 {
7792 return result;7797 return result;
7793 }7798 }
77947799
7795 // fn7800 // fn
7796 if (expected_type->id == TypeTableEntryIdFn &&7801 if (wanted_type->id == TypeTableEntryIdFn &&
7797 actual_type->id == TypeTableEntryIdFn)7802 actual_type->id == TypeTableEntryIdFn)
7798 {7803 {
7799 if (expected_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) {7804 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) {
7800 result.id = ConstCastResultIdFnAlign;7805 result.id = ConstCastResultIdFnAlign;
7801 return result;7806 return result;
7802 }7807 }
7803 if (expected_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) {7808 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) {
7804 result.id = ConstCastResultIdFnCC;7809 result.id = ConstCastResultIdFnCC;
7805 return result;7810 return result;
7806 }7811 }
7807 if (expected_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) {7812 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) {
7808 result.id = ConstCastResultIdFnVarArgs;7813 result.id = ConstCastResultIdFnVarArgs;
7809 return result;7814 return result;
7810 }7815 }
7811 if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) {7816 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) {
7812 result.id = ConstCastResultIdFnIsGeneric;7817 result.id = ConstCastResultIdFnIsGeneric;
7813 return result;7818 return result;
7814 }7819 }
7815 if (!expected_type->data.fn.is_generic &&7820 if (!wanted_type->data.fn.is_generic &&
7816 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable)7821 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable)
7817 {7822 {
7818 ConstCastOnly child = types_match_const_cast_only(ira, expected_type->data.fn.fn_type_id.return_type, actual_type->data.fn.fn_type_id.return_type, source_node);7823 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type,
7824 actual_type->data.fn.fn_type_id.return_type, source_node, false);
7819 if (child.id != ConstCastResultIdOk) {7825 if (child.id != ConstCastResultIdOk) {
7820 result.id = ConstCastResultIdFnReturnType;7826 result.id = ConstCastResultIdFnReturnType;
7821 result.data.return_type = allocate_nonzero<ConstCastOnly>(1);7827 result.data.return_type = allocate_nonzero<ConstCastOnly>(1);
...@@ -7823,9 +7829,11 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7823,9 +7829,11 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7823 return result;7829 return result;
7824 }7830 }
7825 }7831 }
7826 if (!expected_type->data.fn.is_generic && expected_type->data.fn.fn_type_id.cc == CallingConventionAsync) {7832 if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
7827 ConstCastOnly child = types_match_const_cast_only(ira, actual_type->data.fn.fn_type_id.async_allocator_type,7833 ConstCastOnly child = types_match_const_cast_only(ira,
7828 expected_type->data.fn.fn_type_id.async_allocator_type, source_node);7834 actual_type->data.fn.fn_type_id.async_allocator_type,
7835 wanted_type->data.fn.fn_type_id.async_allocator_type,
7836 source_node, false);
7829 if (child.id != ConstCastResultIdOk) {7837 if (child.id != ConstCastResultIdOk) {
7830 result.id = ConstCastResultIdAsyncAllocatorType;7838 result.id = ConstCastResultIdAsyncAllocatorType;
7831 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1);7839 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1);
...@@ -7833,22 +7841,23 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7833,22 +7841,23 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7833 return result;7841 return result;
7834 }7842 }
7835 }7843 }
7836 if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) {7844 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) {
7837 result.id = ConstCastResultIdFnArgCount;7845 result.id = ConstCastResultIdFnArgCount;
7838 return result;7846 return result;
7839 }7847 }
7840 if (expected_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) {7848 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) {
7841 result.id = ConstCastResultIdFnGenericArgCount;7849 result.id = ConstCastResultIdFnGenericArgCount;
7842 return result;7850 return result;
7843 }7851 }
7844 assert(expected_type->data.fn.is_generic ||7852 assert(wanted_type->data.fn.is_generic ||
7845 expected_type->data.fn.fn_type_id.next_param_index == expected_type->data.fn.fn_type_id.param_count);7853 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count);
7846 for (size_t i = 0; i < expected_type->data.fn.fn_type_id.next_param_index; i += 1) {7854 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) {
7847 // note it's reversed for parameters7855 // note it's reversed for parameters
7848 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];7856 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];
7849 FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i];7857 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i];
78507858
7851 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, expected_param_info->type, source_node);7859 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type,
7860 expected_param_info->type, source_node, false);
7852 if (arg_child.id != ConstCastResultIdOk) {7861 if (arg_child.id != ConstCastResultIdOk) {
7853 result.id = ConstCastResultIdFnArg;7862 result.id = ConstCastResultIdFnArg;
7854 result.data.fn_arg.arg_index = i;7863 result.data.fn_arg.arg_index = i;
...@@ -7876,11 +7885,12 @@ enum ImplicitCastMatchResult {...@@ -7876,11 +7885,12 @@ enum ImplicitCastMatchResult {
7876 ImplicitCastMatchResultReportedError,7885 ImplicitCastMatchResultReportedError,
7877};7886};
78787887
7879static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,7888static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *wanted_type,
7880 TypeTableEntry *actual_type, IrInstruction *value)7889 TypeTableEntry *actual_type, IrInstruction *value)
7881{7890{
7882 AstNode *source_node = value->source_node;7891 AstNode *source_node = value->source_node;
7883 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, expected_type, actual_type, source_node);7892 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
7893 source_node, false);
7884 if (const_cast_result.id == ConstCastResultIdOk) {7894 if (const_cast_result.id == ConstCastResultIdOk) {
7885 return ImplicitCastMatchResultYes;7895 return ImplicitCastMatchResultYes;
7886 }7896 }
...@@ -7895,21 +7905,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -7895,21 +7905,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
7895 missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors;7905 missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors;
7896 } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) {7906 } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) {
7897 ErrorMsg *msg = ir_add_error(ira, value,7907 ErrorMsg *msg = ir_add_error(ira, value,
7898 buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name)));7908 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
7899 add_error_note(ira->codegen, msg, value->source_node,7909 add_error_note(ira->codegen, msg, value->source_node,
7900 buf_sprintf("unable to cast global error set into smaller set"));7910 buf_sprintf("unable to cast global error set into smaller set"));
7901 return ImplicitCastMatchResultReportedError;7911 return ImplicitCastMatchResultReportedError;
7902 }7912 }
7903 } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) {7913 } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) {
7904 ErrorMsg *msg = ir_add_error(ira, value,7914 ErrorMsg *msg = ir_add_error(ira, value,
7905 buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name)));7915 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
7906 add_error_note(ira->codegen, msg, value->source_node,7916 add_error_note(ira->codegen, msg, value->source_node,
7907 buf_sprintf("unable to cast global error set into smaller set"));7917 buf_sprintf("unable to cast global error set into smaller set"));
7908 return ImplicitCastMatchResultReportedError;7918 return ImplicitCastMatchResultReportedError;
7909 }7919 }
7910 if (missing_errors != nullptr) {7920 if (missing_errors != nullptr) {
7911 ErrorMsg *msg = ir_add_error(ira, value,7921 ErrorMsg *msg = ir_add_error(ira, value,
7912 buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name)));7922 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
7913 for (size_t i = 0; i < missing_errors->length; i += 1) {7923 for (size_t i = 0; i < missing_errors->length; i += 1) {
7914 ErrorTableEntry *error_entry = missing_errors->at(i);7924 ErrorTableEntry *error_entry = missing_errors->at(i);
7915 add_error_note(ira->codegen, msg, error_entry->decl_node,7925 add_error_note(ira->codegen, msg, error_entry->decl_node,
...@@ -7920,162 +7930,168 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -7920,162 +7930,168 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
7920 }7930 }
79217931
7922 // implicit conversion from ?T to ?U7932 // implicit conversion from ?T to ?U
7923 if (expected_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) {7933 if (wanted_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) {
7924 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type,7934 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type,
7925 actual_type->data.maybe.child_type, value);7935 actual_type->data.maybe.child_type, value);
7926 if (res != ImplicitCastMatchResultNo)7936 if (res != ImplicitCastMatchResultNo)
7927 return res;7937 return res;
7928 }7938 }
79297939
7930 // implicit conversion from non maybe type to maybe type7940 // implicit conversion from non maybe type to maybe type
7931 if (expected_type->id == TypeTableEntryIdOptional) {7941 if (wanted_type->id == TypeTableEntryIdOptional) {
7932 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type,7942 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type,
7933 actual_type, value);7943 actual_type, value);
7934 if (res != ImplicitCastMatchResultNo)7944 if (res != ImplicitCastMatchResultNo)
7935 return res;7945 return res;
7936 }7946 }
79377947
7938 // implicit conversion from null literal to maybe type7948 // implicit conversion from null literal to maybe type
7939 if (expected_type->id == TypeTableEntryIdOptional &&7949 if (wanted_type->id == TypeTableEntryIdOptional &&
7940 actual_type->id == TypeTableEntryIdNull)7950 actual_type->id == TypeTableEntryIdNull)
7941 {7951 {
7942 return ImplicitCastMatchResultYes;7952 return ImplicitCastMatchResultYes;
7943 }7953 }
79447954
7945 // implicit T to U!T7955 // implicit T to U!T
7946 if (expected_type->id == TypeTableEntryIdErrorUnion &&7956 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7947 ir_types_match_with_implicit_cast(ira, expected_type->data.error_union.payload_type, actual_type, value))7957 ir_types_match_with_implicit_cast(ira, wanted_type->data.error_union.payload_type, actual_type, value))
7948 {7958 {
7949 return ImplicitCastMatchResultYes;7959 return ImplicitCastMatchResultYes;
7950 }7960 }
79517961
7952 // implicit conversion from error set to error union type7962 // implicit conversion from error set to error union type
7953 if (expected_type->id == TypeTableEntryIdErrorUnion &&7963 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7954 actual_type->id == TypeTableEntryIdErrorSet)7964 actual_type->id == TypeTableEntryIdErrorSet)
7955 {7965 {
7956 return ImplicitCastMatchResultYes;7966 return ImplicitCastMatchResultYes;
7957 }7967 }
79587968
7959 // implicit conversion from T to U!?T7969 // implicit conversion from T to U!?T
7960 if (expected_type->id == TypeTableEntryIdErrorUnion &&7970 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7961 expected_type->data.error_union.payload_type->id == TypeTableEntryIdOptional &&7971 wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional &&
7962 ir_types_match_with_implicit_cast(ira,7972 ir_types_match_with_implicit_cast(ira,
7963 expected_type->data.error_union.payload_type->data.maybe.child_type,7973 wanted_type->data.error_union.payload_type->data.maybe.child_type,
7964 actual_type, value))7974 actual_type, value))
7965 {7975 {
7966 return ImplicitCastMatchResultYes;7976 return ImplicitCastMatchResultYes;
7967 }7977 }
79687978
7969 // implicit widening conversion7979 // implicit widening conversion
7970 if (expected_type->id == TypeTableEntryIdInt &&7980 if (wanted_type->id == TypeTableEntryIdInt &&
7971 actual_type->id == TypeTableEntryIdInt &&7981 actual_type->id == TypeTableEntryIdInt &&
7972 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&7982 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
7973 expected_type->data.integral.bit_count >= actual_type->data.integral.bit_count)7983 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count)
7974 {7984 {
7975 return ImplicitCastMatchResultYes;7985 return ImplicitCastMatchResultYes;
7976 }7986 }
79777987
7978 // small enough unsigned ints can get casted to large enough signed ints7988 // small enough unsigned ints can get casted to large enough signed ints
7979 if (expected_type->id == TypeTableEntryIdInt && expected_type->data.integral.is_signed &&7989 if (wanted_type->id == TypeTableEntryIdInt && wanted_type->data.integral.is_signed &&
7980 actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed &&7990 actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed &&
7981 expected_type->data.integral.bit_count > actual_type->data.integral.bit_count)7991 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count)
7982 {7992 {
7983 return ImplicitCastMatchResultYes;7993 return ImplicitCastMatchResultYes;
7984 }7994 }
79857995
7986 // implicit float widening conversion7996 // implicit float widening conversion
7987 if (expected_type->id == TypeTableEntryIdFloat &&7997 if (wanted_type->id == TypeTableEntryIdFloat &&
7988 actual_type->id == TypeTableEntryIdFloat &&7998 actual_type->id == TypeTableEntryIdFloat &&
7989 expected_type->data.floating.bit_count >= actual_type->data.floating.bit_count)7999 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count)
7990 {8000 {
7991 return ImplicitCastMatchResultYes;8001 return ImplicitCastMatchResultYes;
7992 }8002 }
79938003
7994 // implicit [N]T to []const T8004 // implicit [N]T to []const T
7995 if (is_slice(expected_type) && actual_type->id == TypeTableEntryIdArray) {8005 if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) {
7996 TypeTableEntry *ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry;8006 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
7997 assert(ptr_type->id == TypeTableEntryIdPointer);8007 assert(ptr_type->id == TypeTableEntryIdPointer);
79988008
7999 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8009 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8000 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8010 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
8011 source_node, false).id == ConstCastResultIdOk)
8001 {8012 {
8002 return ImplicitCastMatchResultYes;8013 return ImplicitCastMatchResultYes;
8003 }8014 }
8004 }8015 }
80058016
8006 // implicit &const [N]T to []const T8017 // implicit &const [N]T to []const T
8007 if (is_slice(expected_type) &&8018 if (is_slice(wanted_type) &&
8008 actual_type->id == TypeTableEntryIdPointer &&8019 actual_type->id == TypeTableEntryIdPointer &&
8009 actual_type->data.pointer.ptr_len == PtrLenSingle &&8020 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8010 actual_type->data.pointer.is_const &&8021 actual_type->data.pointer.is_const &&
8011 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)8022 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
8012 {8023 {
8013 TypeTableEntry *ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry;8024 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8014 assert(ptr_type->id == TypeTableEntryIdPointer);8025 assert(ptr_type->id == TypeTableEntryIdPointer);
80158026
8016 TypeTableEntry *array_type = actual_type->data.pointer.child_type;8027 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
80178028
8018 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&8029 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
8019 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8030 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type,
8031 source_node, false).id == ConstCastResultIdOk)
8020 {8032 {
8021 return ImplicitCastMatchResultYes;8033 return ImplicitCastMatchResultYes;
8022 }8034 }
8023 }8035 }
80248036
8025 // implicit [N]T to &const []const T8037 // implicit [N]T to &const []const T
8026 if (expected_type->id == TypeTableEntryIdPointer &&8038 if (wanted_type->id == TypeTableEntryIdPointer &&
8027 expected_type->data.pointer.is_const &&8039 wanted_type->data.pointer.is_const &&
8028 expected_type->data.pointer.ptr_len == PtrLenSingle &&8040 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8029 is_slice(expected_type->data.pointer.child_type) &&8041 is_slice(wanted_type->data.pointer.child_type) &&
8030 actual_type->id == TypeTableEntryIdArray)8042 actual_type->id == TypeTableEntryIdArray)
8031 {8043 {
8032 TypeTableEntry *ptr_type =8044 TypeTableEntry *ptr_type =
8033 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;8045 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
8034 assert(ptr_type->id == TypeTableEntryIdPointer);8046 assert(ptr_type->id == TypeTableEntryIdPointer);
8035 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8047 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8036 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8048 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type,
8049 actual_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8037 {8050 {
8038 return ImplicitCastMatchResultYes;8051 return ImplicitCastMatchResultYes;
8039 }8052 }
8040 }8053 }
80418054
8042 // implicit *[N]T to [*]T8055 // implicit *[N]T to [*]T
8043 if (expected_type->id == TypeTableEntryIdPointer &&8056 if (wanted_type->id == TypeTableEntryIdPointer &&
8044 expected_type->data.pointer.ptr_len == PtrLenUnknown &&8057 wanted_type->data.pointer.ptr_len == PtrLenUnknown &&
8045 actual_type->id == TypeTableEntryIdPointer &&8058 actual_type->id == TypeTableEntryIdPointer &&
8046 actual_type->data.pointer.ptr_len == PtrLenSingle &&8059 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8047 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&8060 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&
8048 types_match_const_cast_only(ira, expected_type->data.pointer.child_type,8061 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
8049 actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8062 actual_type->data.pointer.child_type->data.array.child_type, source_node,
8063 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
8050 {8064 {
8051 return ImplicitCastMatchResultYes;8065 return ImplicitCastMatchResultYes;
8052 }8066 }
80538067
8054 // implicit *[N]T to []T8068 // implicit *[N]T to []T
8055 if (is_slice(expected_type) &&8069 if (is_slice(wanted_type) &&
8056 actual_type->id == TypeTableEntryIdPointer &&8070 actual_type->id == TypeTableEntryIdPointer &&
8057 actual_type->data.pointer.ptr_len == PtrLenSingle &&8071 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8058 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)8072 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
8059 {8073 {
8060 TypeTableEntry *slice_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry;8074 TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8061 assert(slice_ptr_type->id == TypeTableEntryIdPointer);8075 assert(slice_ptr_type->id == TypeTableEntryIdPointer);
8062 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,8076 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
8063 actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8077 actual_type->data.pointer.child_type->data.array.child_type, source_node,
8078 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
8064 {8079 {
8065 return ImplicitCastMatchResultYes;8080 return ImplicitCastMatchResultYes;
8066 }8081 }
8067 }8082 }
80688083
8069 // implicit [N]T to ?[]const T8084 // implicit [N]T to ?[]const T
8070 if (expected_type->id == TypeTableEntryIdOptional &&8085 if (wanted_type->id == TypeTableEntryIdOptional &&
8071 is_slice(expected_type->data.maybe.child_type) &&8086 is_slice(wanted_type->data.maybe.child_type) &&
8072 actual_type->id == TypeTableEntryIdArray)8087 actual_type->id == TypeTableEntryIdArray)
8073 {8088 {
8074 TypeTableEntry *ptr_type =8089 TypeTableEntry *ptr_type =
8075 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;8090 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
8076 assert(ptr_type->id == TypeTableEntryIdPointer);8091 assert(ptr_type->id == TypeTableEntryIdPointer);
8077 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8092 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8078 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8093 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type,
8094 actual_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8079 {8095 {
8080 return ImplicitCastMatchResultYes;8096 return ImplicitCastMatchResultYes;
8081 }8097 }
...@@ -8087,16 +8103,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8087,16 +8103,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8087 if (actual_type->id == TypeTableEntryIdComptimeFloat ||8103 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
8088 actual_type->id == TypeTableEntryIdComptimeInt)8104 actual_type->id == TypeTableEntryIdComptimeInt)
8089 {8105 {
8090 if (expected_type->id == TypeTableEntryIdPointer &&8106 if (wanted_type->id == TypeTableEntryIdPointer &&
8091 expected_type->data.pointer.ptr_len == PtrLenSingle &&8107 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8092 expected_type->data.pointer.is_const)8108 wanted_type->data.pointer.is_const)
8093 {8109 {
8094 if (ir_num_lit_fits_in_other_type(ira, value, expected_type->data.pointer.child_type, false)) {8110 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.pointer.child_type, false)) {
8095 return ImplicitCastMatchResultYes;8111 return ImplicitCastMatchResultYes;
8096 } else {8112 } else {
8097 return ImplicitCastMatchResultReportedError;8113 return ImplicitCastMatchResultReportedError;
8098 }8114 }
8099 } else if (ir_num_lit_fits_in_other_type(ira, value, expected_type, false)) {8115 } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, false)) {
8100 return ImplicitCastMatchResultYes;8116 return ImplicitCastMatchResultYes;
8101 } else {8117 } else {
8102 return ImplicitCastMatchResultReportedError;8118 return ImplicitCastMatchResultReportedError;
...@@ -8106,41 +8122,41 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8106,41 +8122,41 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8106 // implicit typed number to integer or float literal.8122 // implicit typed number to integer or float literal.
8107 // works when the number is known8123 // works when the number is known
8108 if (value->value.special == ConstValSpecialStatic) {8124 if (value->value.special == ConstValSpecialStatic) {
8109 if (actual_type->id == TypeTableEntryIdInt && expected_type->id == TypeTableEntryIdComptimeInt) {8125 if (actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) {
8110 return ImplicitCastMatchResultYes;8126 return ImplicitCastMatchResultYes;
8111 } else if (actual_type->id == TypeTableEntryIdFloat && expected_type->id == TypeTableEntryIdComptimeFloat) {8127 } else if (actual_type->id == TypeTableEntryIdFloat && wanted_type->id == TypeTableEntryIdComptimeFloat) {
8112 return ImplicitCastMatchResultYes;8128 return ImplicitCastMatchResultYes;
8113 }8129 }
8114 }8130 }
81158131
8116 // implicit union to its enum tag type8132 // implicit union to its enum tag type
8117 if (expected_type->id == TypeTableEntryIdEnum && actual_type->id == TypeTableEntryIdUnion &&8133 if (wanted_type->id == TypeTableEntryIdEnum && actual_type->id == TypeTableEntryIdUnion &&
8118 (actual_type->data.unionation.decl_node->data.container_decl.auto_enum ||8134 (actual_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8119 actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))8135 actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
8120 {8136 {
8121 type_ensure_zero_bits_known(ira->codegen, actual_type);8137 type_ensure_zero_bits_known(ira->codegen, actual_type);
8122 if (actual_type->data.unionation.tag_type == expected_type) {8138 if (actual_type->data.unionation.tag_type == wanted_type) {
8123 return ImplicitCastMatchResultYes;8139 return ImplicitCastMatchResultYes;
8124 }8140 }
8125 }8141 }
81268142
8127 // implicit enum to union which has the enum as the tag type8143 // implicit enum to union which has the enum as the tag type
8128 if (expected_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum &&8144 if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum &&
8129 (expected_type->data.unionation.decl_node->data.container_decl.auto_enum ||8145 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8130 expected_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))8146 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
8131 {8147 {
8132 type_ensure_zero_bits_known(ira->codegen, expected_type);8148 type_ensure_zero_bits_known(ira->codegen, wanted_type);
8133 if (expected_type->data.unionation.tag_type == actual_type) {8149 if (wanted_type->data.unionation.tag_type == actual_type) {
8134 return ImplicitCastMatchResultYes;8150 return ImplicitCastMatchResultYes;
8135 }8151 }
8136 }8152 }
81378153
8138 // implicit enum to &const union which has the enum as the tag type8154 // implicit enum to &const union which has the enum as the tag type
8139 if (actual_type->id == TypeTableEntryIdEnum &&8155 if (actual_type->id == TypeTableEntryIdEnum &&
8140 expected_type->id == TypeTableEntryIdPointer &&8156 wanted_type->id == TypeTableEntryIdPointer &&
8141 expected_type->data.pointer.ptr_len == PtrLenSingle)8157 wanted_type->data.pointer.ptr_len == PtrLenSingle)
8142 {8158 {
8143 TypeTableEntry *union_type = expected_type->data.pointer.child_type;8159 TypeTableEntry *union_type = wanted_type->data.pointer.child_type;
8144 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||8160 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8145 union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)8161 union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
8146 {8162 {
...@@ -8152,9 +8168,9 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8152,9 +8168,9 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8152 }8168 }
81538169
8154 // implicit T to *T where T is zero bits8170 // implicit T to *T where T is zero bits
8155 if (expected_type->id == TypeTableEntryIdPointer && expected_type->data.pointer.ptr_len == PtrLenSingle &&8171 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8156 types_match_const_cast_only(ira, expected_type->data.pointer.child_type,8172 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
8157 actual_type, source_node).id == ConstCastResultIdOk)8173 actual_type, source_node, false).id == ConstCastResultIdOk)
8158 {8174 {
8159 type_ensure_zero_bits_known(ira->codegen, actual_type);8175 type_ensure_zero_bits_known(ira->codegen, actual_type);
8160 if (!type_has_bits(actual_type)) {8176 if (!type_has_bits(actual_type)) {
...@@ -8170,10 +8186,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8170,10 +8186,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8170 // implicitly take a const pointer to something8186 // implicitly take a const pointer to something
8171 if (!type_requires_comptime(actual_type)) {8187 if (!type_requires_comptime(actual_type)) {
8172 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);8188 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
8173 if (expected_type->id == TypeTableEntryIdPointer &&8189 if (wanted_type->id == TypeTableEntryIdPointer &&
8174 expected_type->data.pointer.ptr_len == PtrLenSingle &&8190 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8175 types_match_const_cast_only(ira, expected_type, const_ptr_actual,8191 types_match_const_cast_only(ira, wanted_type, const_ptr_actual,
8176 source_node).id == ConstCastResultIdOk)8192 source_node, false).id == ConstCastResultIdOk)
8177 {8193 {
8178 return ImplicitCastMatchResultYes;8194 return ImplicitCastMatchResultYes;
8179 }8195 }
...@@ -8415,9 +8431,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8415,9 +8431,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8415 TypeTableEntry *cur_payload_type = cur_type->data.error_union.payload_type;8431 TypeTableEntry *cur_payload_type = cur_type->data.error_union.payload_type;
84168432
8417 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type,8433 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type,
8418 source_node).id == ConstCastResultIdOk;8434 source_node, false).id == ConstCastResultIdOk;
8419 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type,8435 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type,
8420 source_node).id == ConstCastResultIdOk;8436 source_node, false).id == ConstCastResultIdOk;
84218437
8422 if (const_cast_prev || const_cast_cur) {8438 if (const_cast_prev || const_cast_cur) {
8423 if (const_cast_cur) {8439 if (const_cast_cur) {
...@@ -8504,11 +8520,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8504,11 +8520,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8504 continue;8520 continue;
8505 }8521 }
85068522
8507 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node).id == ConstCastResultIdOk) {8523 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) {
8508 continue;8524 continue;
8509 }8525 }
85108526
8511 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node).id == ConstCastResultIdOk) {8527 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) {
8512 prev_inst = cur_inst;8528 prev_inst = cur_inst;
8513 continue;8529 continue;
8514 }8530 }
...@@ -8531,13 +8547,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8531,13 +8547,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8531 }8547 }
85328548
8533 if (prev_type->id == TypeTableEntryIdErrorUnion &&8549 if (prev_type->id == TypeTableEntryIdErrorUnion &&
8534 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, source_node).id == ConstCastResultIdOk)8550 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type,
8551 source_node, false).id == ConstCastResultIdOk)
8535 {8552 {
8536 continue;8553 continue;
8537 }8554 }
85388555
8539 if (cur_type->id == TypeTableEntryIdErrorUnion &&8556 if (cur_type->id == TypeTableEntryIdErrorUnion &&
8540 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, source_node).id == ConstCastResultIdOk)8557 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type,
8558 source_node, false).id == ConstCastResultIdOk)
8541 {8559 {
8542 if (err_set_type != nullptr) {8560 if (err_set_type != nullptr) {
8543 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;8561 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
...@@ -8559,13 +8577,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8559,13 +8577,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8559 }8577 }
85608578
8561 if (prev_type->id == TypeTableEntryIdOptional &&8579 if (prev_type->id == TypeTableEntryIdOptional &&
8562 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, source_node).id == ConstCastResultIdOk)8580 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type,
8581 source_node, false).id == ConstCastResultIdOk)
8563 {8582 {
8564 continue;8583 continue;
8565 }8584 }
85668585
8567 if (cur_type->id == TypeTableEntryIdOptional &&8586 if (cur_type->id == TypeTableEntryIdOptional &&
8568 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, source_node).id == ConstCastResultIdOk)8587 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type,
8588 source_node, false).id == ConstCastResultIdOk)
8569 {8589 {
8570 prev_inst = cur_inst;8590 prev_inst = cur_inst;
8571 continue;8591 continue;
...@@ -8602,8 +8622,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8602,8 +8622,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8602 }8622 }
86038623
8604 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&8624 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
8605 cur_type->data.array.len != prev_type->data.array.len &&8625 cur_type->data.array.len != prev_type->data.array.len &&
8606 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8626 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type,
8627 source_node, false).id == ConstCastResultIdOk)
8607 {8628 {
8608 convert_to_const_slice = true;8629 convert_to_const_slice = true;
8609 prev_inst = cur_inst;8630 prev_inst = cur_inst;
...@@ -8611,8 +8632,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8611,8 +8632,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8611 }8632 }
86128633
8613 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&8634 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
8614 cur_type->data.array.len != prev_type->data.array.len &&8635 cur_type->data.array.len != prev_type->data.array.len &&
8615 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8636 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type,
8637 source_node, false).id == ConstCastResultIdOk)
8616 {8638 {
8617 convert_to_const_slice = true;8639 convert_to_const_slice = true;
8618 continue;8640 continue;
...@@ -8621,8 +8643,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8621,8 +8643,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8621 if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&8643 if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
8622 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||8644 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
8623 cur_type->data.array.len == 0) &&8645 cur_type->data.array.len == 0) &&
8624 types_match_const_cast_only(ira, prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,8646 types_match_const_cast_only(ira,
8625 cur_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8647 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
8648 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8626 {8649 {
8627 convert_to_const_slice = false;8650 convert_to_const_slice = false;
8628 continue;8651 continue;
...@@ -8631,8 +8654,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8631,8 +8654,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8631 if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&8654 if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
8632 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||8655 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
8633 prev_type->data.array.len == 0) &&8656 prev_type->data.array.len == 0) &&
8634 types_match_const_cast_only(ira, cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,8657 types_match_const_cast_only(ira,
8635 prev_type->data.array.child_type, source_node).id == ConstCastResultIdOk)8658 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
8659 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8636 {8660 {
8637 prev_inst = cur_inst;8661 prev_inst = cur_inst;
8638 convert_to_const_slice = false;8662 convert_to_const_slice = false;
...@@ -9913,7 +9937,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9913,7 +9937,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9913 }9937 }
99149938
9915 // explicit match or non-const to const9939 // explicit match or non-const to const
9916 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node).id == ConstCastResultIdOk) {9940 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node, false).id == ConstCastResultIdOk) {
9917 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);9941 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
9918 }9942 }
99199943
...@@ -9959,7 +9983,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9959,7 +9983,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9959 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;9983 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
9960 assert(ptr_type->id == TypeTableEntryIdPointer);9984 assert(ptr_type->id == TypeTableEntryIdPointer);
9961 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&9985 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
9962 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)9986 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
9987 source_node, false).id == ConstCastResultIdOk)
9963 {9988 {
9964 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);9989 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
9965 }9990 }
...@@ -9977,7 +10002,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9977,7 +10002,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9977 TypeTableEntry *array_type = actual_type->data.pointer.child_type;10002 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
997810003
9979 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&10004 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
9980 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10005 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type,
10006 source_node, false).id == ConstCastResultIdOk)
9981 {10007 {
9982 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);10008 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
9983 }10009 }
...@@ -9993,7 +10019,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9993,7 +10019,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9993 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;10019 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
9994 assert(ptr_type->id == TypeTableEntryIdPointer);10020 assert(ptr_type->id == TypeTableEntryIdPointer);
9995 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&10021 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
9996 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10022 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
10023 source_node, false).id == ConstCastResultIdOk)
9997 {10024 {
9998 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);10025 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
9999 if (type_is_invalid(cast1->value.type))10026 if (type_is_invalid(cast1->value.type))
...@@ -10016,7 +10043,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10016,7 +10043,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10016 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;10043 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
10017 assert(ptr_type->id == TypeTableEntryIdPointer);10044 assert(ptr_type->id == TypeTableEntryIdPointer);
10018 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&10045 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
10019 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10046 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
10047 source_node, false).id == ConstCastResultIdOk)
10020 {10048 {
10021 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);10049 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
10022 if (type_is_invalid(cast1->value.type))10050 if (type_is_invalid(cast1->value.type))
...@@ -10084,7 +10112,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10084,7 +10112,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10084 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&10112 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&
10085 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment &&10113 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment &&
10086 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,10114 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
10087 actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10115 actual_type->data.pointer.child_type->data.array.child_type, source_node,
10116 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
10088 {10117 {
10089 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);10118 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
10090 }10119 }
...@@ -10098,7 +10127,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10098,7 +10127,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10098 TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;10127 TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
10099 assert(slice_ptr_type->id == TypeTableEntryIdPointer);10128 assert(slice_ptr_type->id == TypeTableEntryIdPointer);
10100 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,10129 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
10101 actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10130 actual_type->data.pointer.child_type->data.array.child_type, source_node,
10131 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
10102 {10132 {
10103 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);10133 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);
10104 }10134 }
...@@ -10109,7 +10139,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10109,7 +10139,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10109 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism10139 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism
10110 if (wanted_type->id == TypeTableEntryIdOptional) {10140 if (wanted_type->id == TypeTableEntryIdOptional) {
10111 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;10141 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;
10112 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk) {10142 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,
10143 false).id == ConstCastResultIdOk)
10144 {
10113 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);10145 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
10114 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||10146 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
10115 actual_type->id == TypeTableEntryIdComptimeFloat)10147 actual_type->id == TypeTableEntryIdComptimeFloat)
...@@ -10144,7 +10176,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10144,7 +10176,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1014410176
10145 // explicit cast from child type of error type to error type10177 // explicit cast from child type of error type to error type
10146 if (wanted_type->id == TypeTableEntryIdErrorUnion) {10178 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
10147 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, source_node).id == ConstCastResultIdOk) {10179 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
10180 source_node, false).id == ConstCastResultIdOk)
10181 {
10148 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);10182 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
10149 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||10183 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
10150 actual_type->id == TypeTableEntryIdComptimeFloat)10184 actual_type->id == TypeTableEntryIdComptimeFloat)
...@@ -10166,7 +10200,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10166,7 +10200,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10166 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;10200 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
10167 assert(ptr_type->id == TypeTableEntryIdPointer);10201 assert(ptr_type->id == TypeTableEntryIdPointer);
10168 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&10202 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
10169 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, source_node).id == ConstCastResultIdOk)10203 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
10204 source_node, false).id == ConstCastResultIdOk)
10170 {10205 {
10171 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);10206 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
10172 if (type_is_invalid(cast1->value.type))10207 if (type_is_invalid(cast1->value.type))
...@@ -10193,7 +10228,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10193,7 +10228,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10193 actual_type->id != TypeTableEntryIdOptional)10228 actual_type->id != TypeTableEntryIdOptional)
10194 {10229 {
10195 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;10230 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
10196 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk ||10231 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk ||
10197 actual_type->id == TypeTableEntryIdNull ||10232 actual_type->id == TypeTableEntryIdNull ||
10198 actual_type->id == TypeTableEntryIdComptimeInt ||10233 actual_type->id == TypeTableEntryIdComptimeInt ||
10199 actual_type->id == TypeTableEntryIdComptimeFloat)10234 actual_type->id == TypeTableEntryIdComptimeFloat)
...@@ -10345,7 +10380,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10345,7 +10380,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10345 TypeTableEntry *array_type = wanted_type->data.pointer.child_type;10380 TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
10346 if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 &&10381 if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 &&
10347 types_match_const_cast_only(ira, array_type->data.array.child_type,10382 types_match_const_cast_only(ira, array_type->data.array.child_type,
10348 actual_type->data.pointer.child_type, source_node).id == ConstCastResultIdOk)10383 actual_type->data.pointer.child_type, source_node,
10384 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
10349 {10385 {
10350 if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {10386 if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {
10351 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));10387 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));
...@@ -10364,7 +10400,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10364,7 +10400,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10364 // explicit cast from T to *T where T is zero bits10400 // explicit cast from T to *T where T is zero bits
10365 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&10401 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
10366 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,10402 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
10367 actual_type, source_node).id == ConstCastResultIdOk)10403 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
10368 {10404 {
10369 type_ensure_zero_bits_known(ira->codegen, actual_type);10405 type_ensure_zero_bits_known(ira->codegen, actual_type);
10370 if (type_is_invalid(actual_type)) {10406 if (type_is_invalid(actual_type)) {
...@@ -10384,7 +10420,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10384,7 +10420,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10384 // explicit cast from something to const pointer of it10420 // explicit cast from something to const pointer of it
10385 if (!type_requires_comptime(actual_type)) {10421 if (!type_requires_comptime(actual_type)) {
10386 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);10422 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
10387 if (types_match_const_cast_only(ira, wanted_type, const_ptr_actual, source_node).id == ConstCastResultIdOk) {10423 if (types_match_const_cast_only(ira, wanted_type, const_ptr_actual, source_node, false).id == ConstCastResultIdOk) {
10388 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);10424 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
10389 }10425 }
10390 }10426 }
test/compile_errors.zig+13
...@@ -1,6 +1,19 @@...@@ -1,6 +1,19 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "use implicit casts to assign null to non-nullable pointer",
6 \\export fn entry() void {
7 \\ var x: i32 = 1234;
8 \\ var p: *i32 = &x;
9 \\ var pp: *?*i32 = &p;
10 \\ pp.* = null;
11 \\ var y = p.*;
12 \\}
13 ,
14 ".tmp_source.zig:4:23: error: expected type '*?*i32', found '**i32'",
15 );
16
4 cases.add(17 cases.add(
5 "attempted implicit cast from T to [*]const T",18 "attempted implicit cast from T to [*]const T",
6 \\export fn entry() void {19 \\export fn entry() void {