Skip to content

Commit 8dd2479

Browse files
committedJun 13, 2018
disallow implicit casts that break rules for optionals
closes #1102
·
0.15.20.3.0
1 parent 86adc1e commit 8dd2479

File tree

2 files changed

+197
-148
lines changed

2 files changed

+197
-148
lines changed
 

‎src/ir.cpp‎

Lines changed: 184 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -7647,23 +7647,24 @@ static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry
76477647
}
76487648

76497649

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)
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,69 +7791,73 @@ 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);
78227828
*result.data.return_type = child;
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);
78327840
*result.data.async_allocator_type = child;
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

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,
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,17 +8622,19 @@ 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;
86108631
continue;
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‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
const tests = @import("tests.zig");
22

33
pub 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 {

0 commit comments

Comments
 (0)
Please sign in to comment.