| ... | @@ -65,12 +65,7 @@ enum ConstCastResultId { | ... | @@ -65,12 +65,7 @@ enum ConstCastResultId { |
| 65 | ConstCastResultIdNullWrapPtr, | 65 | ConstCastResultIdNullWrapPtr, |
| 66 | }; | 66 | }; |
| 67 | | 67 | |
| 68 | struct ConstCastErrSetMismatch { | | |
| 69 | ZigList<ErrorTableEntry *> missing_errors; | | |
| 70 | }; | | |
| 71 | | | |
| 72 | struct ConstCastOnly; | 68 | struct ConstCastOnly; |
| 73 | | | |
| 74 | struct ConstCastArg { | 69 | struct 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 | }; |
| 82 | | 77 | |
| | 78 | struct ConstCastOptionalMismatch; |
| | 79 | struct ConstCastPointerMismatch; |
| | 80 | struct ConstCastSliceMismatch; |
| | 81 | struct ConstCastErrUnionErrSetMismatch; |
| | 82 | struct ConstCastErrUnionPayloadMismatch; |
| | 83 | struct ConstCastErrSetMismatch; |
| | 84 | |
| 83 | struct ConstCastOnly { | 85 | struct 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 | }; |
| 99 | | 101 | |
| | 102 | struct ConstCastOptionalMismatch { |
| | 103 | ConstCastOnly child; |
| | 104 | TypeTableEntry *wanted_child; |
| | 105 | TypeTableEntry *actual_child; |
| | 106 | }; |
| | 107 | |
| | 108 | struct ConstCastPointerMismatch { |
| | 109 | ConstCastOnly child; |
| | 110 | TypeTableEntry *wanted_child; |
| | 111 | TypeTableEntry *actual_child; |
| | 112 | }; |
| | 113 | |
| | 114 | struct ConstCastSliceMismatch { |
| | 115 | ConstCastOnly child; |
| | 116 | TypeTableEntry *wanted_child; |
| | 117 | TypeTableEntry *actual_child; |
| | 118 | }; |
| | 119 | |
| | 120 | struct ConstCastErrUnionErrSetMismatch { |
| | 121 | ConstCastOnly child; |
| | 122 | TypeTableEntry *wanted_err_set; |
| | 123 | TypeTableEntry *actual_err_set; |
| | 124 | }; |
| | 125 | |
| | 126 | struct ConstCastErrUnionPayloadMismatch { |
| | 127 | ConstCastOnly child; |
| | 128 | TypeTableEntry *wanted_payload; |
| | 129 | TypeTableEntry *actual_payload; |
| | 130 | }; |
| | 131 | |
| | 132 | struct ConstCastErrSetMismatch { |
| | 133 | ZigList<ErrorTableEntry *> missing_errors; |
| | 134 | }; |
| 100 | | 135 | |
| 101 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 136 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 102 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); | 137 | static 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 | } |
| 8166 | | 8212 | |
| 8167 | enum ImplicitCastMatchResult { | | |
| 8168 | ImplicitCastMatchResultNo, | | |
| 8169 | ImplicitCastMatchResultYes, | | |
| 8170 | ImplicitCastMatchResultReportedError, | | |
| 8171 | }; | | |
| 8172 | | | |
| 8173 | static 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 | | | |
| 8486 | static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { | 8213 | static 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 | } |
| 10229 | | 9956 | |
| | 9957 | static 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 | |
| 10230 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, | 10034 | static 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 | } |
| 10239 | | 10043 | |
| 10240 | // perfect match or non-const to const | 10044 | // 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 | } |
| 10244 | | 10050 | |
| 10245 | // explicit widening conversion | 10051 | // 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 | } |
| 10261 | | 10067 | |
| 10262 | // explicit float widening conversion | 10068 | // 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 | } |
| 10269 | | 10075 | |
| 10270 | | 10076 | |
| 10271 | // explicit cast from [N]T to []const T | 10077 | // 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 | } |
| 10282 | | 10088 | |
| 10283 | // explicit cast from &const [N]T to []const T | 10089 | // 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 | } |
| 10301 | | 10107 | |
| 10302 | // explicit cast from [N]T to &const []const T | 10108 | // 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 | } |
| 10326 | | 10132 | |
| 10327 | // explicit cast from [N]T to ?[]const N | 10133 | // 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 | } |
| 10350 | | 10156 | |
| 10351 | // explicit *[N]T to [*]T | 10157 | // *[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 | } |
| 10364 | | 10170 | |
| 10365 | // explicit *[N]T to []T | 10171 | // *[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 | } |
| 10380 | | 10186 | |
| 10381 | | 10187 | |
| 10382 | // explicit cast from T to ?T | 10188 | // cast from T to ?T |
| 10383 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism | 10189 | // 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 | } |
| 10413 | | 10219 | |
| 10414 | // explicit cast from null literal to maybe type | 10220 | // 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 | } |
| 10420 | | 10226 | |
| 10421 | // explicit cast from child type of error type to error type | 10227 | // 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 | } |
| 10437 | | 10243 | |
| 10438 | // explicit cast from [N]T to E![]const T | 10244 | // 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 | } |
| 10461 | | 10267 | |
| 10462 | // explicit cast from error set to error union type | 10268 | // 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 | } |
| 10468 | | 10274 | |
| 10469 | // explicit cast from T to E!?T | 10275 | // 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 | } |
| 10491 | | 10297 | |
| 10492 | // explicit cast from number literal to another type | 10298 | // cast from number literal to another type |
| 10493 | // explicit cast from number literal to *const integer | 10299 | // 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 | } |
| 10542 | | 10348 | |
| 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 time | 10350 | // 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 | } |
| 10551 | | 10357 | |
| 10552 | // explicit cast from union to the enum type of the union | 10358 | // 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 | } |
| 10562 | | 10368 | |
| 10563 | // explicit enum to union which has the enum as the tag type | 10369 | // 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 | } |
| 10573 | | 10379 | |
| 10574 | // explicit enum to &const union which has the enum as the tag type | 10380 | // 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 | } |
| 10594 | | 10400 | |
| 10595 | // explicit cast from *T to *[1]T | 10401 | // 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 | } |
| 10618 | | 10424 | |
| 10619 | // explicit cast from T to *T where T is zero bits | 10425 | // 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 | } |
| 10632 | | 10438 | |
| 10633 | | 10439 | |
| 10634 | // explicit cast from undefined to anything | 10440 | // 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 | } |
| 10638 | | 10444 | |
| 10639 | // explicit cast from something to const pointer of it | 10445 | // 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 | } |
| 10646 | | 10452 | |
| 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 | } |
| 10653 | | 10460 | |
| ... | @@ -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; |
| 10666 | | 10473 | |
| 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 | } |
| 10684 | | 10476 | |
| 10685 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { | 10477 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { |