authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-19 18:51:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-19 18:51:46-04:00
log42db807f375d0c8fe248eebcb4eaeed71b43075d
tree2be4e6545f55e9c68abcd434249c64125c3c8a5e
parentee525c92a4c3bafa8f30c46e0303e0bca8f81860

remove redundant implicit casting code

and introduce better type mismatch errors closes #1061

2 files changed, 189 insertions(+), 394 deletions(-)

src/ir.cpp+178-386
...@@ -65,12 +65,7 @@ enum ConstCastResultId {...@@ -65,12 +65,7 @@ enum ConstCastResultId {
65 ConstCastResultIdNullWrapPtr,65 ConstCastResultIdNullWrapPtr,
66};66};
6767
68struct ConstCastErrSetMismatch {
69 ZigList<ErrorTableEntry *> missing_errors;
70};
71
72struct ConstCastOnly;68struct ConstCastOnly;
73
74struct ConstCastArg {69struct ConstCastArg {
75 size_t arg_index;70 size_t arg_index;
76 ConstCastOnly *child;71 ConstCastOnly *child;
...@@ -80,15 +75,22 @@ struct ConstCastArgNoAlias {...@@ -80,15 +75,22 @@ struct ConstCastArgNoAlias {
80 size_t arg_index;75 size_t arg_index;
81};76};
8277
78struct ConstCastOptionalMismatch;
79struct ConstCastPointerMismatch;
80struct ConstCastSliceMismatch;
81struct ConstCastErrUnionErrSetMismatch;
82struct ConstCastErrUnionPayloadMismatch;
83struct ConstCastErrSetMismatch;
84
83struct ConstCastOnly {85struct ConstCastOnly {
84 ConstCastResultId id;86 ConstCastResultId id;
85 union {87 union {
86 ConstCastErrSetMismatch error_set;88 ConstCastErrSetMismatch *error_set_mismatch;
87 ConstCastOnly *pointer_child;89 ConstCastPointerMismatch *pointer_mismatch;
88 ConstCastOnly *slice_child;90 ConstCastSliceMismatch *slice_mismatch;
89 ConstCastOnly *optional_child;91 ConstCastOptionalMismatch *optional;
90 ConstCastOnly *error_union_payload;92 ConstCastErrUnionPayloadMismatch *error_union_payload;
91 ConstCastOnly *error_union_error_set;93 ConstCastErrUnionErrSetMismatch *error_union_error_set;
92 ConstCastOnly *return_type;94 ConstCastOnly *return_type;
93 ConstCastOnly *async_allocator_type;95 ConstCastOnly *async_allocator_type;
94 ConstCastOnly *null_wrap_ptr_child;96 ConstCastOnly *null_wrap_ptr_child;
...@@ -97,6 +99,39 @@ struct ConstCastOnly {...@@ -97,6 +99,39 @@ struct ConstCastOnly {
97 } data;99 } data;
98};100};
99101
102struct ConstCastOptionalMismatch {
103 ConstCastOnly child;
104 TypeTableEntry *wanted_child;
105 TypeTableEntry *actual_child;
106};
107
108struct ConstCastPointerMismatch {
109 ConstCastOnly child;
110 TypeTableEntry *wanted_child;
111 TypeTableEntry *actual_child;
112};
113
114struct ConstCastSliceMismatch {
115 ConstCastOnly child;
116 TypeTableEntry *wanted_child;
117 TypeTableEntry *actual_child;
118};
119
120struct ConstCastErrUnionErrSetMismatch {
121 ConstCastOnly child;
122 TypeTableEntry *wanted_err_set;
123 TypeTableEntry *actual_err_set;
124};
125
126struct ConstCastErrUnionPayloadMismatch {
127 ConstCastOnly child;
128 TypeTableEntry *wanted_payload;
129 TypeTableEntry *actual_payload;
130};
131
132struct ConstCastErrSetMismatch {
133 ZigList<ErrorTableEntry *> missing_errors;
134};
100135
101static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);136static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
102static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);137static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);
...@@ -7972,8 +8007,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7972,8 +8007,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7972 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);8007 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
7973 if (child.id != ConstCastResultIdOk) {8008 if (child.id != ConstCastResultIdOk) {
7974 result.id = ConstCastResultIdPointerChild;8009 result.id = ConstCastResultIdPointerChild;
7975 result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1);8010 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1);
7976 *result.data.pointer_child = child;8011 result.data.pointer_mismatch->child = child;
8012 result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type;
8013 result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
7977 }8014 }
7978 return result;8015 return result;
7979 }8016 }
...@@ -7992,8 +8029,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -7992,8 +8029,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
7992 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);8029 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
7993 if (child.id != ConstCastResultIdOk) {8030 if (child.id != ConstCastResultIdOk) {
7994 result.id = ConstCastResultIdSliceChild;8031 result.id = ConstCastResultIdSliceChild;
7995 result.data.slice_child = allocate_nonzero<ConstCastOnly>(1);8032 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1);
7996 *result.data.slice_child = child;8033 result.data.slice_mismatch->child = child;
8034 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
8035 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type;
7997 }8036 }
7998 return result;8037 return result;
7999 }8038 }
...@@ -8005,8 +8044,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8005,8 +8044,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8005 actual_type->data.maybe.child_type, source_node, wanted_is_mutable);8044 actual_type->data.maybe.child_type, source_node, wanted_is_mutable);
8006 if (child.id != ConstCastResultIdOk) {8045 if (child.id != ConstCastResultIdOk) {
8007 result.id = ConstCastResultIdOptionalChild;8046 result.id = ConstCastResultIdOptionalChild;
8008 result.data.optional_child = allocate_nonzero<ConstCastOnly>(1);8047 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1);
8009 *result.data.optional_child = child;8048 result.data.optional->child = child;
8049 result.data.optional->wanted_child = wanted_type->data.maybe.child_type;
8050 result.data.optional->actual_child = actual_type->data.maybe.child_type;
8010 }8051 }
8011 return result;8052 return result;
8012 }8053 }
...@@ -8017,16 +8058,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8017,16 +8058,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8017 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable);8058 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable);
8018 if (payload_child.id != ConstCastResultIdOk) {8059 if (payload_child.id != ConstCastResultIdOk) {
8019 result.id = ConstCastResultIdErrorUnionPayload;8060 result.id = ConstCastResultIdErrorUnionPayload;
8020 result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1);8061 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1);
8021 *result.data.error_union_payload = payload_child;8062 result.data.error_union_payload->child = payload_child;
8063 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type;
8064 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type;
8022 return result;8065 return result;
8023 }8066 }
8024 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type,8067 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type,
8025 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable);8068 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable);
8026 if (error_set_child.id != ConstCastResultIdOk) {8069 if (error_set_child.id != ConstCastResultIdOk) {
8027 result.id = ConstCastResultIdErrorUnionErrorSet;8070 result.id = ConstCastResultIdErrorUnionErrorSet;
8028 result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1);8071 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1);
8029 *result.data.error_union_error_set = error_set_child;8072 result.data.error_union_error_set->child = error_set_child;
8073 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type;
8074 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type;
8030 return result;8075 return result;
8031 }8076 }
8032 return result;8077 return result;
...@@ -8068,8 +8113,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8068,8 +8113,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8068 if (error_entry == nullptr) {8113 if (error_entry == nullptr) {
8069 if (result.id == ConstCastResultIdOk) {8114 if (result.id == ConstCastResultIdOk) {
8070 result.id = ConstCastResultIdErrSet;8115 result.id = ConstCastResultIdErrSet;
8116 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1);
8071 }8117 }
8072 result.data.error_set.missing_errors.append(contained_error_entry);8118 result.data.error_set_mismatch->missing_errors.append(contained_error_entry);
8073 }8119 }
8074 }8120 }
8075 free(errors);8121 free(errors);
...@@ -8164,325 +8210,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8164,325 +8210,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8164 return result;8210 return result;
8165}8211}
81668212
8167enum ImplicitCastMatchResult {
8168 ImplicitCastMatchResultNo,
8169 ImplicitCastMatchResultYes,
8170 ImplicitCastMatchResultReportedError,
8171};
8172
8173static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *wanted_type,
8174 TypeTableEntry *actual_type, IrInstruction *value)
8175{
8176 AstNode *source_node = value->source_node;
8177 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
8178 source_node, false);
8179 if (const_cast_result.id == ConstCastResultIdOk) {
8180 return ImplicitCastMatchResultYes;
8181 }
8182
8183 // if we got here with error sets, make an error showing the incompatibilities
8184 ZigList<ErrorTableEntry *> *missing_errors = nullptr;
8185 if (const_cast_result.id == ConstCastResultIdErrSet) {
8186 missing_errors = &const_cast_result.data.error_set.missing_errors;
8187 }
8188 if (const_cast_result.id == ConstCastResultIdErrorUnionErrorSet) {
8189 if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSet) {
8190 missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors;
8191 } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) {
8192 ErrorMsg *msg = ir_add_error(ira, value,
8193 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
8194 add_error_note(ira->codegen, msg, value->source_node,
8195 buf_sprintf("unable to cast global error set into smaller set"));
8196 return ImplicitCastMatchResultReportedError;
8197 }
8198 } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) {
8199 ErrorMsg *msg = ir_add_error(ira, value,
8200 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
8201 add_error_note(ira->codegen, msg, value->source_node,
8202 buf_sprintf("unable to cast global error set into smaller set"));
8203 return ImplicitCastMatchResultReportedError;
8204 }
8205 if (missing_errors != nullptr) {
8206 ErrorMsg *msg = ir_add_error(ira, value,
8207 buf_sprintf("expected '%s', found '%s'", buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name)));
8208 for (size_t i = 0; i < missing_errors->length; i += 1) {
8209 ErrorTableEntry *error_entry = missing_errors->at(i);
8210 add_error_note(ira->codegen, msg, error_entry->decl_node,
8211 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name)));
8212 }
8213
8214 return ImplicitCastMatchResultReportedError;
8215 }
8216
8217 // implicit conversion from ?T to ?U
8218 if (wanted_type->id == TypeTableEntryIdOptional && actual_type->id == TypeTableEntryIdOptional) {
8219 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type,
8220 actual_type->data.maybe.child_type, value);
8221 if (res != ImplicitCastMatchResultNo)
8222 return res;
8223 }
8224
8225 // implicit conversion from non maybe type to maybe type
8226 if (wanted_type->id == TypeTableEntryIdOptional) {
8227 ImplicitCastMatchResult res = ir_types_match_with_implicit_cast(ira, wanted_type->data.maybe.child_type,
8228 actual_type, value);
8229 if (res != ImplicitCastMatchResultNo)
8230 return res;
8231 }
8232
8233 // implicit conversion from null literal to maybe type
8234 if (wanted_type->id == TypeTableEntryIdOptional &&
8235 actual_type->id == TypeTableEntryIdNull)
8236 {
8237 return ImplicitCastMatchResultYes;
8238 }
8239
8240 // implicit T to U!T
8241 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
8242 ir_types_match_with_implicit_cast(ira, wanted_type->data.error_union.payload_type, actual_type, value))
8243 {
8244 return ImplicitCastMatchResultYes;
8245 }
8246
8247 // implicit conversion from error set to error union type
8248 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
8249 actual_type->id == TypeTableEntryIdErrorSet)
8250 {
8251 return ImplicitCastMatchResultYes;
8252 }
8253
8254 // implicit conversion from T to U!?T
8255 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
8256 wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional &&
8257 ir_types_match_with_implicit_cast(ira,
8258 wanted_type->data.error_union.payload_type->data.maybe.child_type,
8259 actual_type, value))
8260 {
8261 return ImplicitCastMatchResultYes;
8262 }
8263
8264 // implicit widening conversion
8265 if (wanted_type->id == TypeTableEntryIdInt &&
8266 actual_type->id == TypeTableEntryIdInt &&
8267 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
8268 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count)
8269 {
8270 return ImplicitCastMatchResultYes;
8271 }
8272
8273 // small enough unsigned ints can get casted to large enough signed ints
8274 if (wanted_type->id == TypeTableEntryIdInt && wanted_type->data.integral.is_signed &&
8275 actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed &&
8276 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count)
8277 {
8278 return ImplicitCastMatchResultYes;
8279 }
8280
8281 // implicit float widening conversion
8282 if (wanted_type->id == TypeTableEntryIdFloat &&
8283 actual_type->id == TypeTableEntryIdFloat &&
8284 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count)
8285 {
8286 return ImplicitCastMatchResultYes;
8287 }
8288
8289 // implicit [N]T to []const T
8290 if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) {
8291 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8292 assert(ptr_type->id == TypeTableEntryIdPointer);
8293
8294 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8295 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
8296 source_node, false).id == ConstCastResultIdOk)
8297 {
8298 return ImplicitCastMatchResultYes;
8299 }
8300 }
8301
8302 // implicit &const [N]T to []const T
8303 if (is_slice(wanted_type) &&
8304 actual_type->id == TypeTableEntryIdPointer &&
8305 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8306 actual_type->data.pointer.is_const &&
8307 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
8308 {
8309 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8310 assert(ptr_type->id == TypeTableEntryIdPointer);
8311
8312 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
8313
8314 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
8315 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type,
8316 source_node, false).id == ConstCastResultIdOk)
8317 {
8318 return ImplicitCastMatchResultYes;
8319 }
8320 }
8321
8322 // implicit [N]T to &const []const T
8323 if (wanted_type->id == TypeTableEntryIdPointer &&
8324 wanted_type->data.pointer.is_const &&
8325 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8326 is_slice(wanted_type->data.pointer.child_type) &&
8327 actual_type->id == TypeTableEntryIdArray)
8328 {
8329 TypeTableEntry *ptr_type =
8330 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
8331 assert(ptr_type->id == TypeTableEntryIdPointer);
8332 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8333 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type,
8334 actual_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8335 {
8336 return ImplicitCastMatchResultYes;
8337 }
8338 }
8339
8340 // implicit *[N]T to [*]T
8341 if (wanted_type->id == TypeTableEntryIdPointer &&
8342 wanted_type->data.pointer.ptr_len == PtrLenUnknown &&
8343 actual_type->id == TypeTableEntryIdPointer &&
8344 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8345 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray &&
8346 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
8347 actual_type->data.pointer.child_type->data.array.child_type, source_node,
8348 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
8349 {
8350 return ImplicitCastMatchResultYes;
8351 }
8352
8353 // implicit *[N]T to []T
8354 if (is_slice(wanted_type) &&
8355 actual_type->id == TypeTableEntryIdPointer &&
8356 actual_type->data.pointer.ptr_len == PtrLenSingle &&
8357 actual_type->data.pointer.child_type->id == TypeTableEntryIdArray)
8358 {
8359 TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8360 assert(slice_ptr_type->id == TypeTableEntryIdPointer);
8361 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
8362 actual_type->data.pointer.child_type->data.array.child_type, source_node,
8363 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
8364 {
8365 return ImplicitCastMatchResultYes;
8366 }
8367 }
8368
8369 // implicit [N]T to ?[]const T
8370 if (wanted_type->id == TypeTableEntryIdOptional &&
8371 is_slice(wanted_type->data.maybe.child_type) &&
8372 actual_type->id == TypeTableEntryIdArray)
8373 {
8374 TypeTableEntry *ptr_type =
8375 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
8376 assert(ptr_type->id == TypeTableEntryIdPointer);
8377 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8378 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type,
8379 actual_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
8380 {
8381 return ImplicitCastMatchResultYes;
8382 }
8383 }
8384
8385
8386 // implicit number literal to typed number
8387 // implicit number literal to &const integer
8388 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
8389 actual_type->id == TypeTableEntryIdComptimeInt)
8390 {
8391 if (wanted_type->id == TypeTableEntryIdPointer &&
8392 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8393 wanted_type->data.pointer.is_const)
8394 {
8395 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.pointer.child_type, false)) {
8396 return ImplicitCastMatchResultYes;
8397 } else {
8398 return ImplicitCastMatchResultReportedError;
8399 }
8400 } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, false)) {
8401 return ImplicitCastMatchResultYes;
8402 } else {
8403 return ImplicitCastMatchResultReportedError;
8404 }
8405 }
8406
8407 // implicit typed number to integer or float literal.
8408 // works when the number is known
8409 if (value->value.special == ConstValSpecialStatic) {
8410 if (actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) {
8411 return ImplicitCastMatchResultYes;
8412 } else if (actual_type->id == TypeTableEntryIdFloat && wanted_type->id == TypeTableEntryIdComptimeFloat) {
8413 return ImplicitCastMatchResultYes;
8414 }
8415 }
8416
8417 // implicit union to its enum tag type
8418 if (wanted_type->id == TypeTableEntryIdEnum && actual_type->id == TypeTableEntryIdUnion &&
8419 (actual_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8420 actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
8421 {
8422 type_ensure_zero_bits_known(ira->codegen, actual_type);
8423 if (actual_type->data.unionation.tag_type == wanted_type) {
8424 return ImplicitCastMatchResultYes;
8425 }
8426 }
8427
8428 // implicit enum to union which has the enum as the tag type
8429 if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum &&
8430 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8431 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
8432 {
8433 type_ensure_zero_bits_known(ira->codegen, wanted_type);
8434 if (wanted_type->data.unionation.tag_type == actual_type) {
8435 return ImplicitCastMatchResultYes;
8436 }
8437 }
8438
8439 // implicit enum to &const union which has the enum as the tag type
8440 if (actual_type->id == TypeTableEntryIdEnum &&
8441 wanted_type->id == TypeTableEntryIdPointer &&
8442 wanted_type->data.pointer.ptr_len == PtrLenSingle)
8443 {
8444 TypeTableEntry *union_type = wanted_type->data.pointer.child_type;
8445 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
8446 union_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)
8447 {
8448 type_ensure_zero_bits_known(ira->codegen, union_type);
8449 if (union_type->data.unionation.tag_type == actual_type) {
8450 return ImplicitCastMatchResultYes;
8451 }
8452 }
8453 }
8454
8455 // implicit T to *T where T is zero bits
8456 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8457 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
8458 actual_type, source_node, false).id == ConstCastResultIdOk)
8459 {
8460 type_ensure_zero_bits_known(ira->codegen, actual_type);
8461 if (!type_has_bits(actual_type)) {
8462 return ImplicitCastMatchResultYes;
8463 }
8464 }
8465
8466 // implicit undefined literal to anything
8467 if (actual_type->id == TypeTableEntryIdUndefined) {
8468 return ImplicitCastMatchResultYes;
8469 }
8470
8471 // implicitly take a const pointer to something
8472 if (!type_requires_comptime(actual_type)) {
8473 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
8474 if (wanted_type->id == TypeTableEntryIdPointer &&
8475 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8476 types_match_const_cast_only(ira, wanted_type, const_ptr_actual,
8477 source_node, false).id == ConstCastResultIdOk)
8478 {
8479 return ImplicitCastMatchResultYes;
8480 }
8481 }
8482
8483 return ImplicitCastMatchResultNo;
8484}
8485
8486static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) {8213static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) {
8487 size_t old_errors_count = *errors_count;8214 size_t old_errors_count = *errors_count;
8488 *errors_count = g->errors_by_index.length;8215 *errors_count = g->errors_by_index.length;
...@@ -10227,6 +9954,83 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou...@@ -10227,6 +9954,83 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
10227 return result;9954 return result;
10228}9955}
102299956
9957static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result,
9958 ErrorMsg *parent_msg)
9959{
9960 switch (cast_result->id) {
9961 case ConstCastResultIdOk:
9962 zig_unreachable();
9963 case ConstCastResultIdOptionalChild: {
9964 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
9965 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'",
9966 buf_ptr(&cast_result->data.optional->actual_child->name),
9967 buf_ptr(&cast_result->data.optional->wanted_child->name)));
9968 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg);
9969 break;
9970 }
9971 case ConstCastResultIdErrorUnionErrorSet: {
9972 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
9973 buf_sprintf("error set '%s' cannot cast into error set '%s'",
9974 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name),
9975 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name)));
9976 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg);
9977 break;
9978 }
9979 case ConstCastResultIdErrSet: {
9980 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors;
9981 for (size_t i = 0; i < missing_errors->length; i += 1) {
9982 ErrorTableEntry *error_entry = missing_errors->at(i);
9983 add_error_note(ira->codegen, parent_msg, error_entry->decl_node,
9984 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name)));
9985 }
9986 break;
9987 }
9988 case ConstCastResultIdErrSetGlobal: {
9989 add_error_note(ira->codegen, parent_msg, source_node,
9990 buf_sprintf("cannot cast global error set into smaller set"));
9991 break;
9992 }
9993 case ConstCastResultIdPointerChild: {
9994 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
9995 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'",
9996 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name),
9997 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name)));
9998 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg);
9999 break;
10000 }
10001 case ConstCastResultIdSliceChild: {
10002 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
10003 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'",
10004 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name),
10005 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name)));
10006 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg);
10007 break;
10008 }
10009 case ConstCastResultIdErrorUnionPayload: {
10010 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node,
10011 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'",
10012 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name),
10013 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name)));
10014 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg);
10015 break;
10016 }
10017 case ConstCastResultIdFnAlign: // TODO
10018 case ConstCastResultIdFnCC: // TODO
10019 case ConstCastResultIdFnVarArgs: // TODO
10020 case ConstCastResultIdFnIsGeneric: // TODO
10021 case ConstCastResultIdFnReturnType: // TODO
10022 case ConstCastResultIdFnArgCount: // TODO
10023 case ConstCastResultIdFnGenericArgCount: // TODO
10024 case ConstCastResultIdFnArg: // TODO
10025 case ConstCastResultIdFnArgNoAlias: // TODO
10026 case ConstCastResultIdType: // TODO
10027 case ConstCastResultIdUnresolvedInferredErrSet: // TODO
10028 case ConstCastResultIdAsyncAllocatorType: // TODO
10029 case ConstCastResultIdNullWrapPtr: // TODO
10030 break;
10031 }
10032}
10033
10230static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,10034static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
10231 TypeTableEntry *wanted_type, IrInstruction *value)10035 TypeTableEntry *wanted_type, IrInstruction *value)
10232{10036{
...@@ -10238,11 +10042,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10238,11 +10042,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10238 }10042 }
1023910043
10240 // perfect match or non-const to const10044 // perfect match or non-const to const
10241 if (types_match_const_cast_only(ira, wanted_type, actual_type, source_node, false).id == ConstCastResultIdOk) {10045 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
10046 source_node, false);
10047 if (const_cast_result.id == ConstCastResultIdOk) {
10242 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);10048 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
10243 }10049 }
1024410050
10245 // explicit widening conversion10051 // widening conversion
10246 if (wanted_type->id == TypeTableEntryIdInt &&10052 if (wanted_type->id == TypeTableEntryIdInt &&
10247 actual_type->id == TypeTableEntryIdInt &&10053 actual_type->id == TypeTableEntryIdInt &&
10248 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed &&10054 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
...@@ -10259,7 +10065,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10259,7 +10065,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10259 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);10065 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
10260 }10066 }
1026110067
10262 // explicit float widening conversion10068 // float widening conversion
10263 if (wanted_type->id == TypeTableEntryIdFloat &&10069 if (wanted_type->id == TypeTableEntryIdFloat &&
10264 actual_type->id == TypeTableEntryIdFloat &&10070 actual_type->id == TypeTableEntryIdFloat &&
10265 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count)10071 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count)
...@@ -10268,7 +10074,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10268,7 +10074,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10268 }10074 }
1026910075
1027010076
10271 // explicit cast from [N]T to []const T10077 // cast from [N]T to []const T
10272 if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) {10078 if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) {
10273 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;10079 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
10274 assert(ptr_type->id == TypeTableEntryIdPointer);10080 assert(ptr_type->id == TypeTableEntryIdPointer);
...@@ -10280,7 +10086,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10280,7 +10086,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10280 }10086 }
10281 }10087 }
1028210088
10283 // explicit cast from &const [N]T to []const T10089 // cast from &const [N]T to []const T
10284 if (is_slice(wanted_type) &&10090 if (is_slice(wanted_type) &&
10285 actual_type->id == TypeTableEntryIdPointer &&10091 actual_type->id == TypeTableEntryIdPointer &&
10286 actual_type->data.pointer.is_const &&10092 actual_type->data.pointer.is_const &&
...@@ -10299,7 +10105,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10299,7 +10105,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10299 }10105 }
10300 }10106 }
1030110107
10302 // explicit cast from [N]T to &const []const T10108 // cast from [N]T to &const []const T
10303 if (wanted_type->id == TypeTableEntryIdPointer &&10109 if (wanted_type->id == TypeTableEntryIdPointer &&
10304 wanted_type->data.pointer.is_const &&10110 wanted_type->data.pointer.is_const &&
10305 is_slice(wanted_type->data.pointer.child_type) &&10111 is_slice(wanted_type->data.pointer.child_type) &&
...@@ -10324,7 +10130,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10324,7 +10130,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10324 }10130 }
10325 }10131 }
1032610132
10327 // explicit cast from [N]T to ?[]const N10133 // cast from [N]T to ?[]const N
10328 if (wanted_type->id == TypeTableEntryIdOptional &&10134 if (wanted_type->id == TypeTableEntryIdOptional &&
10329 is_slice(wanted_type->data.maybe.child_type) &&10135 is_slice(wanted_type->data.maybe.child_type) &&
10330 actual_type->id == TypeTableEntryIdArray)10136 actual_type->id == TypeTableEntryIdArray)
...@@ -10348,7 +10154,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10348,7 +10154,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10348 }10154 }
10349 }10155 }
1035010156
10351 // explicit *[N]T to [*]T10157 // *[N]T to [*]T
10352 if (wanted_type->id == TypeTableEntryIdPointer &&10158 if (wanted_type->id == TypeTableEntryIdPointer &&
10353 wanted_type->data.pointer.ptr_len == PtrLenUnknown &&10159 wanted_type->data.pointer.ptr_len == PtrLenUnknown &&
10354 actual_type->id == TypeTableEntryIdPointer &&10160 actual_type->id == TypeTableEntryIdPointer &&
...@@ -10362,7 +10168,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10362,7 +10168,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10362 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);10168 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type);
10363 }10169 }
1036410170
10365 // explicit *[N]T to []T10171 // *[N]T to []T
10366 if (is_slice(wanted_type) &&10172 if (is_slice(wanted_type) &&
10367 actual_type->id == TypeTableEntryIdPointer &&10173 actual_type->id == TypeTableEntryIdPointer &&
10368 actual_type->data.pointer.ptr_len == PtrLenSingle &&10174 actual_type->data.pointer.ptr_len == PtrLenSingle &&
...@@ -10379,7 +10185,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10379,7 +10185,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10379 }10185 }
1038010186
1038110187
10382 // explicit cast from T to ?T10188 // cast from T to ?T
10383 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism10189 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism
10384 if (wanted_type->id == TypeTableEntryIdOptional) {10190 if (wanted_type->id == TypeTableEntryIdOptional) {
10385 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;10191 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;
...@@ -10411,14 +10217,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10411,14 +10217,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10411 }10217 }
10412 }10218 }
1041310219
10414 // explicit cast from null literal to maybe type10220 // cast from null literal to maybe type
10415 if (wanted_type->id == TypeTableEntryIdOptional &&10221 if (wanted_type->id == TypeTableEntryIdOptional &&
10416 actual_type->id == TypeTableEntryIdNull)10222 actual_type->id == TypeTableEntryIdNull)
10417 {10223 {
10418 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);10224 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);
10419 }10225 }
1042010226
10421 // explicit cast from child type of error type to error type10227 // cast from child type of error type to error type
10422 if (wanted_type->id == TypeTableEntryIdErrorUnion) {10228 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
10423 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,10229 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
10424 source_node, false).id == ConstCastResultIdOk)10230 source_node, false).id == ConstCastResultIdOk)
...@@ -10435,7 +10241,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10435,7 +10241,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10435 }10241 }
10436 }10242 }
1043710243
10438 // explicit cast from [N]T to E![]const T10244 // cast from [N]T to E![]const T
10439 if (wanted_type->id == TypeTableEntryIdErrorUnion &&10245 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
10440 is_slice(wanted_type->data.error_union.payload_type) &&10246 is_slice(wanted_type->data.error_union.payload_type) &&
10441 actual_type->id == TypeTableEntryIdArray)10247 actual_type->id == TypeTableEntryIdArray)
...@@ -10459,14 +10265,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10459,14 +10265,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10459 }10265 }
10460 }10266 }
1046110267
10462 // explicit cast from error set to error union type10268 // cast from error set to error union type
10463 if (wanted_type->id == TypeTableEntryIdErrorUnion &&10269 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
10464 actual_type->id == TypeTableEntryIdErrorSet)10270 actual_type->id == TypeTableEntryIdErrorSet)
10465 {10271 {
10466 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);10272 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
10467 }10273 }
1046810274
10469 // explicit cast from T to E!?T10275 // cast from T to E!?T
10470 if (wanted_type->id == TypeTableEntryIdErrorUnion &&10276 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
10471 wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional &&10277 wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional &&
10472 actual_type->id != TypeTableEntryIdOptional)10278 actual_type->id != TypeTableEntryIdOptional)
...@@ -10489,8 +10295,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10489,8 +10295,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10489 }10295 }
10490 }10296 }
1049110297
10492 // explicit cast from number literal to another type10298 // cast from number literal to another type
10493 // explicit cast from number literal to *const integer10299 // cast from number literal to *const integer
10494 if (actual_type->id == TypeTableEntryIdComptimeFloat ||10300 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
10495 actual_type->id == TypeTableEntryIdComptimeInt)10301 actual_type->id == TypeTableEntryIdComptimeInt)
10496 {10302 {
...@@ -10540,7 +10346,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10540,7 +10346,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10540 }10346 }
10541 }10347 }
1054210348
10543 // explicit cast from typed number to integer or float literal.10349 // cast from typed number to integer or float literal.
10544 // works when the number is known at compile time10350 // works when the number is known at compile time
10545 if (instr_is_comptime(value) &&10351 if (instr_is_comptime(value) &&
10546 ((actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) ||10352 ((actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) ||
...@@ -10549,7 +10355,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10549,7 +10355,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10549 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);10355 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);
10550 }10356 }
1055110357
10552 // explicit cast from union to the enum type of the union10358 // cast from union to the enum type of the union
10553 if (actual_type->id == TypeTableEntryIdUnion && wanted_type->id == TypeTableEntryIdEnum) {10359 if (actual_type->id == TypeTableEntryIdUnion && wanted_type->id == TypeTableEntryIdEnum) {
10554 type_ensure_zero_bits_known(ira->codegen, actual_type);10360 type_ensure_zero_bits_known(ira->codegen, actual_type);
10555 if (type_is_invalid(actual_type))10361 if (type_is_invalid(actual_type))
...@@ -10560,7 +10366,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10560,7 +10366,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10560 }10366 }
10561 }10367 }
1056210368
10563 // explicit enum to union which has the enum as the tag type10369 // enum to union which has the enum as the tag type
10564 if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum &&10370 if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum &&
10565 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||10371 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum ||
10566 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))10372 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr))
...@@ -10571,7 +10377,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10571,7 +10377,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10571 }10377 }
10572 }10378 }
1057310379
10574 // explicit enum to &const union which has the enum as the tag type10380 // enum to &const union which has the enum as the tag type
10575 if (actual_type->id == TypeTableEntryIdEnum && wanted_type->id == TypeTableEntryIdPointer) {10381 if (actual_type->id == TypeTableEntryIdEnum && wanted_type->id == TypeTableEntryIdPointer) {
10576 TypeTableEntry *union_type = wanted_type->data.pointer.child_type;10382 TypeTableEntry *union_type = wanted_type->data.pointer.child_type;
10577 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||10383 if (union_type->data.unionation.decl_node->data.container_decl.auto_enum ||
...@@ -10592,7 +10398,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10592,7 +10398,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10592 }10398 }
10593 }10399 }
1059410400
10595 // explicit cast from *T to *[1]T10401 // cast from *T to *[1]T
10596 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&10402 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
10597 actual_type->id == TypeTableEntryIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle)10403 actual_type->id == TypeTableEntryIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle)
10598 {10404 {
...@@ -10616,7 +10422,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10616,7 +10422,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10616 }10422 }
10617 }10423 }
1061810424
10619 // explicit cast from T to *T where T is zero bits10425 // cast from T to *T where T is zero bits
10620 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&10426 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
10621 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,10427 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
10622 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)10428 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
...@@ -10631,12 +10437,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10631,12 +10437,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10631 }10437 }
1063210438
1063310439
10634 // explicit cast from undefined to anything10440 // cast from undefined to anything
10635 if (actual_type->id == TypeTableEntryIdUndefined) {10441 if (actual_type->id == TypeTableEntryIdUndefined) {
10636 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);10442 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
10637 }10443 }
1063810444
10639 // explicit cast from something to const pointer of it10445 // cast from something to const pointer of it
10640 if (!type_requires_comptime(actual_type)) {10446 if (!type_requires_comptime(actual_type)) {
10641 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);10447 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
10642 if (types_match_const_cast_only(ira, wanted_type, const_ptr_actual, source_node, false).id == ConstCastResultIdOk) {10448 if (types_match_const_cast_only(ira, wanted_type, const_ptr_actual, source_node, false).id == ConstCastResultIdOk) {
...@@ -10644,10 +10450,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10644,10 +10450,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10644 }10450 }
10645 }10451 }
1064610452
10647 ir_add_error_node(ira, source_instr->source_node,10453 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node,
10648 buf_sprintf("invalid cast from type '%s' to '%s'",10454 buf_sprintf("expected type '%s', found '%s'",
10649 buf_ptr(&actual_type->name),10455 buf_ptr(&wanted_type->name),
10650 buf_ptr(&wanted_type->name)));10456 buf_ptr(&actual_type->name)));
10457 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg);
10651 return ira->codegen->invalid_instruction;10458 return ira->codegen->invalid_instruction;
10652}10459}
1065310460
...@@ -10664,22 +10471,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ...@@ -10664,22 +10471,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
10664 if (value->value.type->id == TypeTableEntryIdUnreachable)10471 if (value->value.type->id == TypeTableEntryIdUnreachable)
10665 return value;10472 return value;
1066610473
10667 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->value.type, value);10474 return ir_analyze_cast(ira, value, expected_type, value);
10668 switch (result) {
10669 case ImplicitCastMatchResultNo:
10670 ir_add_error(ira, value,
10671 buf_sprintf("expected type '%s', found '%s'",
10672 buf_ptr(&expected_type->name),
10673 buf_ptr(&value->value.type->name)));
10674 return ira->codegen->invalid_instruction;
10675
10676 case ImplicitCastMatchResultYes:
10677 return ir_analyze_cast(ira, value, expected_type, value);
10678 case ImplicitCastMatchResultReportedError:
10679 return ira->codegen->invalid_instruction;
10680 }
10681
10682 zig_unreachable();
10683}10475}
1068410476
10685static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {10477static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
test/compile_errors.zig+11-8
...@@ -100,7 +100,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -100,7 +100,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
100 \\ var rule_set = try Foo.init();100 \\ var rule_set = try Foo.init();
101 \\}101 \\}
102 ,102 ,
103 ".tmp_source.zig:2:13: error: invalid cast from type 'type' to 'i32'",103 ".tmp_source.zig:2:13: error: expected type 'i32', found 'type'",
104 );104 );
105105
106 cases.add(106 cases.add(
...@@ -122,7 +122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -122,7 +122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
122 );122 );
123123
124 cases.add(124 cases.add(
125 "invalid deref on switch target",125 "nested error set mismatch",
126 \\const NextError = error{NextError};126 \\const NextError = error{NextError};
127 \\const OtherError = error{OutOfMemory};127 \\const OtherError = error{OutOfMemory};
128 \\128 \\
...@@ -134,7 +134,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -134,7 +134,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
134 \\ return null;134 \\ return null;
135 \\}135 \\}
136 ,136 ,
137 ".tmp_source.zig:5:34: error: expected 'NextError!i32', found 'OtherError!i32'",137 ".tmp_source.zig:5:34: error: expected type '?NextError!i32', found '?OtherError!i32'",
138 ".tmp_source.zig:5:34: note: optional type child 'OtherError!i32' cannot cast into optional type child 'NextError!i32'",
139 ".tmp_source.zig:5:34: note: error set 'OtherError' cannot cast into error set 'NextError'",
138 ".tmp_source.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",140 ".tmp_source.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",
139 );141 );
140142
...@@ -437,8 +439,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -437,8 +439,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
437 \\ return error.B;439 \\ return error.B;
438 \\}440 \\}
439 ,441 ,
440 ".tmp_source.zig:3:35: error: expected 'SmallErrorSet!i32', found 'error!i32'",442 ".tmp_source.zig:3:35: error: expected type 'SmallErrorSet!i32', found 'error!i32'",
441 ".tmp_source.zig:3:35: note: unable to cast global error set into smaller set",443 ".tmp_source.zig:3:35: note: error set 'error' cannot cast into error set 'SmallErrorSet'",
444 ".tmp_source.zig:3:35: note: cannot cast global error set into smaller set",
442 );445 );
443446
444 cases.add(447 cases.add(
...@@ -451,8 +454,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -451,8 +454,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
451 \\ return error.B;454 \\ return error.B;
452 \\}455 \\}
453 ,456 ,
454 ".tmp_source.zig:3:31: error: expected 'SmallErrorSet', found 'error'",457 ".tmp_source.zig:3:31: error: expected type 'SmallErrorSet', found 'error'",
455 ".tmp_source.zig:3:31: note: unable to cast global error set into smaller set",458 ".tmp_source.zig:3:31: note: cannot cast global error set into smaller set",
456 );459 );
457460
458 cases.add(461 cases.add(
...@@ -478,7 +481,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -478,7 +481,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
478 \\ var x: Set2 = set1;481 \\ var x: Set2 = set1;
479 \\}482 \\}
480 ,483 ,
481 ".tmp_source.zig:7:19: error: expected 'Set2', found 'Set1'",484 ".tmp_source.zig:7:19: error: expected type 'Set2', found 'Set1'",
482 ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set",485 ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set",
483 );486 );
484487