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
76477647}
76487648
76497649
7650static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *expected_type,
7651 TypeTableEntry *actual_type, AstNode *source_node)
7650static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry *wanted_type,
7651 TypeTableEntry *actual_type, AstNode *source_node, bool wanted_is_mutable)
76527652{
76537653 CodeGen *g = ira->codegen;
76547654 ConstCastOnly result = {};
76557655 result.id = ConstCastResultIdOk;
76567656
7657 if (expected_type == actual_type)
7657 if (wanted_type == actual_type)
76587658 return result;
76597659
76607660 // * 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 &&
76637664 actual_type->id == TypeTableEntryIdPointer)
76647665 {
76657666 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);
76677668 if (child.id != ConstCastResultIdOk) {
76687669 result.id = ConstCastResultIdNullWrapPtr;
76697670 result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1);
......@@ -7673,16 +7674,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
76737674 }
76747675
76757676 // pointer const
7676 if (expected_type->id == TypeTableEntryIdPointer &&
7677 if (wanted_type->id == TypeTableEntryIdPointer &&
76777678 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)
76847685 {
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);
76867688 if (child.id != ConstCastResultIdOk) {
76877689 result.id = ConstCastResultIdPointerChild;
76887690 result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1);
......@@ -7692,17 +7694,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
76927694 }
76937695
76947696 // slice const
7695 if (is_slice(expected_type) && is_slice(actual_type)) {
7697 if (is_slice(wanted_type) && is_slice(actual_type)) {
76967698 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)
77037705 {
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);
77067708 if (child.id != ConstCastResultIdOk) {
77077709 result.id = ConstCastResultIdSliceChild;
77087710 result.data.slice_child = allocate_nonzero<ConstCastOnly>(1);
......@@ -7713,8 +7715,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
77137715 }
77147716
77157717 // 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);
77187721 if (child.id != ConstCastResultIdOk) {
77197722 result.id = ConstCastResultIdOptionalChild;
77207723 result.data.optional_child = allocate_nonzero<ConstCastOnly>(1);
......@@ -7724,15 +7727,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
77247727 }
77257728
77267729 // 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);
77297733 if (payload_child.id != ConstCastResultIdOk) {
77307734 result.id = ConstCastResultIdErrorUnionPayload;
77317735 result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1);
77327736 *result.data.error_union_payload = payload_child;
77337737 return result;
77347738 }
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);
77367741 if (error_set_child.id != ConstCastResultIdOk) {
77377742 result.id = ConstCastResultIdErrorUnionErrorSet;
77387743 result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1);
......@@ -7743,9 +7748,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
77437748 }
77447749
77457750 // error set
7746 if (expected_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) {
7751 if (wanted_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) {
77477752 TypeTableEntry *contained_set = actual_type;
7748 TypeTableEntry *container_set = expected_type;
7753 TypeTableEntry *container_set = wanted_type;
77497754
77507755 // if the container set is inferred, then this will always work.
77517756 if (container_set->data.error_set.infer_fn != nullptr) {
......@@ -7786,36 +7791,37 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
77867791 return result;
77877792 }
77887793
7789 if (expected_type == ira->codegen->builtin_types.entry_promise &&
7794 if (wanted_type == ira->codegen->builtin_types.entry_promise &&
77907795 actual_type->id == TypeTableEntryIdPromise)
77917796 {
77927797 return result;
77937798 }
77947799
77957800 // fn
7796 if (expected_type->id == TypeTableEntryIdFn &&
7801 if (wanted_type->id == TypeTableEntryIdFn &&
77977802 actual_type->id == TypeTableEntryIdFn)
77987803 {
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) {
78007805 result.id = ConstCastResultIdFnAlign;
78017806 return result;
78027807 }
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) {
78047809 result.id = ConstCastResultIdFnCC;
78057810 return result;
78067811 }
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) {
78087813 result.id = ConstCastResultIdFnVarArgs;
78097814 return result;
78107815 }
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) {
78127817 result.id = ConstCastResultIdFnIsGeneric;
78137818 return result;
78147819 }
7815 if (!expected_type->data.fn.is_generic &&
7820 if (!wanted_type->data.fn.is_generic &&
78167821 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable)
78177822 {
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);
78197825 if (child.id != ConstCastResultIdOk) {
78207826 result.id = ConstCastResultIdFnReturnType;
78217827 result.data.return_type = allocate_nonzero<ConstCastOnly>(1);
......@@ -7823,9 +7829,11 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
78237829 return result;
78247830 }
78257831 }
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);
78297837 if (child.id != ConstCastResultIdOk) {
78307838 result.id = ConstCastResultIdAsyncAllocatorType;
78317839 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1);
......@@ -7833,22 +7841,23 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
78337841 return result;
78347842 }
78357843 }
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) {
78377845 result.id = ConstCastResultIdFnArgCount;
78387846 return result;
78397847 }
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) {
78417849 result.id = ConstCastResultIdFnGenericArgCount;
78427850 return result;
78437851 }
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) {
78477855 // note it's reversed for parameters
78487856 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);
78527861 if (arg_child.id != ConstCastResultIdOk) {
78537862 result.id = ConstCastResultIdFnArg;
78547863 result.data.fn_arg.arg_index = i;
......@@ -7876,11 +7885,12 @@ enum ImplicitCastMatchResult {
78767885 ImplicitCastMatchResultReportedError,
78777886};
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,
78807889 TypeTableEntry *actual_type, IrInstruction *value)
78817890{
78827891 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);
78847894 if (const_cast_result.id == ConstCastResultIdOk) {
78857895 return ImplicitCastMatchResultYes;
78867896 }
......@@ -7895,21 +7905,21 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
78957905 missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors;
78967906 } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) {
78977907 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)));
78997909 add_error_note(ira->codegen, msg, value->source_node,
79007910 buf_sprintf("unable to cast global error set into smaller set"));
79017911 return ImplicitCastMatchResultReportedError;
79027912 }
79037913 } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) {
79047914 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)));
79067916 add_error_note(ira->codegen, msg, value->source_node,
79077917 buf_sprintf("unable to cast global error set into smaller set"));
79087918 return ImplicitCastMatchResultReportedError;
79097919 }
79107920 if (missing_errors != nullptr) {
79117921 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)));
79137923 for (size_t i = 0; i < missing_errors->length; i += 1) {
79147924 ErrorTableEntry *error_entry = missing_errors->at(i);
79157925 add_error_note(ira->codegen, msg, error_entry->decl_node,
......@@ -7920,162 +7930,168 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
79207930 }
79217931
79227932 // 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,
79257935 actual_type->data.maybe.child_type, value);
79267936 if (res != ImplicitCastMatchResultNo)
79277937 return res;
79287938 }
79297939
79307940 // 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,
79337943 actual_type, value);
79347944 if (res != ImplicitCastMatchResultNo)
79357945 return res;
79367946 }
79377947
79387948 // implicit conversion from null literal to maybe type
7939 if (expected_type->id == TypeTableEntryIdOptional &&
7949 if (wanted_type->id == TypeTableEntryIdOptional &&
79407950 actual_type->id == TypeTableEntryIdNull)
79417951 {
79427952 return ImplicitCastMatchResultYes;
79437953 }
79447954
79457955 // 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))
79487958 {
79497959 return ImplicitCastMatchResultYes;
79507960 }
79517961
79527962 // implicit conversion from error set to error union type
7953 if (expected_type->id == TypeTableEntryIdErrorUnion &&
7963 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
79547964 actual_type->id == TypeTableEntryIdErrorSet)
79557965 {
79567966 return ImplicitCastMatchResultYes;
79577967 }
79587968
79597969 // 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 &&
79627972 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,
79647974 actual_type, value))
79657975 {
79667976 return ImplicitCastMatchResultYes;
79677977 }
79687978
79697979 // implicit widening conversion
7970 if (expected_type->id == TypeTableEntryIdInt &&
7980 if (wanted_type->id == TypeTableEntryIdInt &&
79717981 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)
79747984 {
79757985 return ImplicitCastMatchResultYes;
79767986 }
79777987
79787988 // 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 &&
79807990 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)
79827992 {
79837993 return ImplicitCastMatchResultYes;
79847994 }
79857995
79867996 // implicit float widening conversion
7987 if (expected_type->id == TypeTableEntryIdFloat &&
7997 if (wanted_type->id == TypeTableEntryIdFloat &&
79887998 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)
79908000 {
79918001 return ImplicitCastMatchResultYes;
79928002 }
79938003
79948004 // 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;
79978007 assert(ptr_type->id == TypeTableEntryIdPointer);
79988008
79998009 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)
80018012 {
80028013 return ImplicitCastMatchResultYes;
80038014 }
80048015 }
80058016
80068017 // implicit &const [N]T to []const T
8007 if (is_slice(expected_type) &&
8018 if (is_slice(wanted_type) &&
80088019 actual_type->id == TypeTableEntryIdPointer &&
80098020 actual_type->data.pointer.ptr_len == PtrLenSingle &&
80108021 actual_type->data.pointer.is_const &&
80118022 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
80128023 {
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;
80148025 assert(ptr_type->id == TypeTableEntryIdPointer);
80158026
80168027 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
80178028
80188029 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)
80208032 {
80218033 return ImplicitCastMatchResultYes;
80228034 }
80238035 }
80248036
80258037 // 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) &&
80308042 actual_type->id == TypeTableEntryIdArray)
80318043 {
80328044 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;
80348046 assert(ptr_type->id == TypeTableEntryIdPointer);
80358047 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)
80378050 {
80388051 return ImplicitCastMatchResultYes;
80398052 }
80408053 }
80418054
80428055 // 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 &&
80458058 actual_type->id == TypeTableEntryIdPointer &&
80468059 actual_type->data.pointer.ptr_len == PtrLenSingle &&
80478060 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)
80508064 {
80518065 return ImplicitCastMatchResultYes;
80528066 }
80538067
80548068 // implicit *[N]T to []T
8055 if (is_slice(expected_type) &&
8069 if (is_slice(wanted_type) &&
80568070 actual_type->id == TypeTableEntryIdPointer &&
80578071 actual_type->data.pointer.ptr_len == PtrLenSingle &&
80588072 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
80598073 {
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;
80618075 assert(slice_ptr_type->id == TypeTableEntryIdPointer);
80628076 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)
80648079 {
80658080 return ImplicitCastMatchResultYes;
80668081 }
80678082 }
80688083
80698084 // 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) &&
80728087 actual_type->id == TypeTableEntryIdArray)
80738088 {
80748089 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;
80768091 assert(ptr_type->id == TypeTableEntryIdPointer);
80778092 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)
80798095 {
80808096 return ImplicitCastMatchResultYes;
80818097 }
......@@ -8087,16 +8103,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
80878103 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
80888104 actual_type->id == TypeTableEntryIdComptimeInt)
80898105 {
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)
80938109 {
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)) {
80958111 return ImplicitCastMatchResultYes;
80968112 } else {
80978113 return ImplicitCastMatchResultReportedError;
80988114 }
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)) {
81008116 return ImplicitCastMatchResultYes;
81018117 } else {
81028118 return ImplicitCastMatchResultReportedError;
......@@ -8106,41 +8122,41 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
81068122 // implicit typed number to integer or float literal.
81078123 // works when the number is known
81088124 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) {
81108126 return ImplicitCastMatchResultYes;
8111 } else if (actual_type->id == TypeTableEntryIdFloat && expected_type->id == TypeTableEntryIdComptimeFloat) {
8127 } else if (actual_type->id == TypeTableEntryIdFloat && wanted_type->id == TypeTableEntryIdComptimeFloat) {
81128128 return ImplicitCastMatchResultYes;
81138129 }
81148130 }
81158131
81168132 // 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 &&
81188134 (actual_type->data.unionation.decl_node->data.container_decl.auto_enum ||
81198135 actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
81208136 {
81218137 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) {
81238139 return ImplicitCastMatchResultYes;
81248140 }
81258141 }
81268142
81278143 // 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))
81318147 {
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) {
81348150 return ImplicitCastMatchResultYes;
81358151 }
81368152 }
81378153
81388154 // implicit enum to &const union which has the enum as the tag type
81398155 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)
81428158 {
8143 TypeTableEntry *union_type = expected_type->data.pointer.child_type;
8159 TypeTableEntry *union_type = wanted_type->data.pointer.child_type;
81448160 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
81458161 union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
81468162 {
......@@ -8152,9 +8168,9 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
81528168 }
81538169
81548170 // 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)
81588174 {
81598175 type_ensure_zero_bits_known(ira->codegen, actual_type);
81608176 if (!type_has_bits(actual_type)) {
......@@ -8170,10 +8186,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
81708186 // implicitly take a const pointer to something
81718187 if (!type_requires_comptime(actual_type)) {
81728188 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)
81778193 {
81788194 return ImplicitCastMatchResultYes;
81798195 }
......@@ -8415,9 +8431,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
84158431 TypeTableEntry *cur_payload_type = cur_type->data.error_union.payload_type;
84168432
84178433 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;
84198435 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
84228438 if (const_cast_prev || const_cast_cur) {
84238439 if (const_cast_cur) {
......@@ -8504,11 +8520,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
85048520 continue;
85058521 }
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) {
85088524 continue;
85098525 }
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) {
85128528 prev_inst = cur_inst;
85138529 continue;
85148530 }
......@@ -8531,13 +8547,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
85318547 }
85328548
85338549 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)
85358552 {
85368553 continue;
85378554 }
85388555
85398556 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)
85418559 {
85428560 if (err_set_type != nullptr) {
85438561 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
85598577 }
85608578
85618579 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)
85638582 {
85648583 continue;
85658584 }
85668585
85678586 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)
85698589 {
85708590 prev_inst = cur_inst;
85718591 continue;
......@@ -8602,8 +8622,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86028622 }
86038623
86048624 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)
86078628 {
86088629 convert_to_const_slice = true;
86098630 prev_inst = cur_inst;
......@@ -8611,8 +8632,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86118632 }
86128633
86138634 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)
86168638 {
86178639 convert_to_const_slice = true;
86188640 continue;
......@@ -8621,8 +8643,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86218643 if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
86228644 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
86238645 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)
86268649 {
86278650 convert_to_const_slice = false;
86288651 continue;
......@@ -8631,8 +8654,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86318654 if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
86328655 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
86338656 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)
86368660 {
86378661 prev_inst = cur_inst;
86388662 convert_to_const_slice = false;
......@@ -9913,7 +9937,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
99139937 }
99149938
99159939 // 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) {
99179941 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
99189942 }
99199943
......@@ -9959,7 +9983,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
99599983 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
99609984 assert(ptr_type->id == TypeTableEntryIdPointer);
99619985 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)
99639988 {
99649989 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
99659990 }
......@@ -9977,7 +10002,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
997710002 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
997810003
997910004 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)
998110007 {
998210008 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
998310009 }
......@@ -9993,7 +10019,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
999310019 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
999410020 assert(ptr_type->id == TypeTableEntryIdPointer);
999510021 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)
999710024 {
999810025 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
999910026 if (type_is_invalid(cast1->value.type))
......@@ -10016,7 +10043,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1001610043 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
1001710044 assert(ptr_type->id == TypeTableEntryIdPointer);
1001810045 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)
1002010048 {
1002110049 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
1002210050 if (type_is_invalid(cast1->value.type))
......@@ -10084,7 +10112,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1008410112 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&
1008510113 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment &&
1008610114 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)
1008810117 {
1008910118 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
1009010119 }
......@@ -10098,7 +10127,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1009810127 TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
1009910128 assert(slice_ptr_type->id == TypeTableEntryIdPointer);
1010010129 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)
1010210132 {
1010310133 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);
1010410134 }
......@@ -10109,7 +10139,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1010910139 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism
1011010140 if (wanted_type->id == TypeTableEntryIdOptional) {
1011110141 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 {
1011310145 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
1011410146 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
1011510147 actual_type->id == TypeTableEntryIdComptimeFloat)
......@@ -10144,7 +10176,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1014410176
1014510177 // explicit cast from child type of error type to error type
1014610178 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 {
1014810182 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
1014910183 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
1015010184 actual_type->id == TypeTableEntryIdComptimeFloat)
......@@ -10166,7 +10200,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1016610200 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
1016710201 assert(ptr_type->id == TypeTableEntryIdPointer);
1016810202 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)
1017010205 {
1017110206 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
1017210207 if (type_is_invalid(cast1->value.type))
......@@ -10193,7 +10228,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1019310228 actual_type->id != TypeTableEntryIdOptional)
1019410229 {
1019510230 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 ||
1019710232 actual_type->id == TypeTableEntryIdNull ||
1019810233 actual_type->id == TypeTableEntryIdComptimeInt ||
1019910234 actual_type->id == TypeTableEntryIdComptimeFloat)
......@@ -10345,7 +10380,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1034510380 TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
1034610381 if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 &&
1034710382 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)
1034910385 {
1035010386 if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {
1035110387 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
1036410400 // explicit cast from T to *T where T is zero bits
1036510401 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
1036610402 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)
1036810404 {
1036910405 type_ensure_zero_bits_known(ira->codegen, actual_type);
1037010406 if (type_is_invalid(actual_type)) {
......@@ -10384,7 +10420,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1038410420 // explicit cast from something to const pointer of it
1038510421 if (!type_requires_comptime(actual_type)) {
1038610422 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) {
1038810424 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
1038910425 }
1039010426 }
test/compile_errors.zig+13
......@@ -1,6 +1,19 @@
11const tests = @import("tests.zig");
22
33pub 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
417 cases.add(
518 "attempted implicit cast from T to [*]const T",
619 \\export fn entry() void {