| ... | ... | @@ -7647,23 +7647,24 @@ static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry |
| 7647 | 7647 | } |
| 7648 | 7648 | |
| 7649 | 7649 | |
| 7650 | | static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *expected_type, |
| 7651 | | TypeTableEntry *actual_type, AstNode *source_node) |
| 7650 | static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *wanted_type, |
| 7651 | TypeTableEntry *actual_type, AstNode *source_node, bool wanted_is_mutable) |
| 7652 | 7652 | { |
| 7653 | 7653 | CodeGen *g = ira->codegen; |
| 7654 | 7654 | ConstCastOnly result = {}; |
| 7655 | 7655 | result.id = ConstCastResultIdOk; |
| 7656 | 7656 | |
| 7657 | | if (expected_type == actual_type) |
| 7657 | if (wanted_type == actual_type) |
| 7658 | 7658 | return result; |
| 7659 | 7659 | |
| 7660 | 7660 | // * and [*] can do a const-cast-only to ?* and ?[*], respectively |
| 7661 | | if (expected_type->id == TypeTableEntryIdOptional && |
| 7662 | | expected_type->data.maybe.child_type->id == TypeTableEntryIdPointer && |
| 7661 | // but not if there is a mutable parent pointer |
| 7662 | if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional && |
| 7663 | wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer && |
| 7663 | 7664 | actual_type->id == TypeTableEntryIdPointer) |
| 7664 | 7665 | { |
| 7665 | 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 | 7668 | if (child.id != ConstCastResultIdOk) { |
| 7668 | 7669 | result.id = ConstCastResultIdNullWrapPtr; |
| 7669 | 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 | 7674 | } |
| 7674 | 7675 | |
| 7675 | 7676 | // pointer const |
| 7676 | | if (expected_type->id == TypeTableEntryIdPointer && |
| 7677 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 7677 | 7678 | actual_type->id == TypeTableEntryIdPointer && |
| 7678 | | (actual_type->data.pointer.ptr_len == expected_type->data.pointer.ptr_len) && |
| 7679 | | (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) && |
| 7680 | | (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) && |
| 7681 | | actual_type->data.pointer.bit_offset == expected_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.alignment >= expected_type->data.pointer.alignment) |
| 7679 | (actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) && |
| 7680 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && |
| 7681 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) && |
| 7682 | actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset && |
| 7683 | actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count && |
| 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 | 7688 | if (child.id != ConstCastResultIdOk) { |
| 7687 | 7689 | result.id = ConstCastResultIdPointerChild; |
| 7688 | 7690 | result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1); |
| ... | ... | @@ -7692,17 +7694,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 7692 | 7694 | } |
| 7693 | 7695 | |
| 7694 | 7696 | // slice const |
| 7695 | | if (is_slice(expected_type) && is_slice(actual_type)) { |
| 7697 | if (is_slice(wanted_type) && is_slice(actual_type)) { |
| 7696 | 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; |
| 7698 | | if ((!actual_ptr_type->data.pointer.is_const || expected_ptr_type->data.pointer.is_const) && |
| 7699 | | (!actual_ptr_type->data.pointer.is_volatile || expected_ptr_type->data.pointer.is_volatile) && |
| 7700 | | actual_ptr_type->data.pointer.bit_offset == expected_ptr_type->data.pointer.bit_offset && |
| 7701 | | actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count && |
| 7702 | | actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment) |
| 7699 | TypeTableEntry *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| 7700 | if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && |
| 7701 | (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && |
| 7702 | actual_ptr_type->data.pointer.bit_offset == wanted_ptr_type->data.pointer.bit_offset && |
| 7703 | actual_ptr_type->data.pointer.unaligned_bit_count == wanted_ptr_type->data.pointer.unaligned_bit_count && |
| 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, |
| 7705 | | actual_ptr_type->data.pointer.child_type, source_node); |
| 7706 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, |
| 7707 | actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); |
| 7706 | 7708 | if (child.id != ConstCastResultIdOk) { |
| 7707 | 7709 | result.id = ConstCastResultIdSliceChild; |
| 7708 | 7710 | result.data.slice_child = allocate_nonzero<ConstCastOnly>(1); |
| ... | ... | @@ -7713,8 +7715,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 7713 | 7715 | } |
| 7714 | 7716 | |
| 7715 | 7717 | // maybe |
| 7716 | | if (expected_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); |
| 7718 | if (wanted_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) { |
| 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 | 7721 | if (child.id != ConstCastResultIdOk) { |
| 7719 | 7722 | result.id = ConstCastResultIdOptionalChild; |
| 7720 | 7723 | result.data.optional_child = allocate_nonzero<ConstCastOnly>(1); |
| ... | ... | @@ -7724,15 +7727,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 7724 | 7727 | } |
| 7725 | 7728 | |
| 7726 | 7729 | // error union |
| 7727 | | if (expected_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); |
| 7730 | if (wanted_type->id == TypeTableEntryIdErrorUnion && actual_type->id == TypeTableEntryIdErrorUnion) { |
| 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 | 7733 | if (payload_child.id != ConstCastResultIdOk) { |
| 7730 | 7734 | result.id = ConstCastResultIdErrorUnionPayload; |
| 7731 | 7735 | result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1); |
| 7732 | 7736 | *result.data.error_union_payload = payload_child; |
| 7733 | 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 | 7741 | if (error_set_child.id != ConstCastResultIdOk) { |
| 7737 | 7742 | result.id = ConstCastResultIdErrorUnionErrorSet; |
| 7738 | 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 | 7748 | } |
| 7744 | 7749 | |
| 7745 | 7750 | // error set |
| 7746 | | if (expected_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) { |
| 7751 | if (wanted_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) { |
| 7747 | 7752 | TypeTableEntry *contained_set = actual_type; |
| 7748 | | TypeTableEntry *container_set = expected_type; |
| 7753 | TypeTableEntry *container_set = wanted_type; |
| 7749 | 7754 | |
| 7750 | 7755 | // if the container set is inferred, then this will always work. |
| 7751 | 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 | 7791 | return result; |
| 7787 | 7792 | } |
| 7788 | 7793 | |
| 7789 | | if (expected_type == ira->codegen->builtin_types.entry_promise && |
| 7794 | if (wanted_type == ira->codegen->builtin_types.entry_promise && |
| 7790 | 7795 | actual_type->id == TypeTableEntryIdPromise) |
| 7791 | 7796 | { |
| 7792 | 7797 | return result; |
| 7793 | 7798 | } |
| 7794 | 7799 | |
| 7795 | 7800 | // fn |
| 7796 | | if (expected_type->id == TypeTableEntryIdFn && |
| 7801 | if (wanted_type->id == TypeTableEntryIdFn && |
| 7797 | 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 | 7805 | result.id = ConstCastResultIdFnAlign; |
| 7801 | 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 | 7809 | result.id = ConstCastResultIdFnCC; |
| 7805 | 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 | 7813 | result.id = ConstCastResultIdFnVarArgs; |
| 7809 | 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 | 7817 | result.id = ConstCastResultIdFnIsGeneric; |
| 7813 | 7818 | return result; |
| 7814 | 7819 | } |
| 7815 | | if (!expected_type->data.fn.is_generic && |
| 7820 | if (!wanted_type->data.fn.is_generic && |
| 7816 | 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 | 7825 | if (child.id != ConstCastResultIdOk) { |
| 7820 | 7826 | result.id = ConstCastResultIdFnReturnType; |
| 7821 | 7827 | result.data.return_type = allocate_nonzero<ConstCastOnly>(1); |
| ... | ... | @@ -7823,9 +7829,11 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 7823 | 7829 | return result; |
| 7824 | 7830 | } |
| 7825 | 7831 | } |
| 7826 | | if (!expected_type->data.fn.is_generic && expected_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, |
| 7828 | | expected_type->data.fn.fn_type_id.async_allocator_type, source_node); |
| 7832 | if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { |
| 7833 | ConstCastOnly child = types_match_const_cast_only(ira, |
| 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 | 7837 | if (child.id != ConstCastResultIdOk) { |
| 7830 | 7838 | result.id = ConstCastResultIdAsyncAllocatorType; |
| 7831 | 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 | 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 | 7845 | result.id = ConstCastResultIdFnArgCount; |
| 7838 | 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 | 7849 | result.id = ConstCastResultIdFnGenericArgCount; |
| 7842 | 7850 | return result; |
| 7843 | 7851 | } |
| 7844 | | assert(expected_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); |
| 7846 | | for (size_t i = 0; i < expected_type->data.fn.fn_type_id.next_param_index; i += 1) { |
| 7852 | assert(wanted_type->data.fn.is_generic || |
| 7853 | wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); |
| 7854 | for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { |
| 7847 | 7855 | // note it's reversed for parameters |
| 7848 | 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]; |
| 7850 | 7858 | |
| 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 | 7861 | if (arg_child.id != ConstCastResultIdOk) { |
| 7853 | 7862 | result.id = ConstCastResultIdFnArg; |
| 7854 | 7863 | result.data.fn_arg.arg_index = i; |
| ... | ... | @@ -7876,11 +7885,12 @@ enum ImplicitCastMatchResult { |
| 7876 | 7885 | ImplicitCastMatchResultReportedError, |
| 7877 | 7886 | }; |
| 7878 | 7887 | |
| 7879 | | static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type, |
| 7888 | static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *wanted_type, |
| 7880 | 7889 | TypeTableEntry *actual_type, IrInstruction *value) |
| 7881 | 7890 | { |
| 7882 | 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 | 7894 | if (const_cast_result.id == ConstCastResultIdOk) { |
| 7885 | 7895 | return ImplicitCastMatchResultYes; |
| 7886 | 7896 | } |
| ... | ... | @@ -7895,21 +7905,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 7895 | 7905 | missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors; |
| 7896 | 7906 | } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) { |
| 7897 | 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 | 7909 | add_error_note(ira->codegen, msg, value->source_node, |
| 7900 | 7910 | buf_sprintf("unable to cast global error set into smaller set")); |
| 7901 | 7911 | return ImplicitCastMatchResultReportedError; |
| 7902 | 7912 | } |
| 7903 | 7913 | } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) { |
| 7904 | 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 | 7916 | add_error_note(ira->codegen, msg, value->source_node, |
| 7907 | 7917 | buf_sprintf("unable to cast global error set into smaller set")); |
| 7908 | 7918 | return ImplicitCastMatchResultReportedError; |
| 7909 | 7919 | } |
| 7910 | 7920 | if (missing_errors != nullptr) { |
| 7911 | 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 | 7923 | for (size_t i = 0; i < missing_errors->length; i += 1) { |
| 7914 | 7924 | ErrorTableEntry *error_entry = missing_errors->at(i); |
| 7915 | 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 | 7930 | } |
| 7921 | 7931 | |
| 7922 | 7932 | // implicit conversion from ?T to ?U |
| 7923 | | if (expected_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) { |
| 7924 | | ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, |
| 7933 | if (wanted_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) { |
| 7934 | ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type, |
| 7925 | 7935 | actual_type->data.maybe.child_type, value); |
| 7926 | 7936 | if (res != ImplicitCastMatchResultNo) |
| 7927 | 7937 | return res; |
| 7928 | 7938 | } |
| 7929 | 7939 | |
| 7930 | 7940 | // implicit conversion from non maybe type to maybe type |
| 7931 | | if (expected_type->id == TypeTableEntryIdOptional) { |
| 7932 | | ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, expected_type->data.maybe.child_type, |
| 7941 | if (wanted_type->id == TypeTableEntryIdOptional) { |
| 7942 | ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type, |
| 7933 | 7943 | actual_type, value); |
| 7934 | 7944 | if (res != ImplicitCastMatchResultNo) |
| 7935 | 7945 | return res; |
| 7936 | 7946 | } |
| 7937 | 7947 | |
| 7938 | 7948 | // implicit conversion from null literal to maybe type |
| 7939 | | if (expected_type->id == TypeTableEntryIdOptional && |
| 7949 | if (wanted_type->id == TypeTableEntryIdOptional && |
| 7940 | 7950 | actual_type->id == TypeTableEntryIdNull) |
| 7941 | 7951 | { |
| 7942 | 7952 | return ImplicitCastMatchResultYes; |
| 7943 | 7953 | } |
| 7944 | 7954 | |
| 7945 | 7955 | // implicit T to U!T |
| 7946 | | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 7947 | | ir_types_match_with_implicit_cast(ira, expected_type->data.error_union.payload_type, actual_type, value)) |
| 7956 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 7957 | ir_types_match_with_implicit_cast(ira, wanted_type->data.error_union.payload_type, actual_type, value)) |
| 7948 | 7958 | { |
| 7949 | 7959 | return ImplicitCastMatchResultYes; |
| 7950 | 7960 | } |
| 7951 | 7961 | |
| 7952 | 7962 | // implicit conversion from error set to error union type |
| 7953 | | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 7963 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 7954 | 7964 | actual_type->id == TypeTableEntryIdErrorSet) |
| 7955 | 7965 | { |
| 7956 | 7966 | return ImplicitCastMatchResultYes; |
| 7957 | 7967 | } |
| 7958 | 7968 | |
| 7959 | 7969 | // implicit conversion from T to U!?T |
| 7960 | | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 7961 | | expected_type->data.error_union.payload_type->id == TypeTableEntryIdOptional && |
| 7970 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 7971 | wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional && |
| 7962 | 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 | 7974 | actual_type, value)) |
| 7965 | 7975 | { |
| 7966 | 7976 | return ImplicitCastMatchResultYes; |
| 7967 | 7977 | } |
| 7968 | 7978 | |
| 7969 | 7979 | // implicit widening conversion |
| 7970 | | if (expected_type->id == TypeTableEntryIdInt && |
| 7980 | if (wanted_type->id == TypeTableEntryIdInt && |
| 7971 | 7981 | actual_type->id == TypeTableEntryIdInt && |
| 7972 | | expected_type->data.integral.is_signed == actual_type->data.integral.is_signed && |
| 7973 | | expected_type->data.integral.bit_count >= actual_type->data.integral.bit_count) |
| 7982 | wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && |
| 7983 | wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) |
| 7974 | 7984 | { |
| 7975 | 7985 | return ImplicitCastMatchResultYes; |
| 7976 | 7986 | } |
| 7977 | 7987 | |
| 7978 | 7988 | // 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 | 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 | 7993 | return ImplicitCastMatchResultYes; |
| 7984 | 7994 | } |
| 7985 | 7995 | |
| 7986 | 7996 | // implicit float widening conversion |
| 7987 | | if (expected_type->id == TypeTableEntryIdFloat && |
| 7997 | if (wanted_type->id == TypeTableEntryIdFloat && |
| 7988 | 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 | 8001 | return ImplicitCastMatchResultYes; |
| 7992 | 8002 | } |
| 7993 | 8003 | |
| 7994 | 8004 | // implicit [N]T to []const T |
| 7995 | | if (is_slice(expected_type) && actual_type->id == TypeTableEntryIdArray) { |
| 7996 | | TypeTableEntry *ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry; |
| 8005 | if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) { |
| 8006 | TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| 7997 | 8007 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 7998 | 8008 | |
| 7999 | 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 | 8013 | return ImplicitCastMatchResultYes; |
| 8003 | 8014 | } |
| 8004 | 8015 | } |
| 8005 | 8016 | |
| 8006 | 8017 | // implicit &const [N]T to []const T |
| 8007 | | if (is_slice(expected_type) && |
| 8018 | if (is_slice(wanted_type) && |
| 8008 | 8019 | actual_type->id == TypeTableEntryIdPointer && |
| 8009 | 8020 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 8010 | 8021 | actual_type->data.pointer.is_const && |
| 8011 | 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 | 8025 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 8015 | 8026 | |
| 8016 | 8027 | TypeTableEntry *array_type = actual_type->data.pointer.child_type; |
| 8017 | 8028 | |
| 8018 | 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 | 8033 | return ImplicitCastMatchResultYes; |
| 8022 | 8034 | } |
| 8023 | 8035 | } |
| 8024 | 8036 | |
| 8025 | 8037 | // implicit [N]T to &const []const T |
| 8026 | | if (expected_type->id == TypeTableEntryIdPointer && |
| 8027 | | expected_type->data.pointer.is_const && |
| 8028 | | expected_type->data.pointer.ptr_len == PtrLenSingle && |
| 8029 | | is_slice(expected_type->data.pointer.child_type) && |
| 8038 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 8039 | wanted_type->data.pointer.is_const && |
| 8040 | wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 8041 | is_slice(wanted_type->data.pointer.child_type) && |
| 8030 | 8042 | actual_type->id == TypeTableEntryIdArray) |
| 8031 | 8043 | { |
| 8032 | 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 | 8046 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 8035 | 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 | 8051 | return ImplicitCastMatchResultYes; |
| 8039 | 8052 | } |
| 8040 | 8053 | } |
| 8041 | 8054 | |
| 8042 | 8055 | // implicit *[N]T to [*]T |
| 8043 | | if (expected_type->id == TypeTableEntryIdPointer && |
| 8044 | | expected_type->data.pointer.ptr_len == PtrLenUnknown && |
| 8056 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 8057 | wanted_type->data.pointer.ptr_len == PtrLenUnknown && |
| 8045 | 8058 | actual_type->id == TypeTableEntryIdPointer && |
| 8046 | 8059 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 8047 | 8060 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray && |
| 8048 | | types_match_const_cast_only(ira, expected_type->data.pointer.child_type, |
| 8049 | | actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| 8061 | types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, |
| 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 | 8065 | return ImplicitCastMatchResultYes; |
| 8052 | 8066 | } |
| 8053 | 8067 | |
| 8054 | 8068 | // implicit *[N]T to []T |
| 8055 | | if (is_slice(expected_type) && |
| 8069 | if (is_slice(wanted_type) && |
| 8056 | 8070 | actual_type->id == TypeTableEntryIdPointer && |
| 8057 | 8071 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 8058 | 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 | 8075 | assert(slice_ptr_type->id == TypeTableEntryIdPointer); |
| 8062 | 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 | 8080 | return ImplicitCastMatchResultYes; |
| 8066 | 8081 | } |
| 8067 | 8082 | } |
| 8068 | 8083 | |
| 8069 | 8084 | // implicit [N]T to ?[]const T |
| 8070 | | if (expected_type->id == TypeTableEntryIdOptional && |
| 8071 | | is_slice(expected_type->data.maybe.child_type) && |
| 8085 | if (wanted_type->id == TypeTableEntryIdOptional && |
| 8086 | is_slice(wanted_type->data.maybe.child_type) && |
| 8072 | 8087 | actual_type->id == TypeTableEntryIdArray) |
| 8073 | 8088 | { |
| 8074 | 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 | 8091 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 8077 | 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 | 8096 | return ImplicitCastMatchResultYes; |
| 8081 | 8097 | } |
| ... | ... | @@ -8087,16 +8103,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 8087 | 8103 | if (actual_type->id == TypeTableEntryIdComptimeFloat || |
| 8088 | 8104 | actual_type->id == TypeTableEntryIdComptimeInt) |
| 8089 | 8105 | { |
| 8090 | | if (expected_type->id == TypeTableEntryIdPointer && |
| 8091 | | expected_type->data.pointer.ptr_len == PtrLenSingle && |
| 8092 | | expected_type->data.pointer.is_const) |
| 8106 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 8107 | wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 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 | 8111 | return ImplicitCastMatchResultYes; |
| 8096 | 8112 | } else { |
| 8097 | 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 | 8116 | return ImplicitCastMatchResultYes; |
| 8101 | 8117 | } else { |
| 8102 | 8118 | return ImplicitCastMatchResultReportedError; |
| ... | ... | @@ -8106,41 +8122,41 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 8106 | 8122 | // implicit typed number to integer or float literal. |
| 8107 | 8123 | // works when the number is known |
| 8108 | 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 | 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 | 8128 | return ImplicitCastMatchResultYes; |
| 8113 | 8129 | } |
| 8114 | 8130 | } |
| 8115 | 8131 | |
| 8116 | 8132 | // 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 | 8134 | (actual_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 8119 | 8135 | actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) |
| 8120 | 8136 | { |
| 8121 | 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 | 8139 | return ImplicitCastMatchResultYes; |
| 8124 | 8140 | } |
| 8125 | 8141 | } |
| 8126 | 8142 | |
| 8127 | 8143 | // implicit enum to union which has the enum as the tag type |
| 8128 | | if (expected_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum && |
| 8129 | | (expected_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 8130 | | expected_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) |
| 8144 | if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum && |
| 8145 | (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 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); |
| 8133 | | if (expected_type->data.unionation.tag_type == actual_type) { |
| 8148 | type_ensure_zero_bits_known(ira->codegen, wanted_type); |
| 8149 | if (wanted_type->data.unionation.tag_type == actual_type) { |
| 8134 | 8150 | return ImplicitCastMatchResultYes; |
| 8135 | 8151 | } |
| 8136 | 8152 | } |
| 8137 | 8153 | |
| 8138 | 8154 | // implicit enum to &const union which has the enum as the tag type |
| 8139 | 8155 | if (actual_type->id == TypeTableEntryIdEnum && |
| 8140 | | expected_type->id == TypeTableEntryIdPointer && |
| 8141 | | expected_type->data.pointer.ptr_len == PtrLenSingle) |
| 8156 | wanted_type->id == TypeTableEntryIdPointer && |
| 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 | 8160 | if (union_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 8145 | 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 | 8168 | } |
| 8153 | 8169 | |
| 8154 | 8170 | // implicit T to *T where T is zero bits |
| 8155 | | if (expected_type->id == TypeTableEntryIdPointer && expected_type->data.pointer.ptr_len == PtrLenSingle && |
| 8156 | | types_match_const_cast_only(ira, expected_type->data.pointer.child_type, |
| 8157 | | actual_type, source_node).id == ConstCastResultIdOk) |
| 8171 | if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 8172 | types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, |
| 8173 | actual_type, source_node, false).id == ConstCastResultIdOk) |
| 8158 | 8174 | { |
| 8159 | 8175 | type_ensure_zero_bits_known(ira->codegen, actual_type); |
| 8160 | 8176 | if (!type_has_bits(actual_type)) { |
| ... | ... | @@ -8170,10 +8186,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 8170 | 8186 | // implicitly take a const pointer to something |
| 8171 | 8187 | if (!type_requires_comptime(actual_type)) { |
| 8172 | 8188 | TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); |
| 8173 | | if (expected_type->id == TypeTableEntryIdPointer && |
| 8174 | | expected_type->data.pointer.ptr_len == PtrLenSingle && |
| 8175 | | types_match_const_cast_only(ira, expected_type, const_ptr_actual, |
| 8176 | | source_node).id == ConstCastResultIdOk) |
| 8189 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 8190 | wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 8191 | types_match_const_cast_only(ira, wanted_type, const_ptr_actual, |
| 8192 | source_node, false).id == ConstCastResultIdOk) |
| 8177 | 8193 | { |
| 8178 | 8194 | return ImplicitCastMatchResultYes; |
| 8179 | 8195 | } |
| ... | ... | @@ -8415,9 +8431,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8415 | 8431 | TypeTableEntry *cur_payload_type = cur_type->data.error_union.payload_type; |
| 8416 | 8432 | |
| 8417 | 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 | 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; |
| 8421 | 8437 | |
| 8422 | 8438 | if (const_cast_prev || const_cast_cur) { |
| 8423 | 8439 | if (const_cast_cur) { |
| ... | ... | @@ -8504,11 +8520,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8504 | 8520 | continue; |
| 8505 | 8521 | } |
| 8506 | 8522 | |
| 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 | 8524 | continue; |
| 8509 | 8525 | } |
| 8510 | 8526 | |
| 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 | 8528 | prev_inst = cur_inst; |
| 8513 | 8529 | continue; |
| 8514 | 8530 | } |
| ... | ... | @@ -8531,13 +8547,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8531 | 8547 | } |
| 8532 | 8548 | |
| 8533 | 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 | 8553 | continue; |
| 8537 | 8554 | } |
| 8538 | 8555 | |
| 8539 | 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 | 8560 | if (err_set_type != nullptr) { |
| 8543 | 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 | 8577 | } |
| 8560 | 8578 | |
| 8561 | 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 | 8583 | continue; |
| 8565 | 8584 | } |
| 8566 | 8585 | |
| 8567 | 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 | 8590 | prev_inst = cur_inst; |
| 8571 | 8591 | continue; |
| ... | ... | @@ -8602,8 +8622,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8602 | 8622 | } |
| 8603 | 8623 | |
| 8604 | 8624 | if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 8605 | | 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) |
| 8625 | cur_type->data.array.len != prev_type->data.array.len && |
| 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 | 8629 | convert_to_const_slice = true; |
| 8609 | 8630 | prev_inst = cur_inst; |
| ... | ... | @@ -8611,8 +8632,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8611 | 8632 | } |
| 8612 | 8633 | |
| 8613 | 8634 | if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 8614 | | 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) |
| 8635 | cur_type->data.array.len != prev_type->data.array.len && |
| 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 | 8639 | convert_to_const_slice = true; |
| 8618 | 8640 | continue; |
| ... | ... | @@ -8621,8 +8643,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8621 | 8643 | if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) && |
| 8622 | 8644 | (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || |
| 8623 | 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, |
| 8625 | | cur_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| 8646 | types_match_const_cast_only(ira, |
| 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 | 8650 | convert_to_const_slice = false; |
| 8628 | 8651 | continue; |
| ... | ... | @@ -8631,8 +8654,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 8631 | 8654 | if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) && |
| 8632 | 8655 | (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || |
| 8633 | 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, |
| 8635 | | prev_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| 8657 | types_match_const_cast_only(ira, |
| 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 | 8661 | prev_inst = cur_inst; |
| 8638 | 8662 | convert_to_const_slice = false; |
| ... | ... | @@ -9913,7 +9937,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 9913 | 9937 | } |
| 9914 | 9938 | |
| 9915 | 9939 | // 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 | 9941 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 9918 | 9942 | } |
| 9919 | 9943 | |
| ... | ... | @@ -9959,7 +9983,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 9959 | 9983 | TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| 9960 | 9984 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 9961 | 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 | 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 | 10002 | TypeTableEntry *array_type = actual_type->data.pointer.child_type; |
| 9978 | 10003 | |
| 9979 | 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 | 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 | 10019 | wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry; |
| 9994 | 10020 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 9995 | 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 | 10025 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value); |
| 9999 | 10026 | if (type_is_invalid(cast1->value.type)) |
| ... | ... | @@ -10016,7 +10043,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10016 | 10043 | wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; |
| 10017 | 10044 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 10018 | 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 | 10049 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); |
| 10022 | 10050 | if (type_is_invalid(cast1->value.type)) |
| ... | ... | @@ -10084,7 +10112,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10084 | 10112 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray && |
| 10085 | 10113 | actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment && |
| 10086 | 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 | 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 | 10127 | TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| 10099 | 10128 | assert(slice_ptr_type->id == TypeTableEntryIdPointer); |
| 10100 | 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 | 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 | 10139 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism |
| 10110 | 10140 | if (wanted_type->id == TypeTableEntryIdOptional) { |
| 10111 | 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 | 10145 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| 10114 | 10146 | } else if (actual_type->id == TypeTableEntryIdComptimeInt || |
| 10115 | 10147 | actual_type->id == TypeTableEntryIdComptimeFloat) |
| ... | ... | @@ -10144,7 +10176,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10144 | 10176 | |
| 10145 | 10177 | // explicit cast from child type of error type to error type |
| 10146 | 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 | 10182 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| 10149 | 10183 | } else if (actual_type->id == TypeTableEntryIdComptimeInt || |
| 10150 | 10184 | actual_type->id == TypeTableEntryIdComptimeFloat) |
| ... | ... | @@ -10166,7 +10200,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10166 | 10200 | wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; |
| 10167 | 10201 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 10168 | 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 | 10206 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| 10172 | 10207 | if (type_is_invalid(cast1->value.type)) |
| ... | ... | @@ -10193,7 +10228,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10193 | 10228 | actual_type->id != TypeTableEntryIdOptional) |
| 10194 | 10229 | { |
| 10195 | 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 | 10232 | actual_type->id == TypeTableEntryIdNull || |
| 10198 | 10233 | actual_type->id == TypeTableEntryIdComptimeInt || |
| 10199 | 10234 | actual_type->id == TypeTableEntryIdComptimeFloat) |
| ... | ... | @@ -10345,7 +10380,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10345 | 10380 | TypeTableEntry *array_type = wanted_type->data.pointer.child_type; |
| 10346 | 10381 | if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 && |
| 10347 | 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 | 10386 | if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) { |
| 10351 | 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 | 10400 | // explicit cast from T to *T where T is zero bits |
| 10365 | 10401 | if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 10366 | 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 | 10405 | type_ensure_zero_bits_known(ira->codegen, actual_type); |
| 10370 | 10406 | if (type_is_invalid(actual_type)) { |
| ... | ... | @@ -10384,7 +10420,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10384 | 10420 | // explicit cast from something to const pointer of it |
| 10385 | 10421 | if (!type_requires_comptime(actual_type)) { |
| 10386 | 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 | 10424 | return ir_analyze_cast_ref(ira, source_instr, value, wanted_type); |
| 10389 | 10425 | } |
| 10390 | 10426 | } |