| ... | ... | @@ -65,12 +65,7 @@ enum ConstCastResultId { |
| 65 | 65 | ConstCastResultIdNullWrapPtr, |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | | struct ConstCastErrSetMismatch { |
| 69 | | ZigList<ErrorTableEntry *> missing_errors; |
| 70 | | }; |
| 71 | | |
| 72 | 68 | struct ConstCastOnly; |
| 73 | | |
| 74 | 69 | struct ConstCastArg { |
| 75 | 70 | size_t arg_index; |
| 76 | 71 | ConstCastOnly *child; |
| ... | ... | @@ -80,15 +75,22 @@ struct ConstCastArgNoAlias { |
| 80 | 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 | 85 | struct ConstCastOnly { |
| 84 | 86 | ConstCastResultId id; |
| 85 | 87 | union { |
| 86 | | ConstCastErrSetMismatch error_set; |
| 87 | | ConstCastOnly *pointer_child; |
| 88 | | ConstCastOnly *slice_child; |
| 89 | | ConstCastOnly *optional_child; |
| 90 | | ConstCastOnly *error_union_payload; |
| 91 | | ConstCastOnly *error_union_error_set; |
| 88 | ConstCastErrSetMismatch *error_set_mismatch; |
| 89 | ConstCastPointerMismatch *pointer_mismatch; |
| 90 | ConstCastSliceMismatch *slice_mismatch; |
| 91 | ConstCastOptionalMismatch *optional; |
| 92 | ConstCastErrUnionPayloadMismatch *error_union_payload; |
| 93 | ConstCastErrUnionErrSetMismatch *error_union_error_set; |
| 92 | 94 | ConstCastOnly *return_type; |
| 93 | 95 | ConstCastOnly *async_allocator_type; |
| 94 | 96 | ConstCastOnly *null_wrap_ptr_child; |
| ... | ... | @@ -97,6 +99,39 @@ struct ConstCastOnly { |
| 97 | 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 | 136 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 102 | 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 | 8007 | actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const); |
| 7973 | 8008 | if (child.id != ConstCastResultIdOk) { |
| 7974 | 8009 | result.id = ConstCastResultIdPointerChild; |
| 7975 | | result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1); |
| 7976 | | *result.data.pointer_child = child; |
| 8010 | result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); |
| 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 | 8015 | return result; |
| 7979 | 8016 | } |
| ... | ... | @@ -7992,8 +8029,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 7992 | 8029 | actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); |
| 7993 | 8030 | if (child.id != ConstCastResultIdOk) { |
| 7994 | 8031 | result.id = ConstCastResultIdSliceChild; |
| 7995 | | result.data.slice_child = allocate_nonzero<ConstCastOnly>(1); |
| 7996 | | *result.data.slice_child = child; |
| 8032 | result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); |
| 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 | 8037 | return result; |
| 7999 | 8038 | } |
| ... | ... | @@ -8005,8 +8044,10 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8005 | 8044 | actual_type->data.maybe.child_type, source_node, wanted_is_mutable); |
| 8006 | 8045 | if (child.id != ConstCastResultIdOk) { |
| 8007 | 8046 | result.id = ConstCastResultIdOptionalChild; |
| 8008 | | result.data.optional_child = allocate_nonzero<ConstCastOnly>(1); |
| 8009 | | *result.data.optional_child = child; |
| 8047 | result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); |
| 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 | 8052 | return result; |
| 8012 | 8053 | } |
| ... | ... | @@ -8017,16 +8058,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8017 | 8058 | actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); |
| 8018 | 8059 | if (payload_child.id != ConstCastResultIdOk) { |
| 8019 | 8060 | result.id = ConstCastResultIdErrorUnionPayload; |
| 8020 | | result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1); |
| 8021 | | *result.data.error_union_payload = payload_child; |
| 8061 | result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); |
| 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 | 8065 | return result; |
| 8023 | 8066 | } |
| 8024 | 8067 | ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, |
| 8025 | 8068 | actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); |
| 8026 | 8069 | if (error_set_child.id != ConstCastResultIdOk) { |
| 8027 | 8070 | result.id = ConstCastResultIdErrorUnionErrorSet; |
| 8028 | | result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1); |
| 8029 | | *result.data.error_union_error_set = error_set_child; |
| 8071 | result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); |
| 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 | 8075 | return result; |
| 8031 | 8076 | } |
| 8032 | 8077 | return result; |
| ... | ... | @@ -8068,8 +8113,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8068 | 8113 | if (error_entry == nullptr) { |
| 8069 | 8114 | if (result.id == ConstCastResultIdOk) { |
| 8070 | 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 | 8121 | free(errors); |
| ... | ... | @@ -8164,325 +8210,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8164 | 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 | 8213 | static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { |
| 8487 | 8214 | size_t old_errors_count = *errors_count; |
| 8488 | 8215 | *errors_count = g->errors_by_index.length; |
| ... | ... | @@ -10227,6 +9954,83 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou |
| 10227 | 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 | 10034 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 10231 | 10035 | TypeTableEntry *wanted_type, IrInstruction *value) |
| 10232 | 10036 | { |
| ... | ... | @@ -10238,11 +10042,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10238 | 10042 | } |
| 10239 | 10043 | |
| 10240 | 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 | 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 | 10052 | if (wanted_type->id == TypeTableEntryIdInt && |
| 10247 | 10053 | actual_type->id == TypeTableEntryIdInt && |
| 10248 | 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 | 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 | 10069 | if (wanted_type->id == TypeTableEntryIdFloat && |
| 10264 | 10070 | actual_type->id == TypeTableEntryIdFloat && |
| 10265 | 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 | 10074 | } |
| 10269 | 10075 | |
| 10270 | 10076 | |
| 10271 | | // explicit cast from [N]T to []const T |
| 10077 | // cast from [N]T to []const T |
| 10272 | 10078 | if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) { |
| 10273 | 10079 | TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| 10274 | 10080 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| ... | ... | @@ -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 | 10090 | if (is_slice(wanted_type) && |
| 10285 | 10091 | actual_type->id == TypeTableEntryIdPointer && |
| 10286 | 10092 | actual_type->data.pointer.is_const && |
| ... | ... | @@ -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 | 10109 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 10304 | 10110 | wanted_type->data.pointer.is_const && |
| 10305 | 10111 | is_slice(wanted_type->data.pointer.child_type) && |
| ... | ... | @@ -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 | 10134 | if (wanted_type->id == TypeTableEntryIdOptional && |
| 10329 | 10135 | is_slice(wanted_type->data.maybe.child_type) && |
| 10330 | 10136 | actual_type->id == TypeTableEntryIdArray) |
| ... | ... | @@ -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 | 10158 | if (wanted_type->id == TypeTableEntryIdPointer && |
| 10353 | 10159 | wanted_type->data.pointer.ptr_len == PtrLenUnknown && |
| 10354 | 10160 | actual_type->id == TypeTableEntryIdPointer && |
| ... | ... | @@ -10362,7 +10168,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10362 | 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 | 10172 | if (is_slice(wanted_type) && |
| 10367 | 10173 | actual_type->id == TypeTableEntryIdPointer && |
| 10368 | 10174 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| ... | ... | @@ -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 | 10189 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism |
| 10384 | 10190 | if (wanted_type->id == TypeTableEntryIdOptional) { |
| 10385 | 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 | 10217 | } |
| 10412 | 10218 | } |
| 10413 | 10219 | |
| 10414 | | // explicit cast from null literal to maybe type |
| 10220 | // cast from null literal to maybe type |
| 10415 | 10221 | if (wanted_type->id == TypeTableEntryIdOptional && |
| 10416 | 10222 | actual_type->id == TypeTableEntryIdNull) |
| 10417 | 10223 | { |
| 10418 | 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 | 10228 | if (wanted_type->id == TypeTableEntryIdErrorUnion) { |
| 10423 | 10229 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| 10424 | 10230 | source_node, false).id == ConstCastResultIdOk) |
| ... | ... | @@ -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 | 10245 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 10440 | 10246 | is_slice(wanted_type->data.error_union.payload_type) && |
| 10441 | 10247 | actual_type->id == TypeTableEntryIdArray) |
| ... | ... | @@ -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 | 10269 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 10464 | 10270 | actual_type->id == TypeTableEntryIdErrorSet) |
| 10465 | 10271 | { |
| 10466 | 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 | 10276 | if (wanted_type->id == TypeTableEntryIdErrorUnion && |
| 10471 | 10277 | wanted_type->data.error_union.payload_type->id == TypeTableEntryIdOptional && |
| 10472 | 10278 | actual_type->id != TypeTableEntryIdOptional) |
| ... | ... | @@ -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 |
| 10493 | | // explicit cast from number literal to *const integer |
| 10298 | // cast from number literal to another type |
| 10299 | // cast from number literal to *const integer |
| 10494 | 10300 | if (actual_type->id == TypeTableEntryIdComptimeFloat || |
| 10495 | 10301 | actual_type->id == TypeTableEntryIdComptimeInt) |
| 10496 | 10302 | { |
| ... | ... | @@ -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 | 10350 | // works when the number is known at compile time |
| 10545 | 10351 | if (instr_is_comptime(value) && |
| 10546 | 10352 | ((actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) || |
| ... | ... | @@ -10549,7 +10355,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10549 | 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 | 10359 | if (actual_type->id == TypeTableEntryIdUnion && wanted_type->id == TypeTableEntryIdEnum) { |
| 10554 | 10360 | type_ensure_zero_bits_known(ira->codegen, actual_type); |
| 10555 | 10361 | if (type_is_invalid(actual_type)) |
| ... | ... | @@ -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 | 10370 | if (wanted_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum && |
| 10565 | 10371 | (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 10566 | 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 | 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 | 10381 | if (actual_type->id == TypeTableEntryIdEnum && wanted_type->id == TypeTableEntryIdPointer) { |
| 10576 | 10382 | TypeTableEntry *union_type = wanted_type->data.pointer.child_type; |
| 10577 | 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 | 10398 | } |
| 10593 | 10399 | } |
| 10594 | 10400 | |
| 10595 | | // explicit cast from *T to *[1]T |
| 10401 | // cast from *T to *[1]T |
| 10596 | 10402 | if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 10597 | 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 | 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 | 10426 | if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| 10621 | 10427 | types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, |
| 10622 | 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 | 10437 | } |
| 10632 | 10438 | |
| 10633 | 10439 | |
| 10634 | | // explicit cast from undefined to anything |
| 10440 | // cast from undefined to anything |
| 10635 | 10441 | if (actual_type->id == TypeTableEntryIdUndefined) { |
| 10636 | 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 | 10446 | if (!type_requires_comptime(actual_type)) { |
| 10641 | 10447 | TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); |
| 10642 | 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 | 10450 | } |
| 10645 | 10451 | } |
| 10646 | 10452 | |
| 10647 | | ir_add_error_node(ira, source_instr->source_node, |
| 10648 | | buf_sprintf("invalid cast from type '%s' to '%s'", |
| 10649 | | buf_ptr(&actual_type->name), |
| 10650 | | buf_ptr(&wanted_type->name))); |
| 10453 | ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, |
| 10454 | buf_sprintf("expected type '%s', found '%s'", |
| 10455 | 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 | 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 | 10471 | if (value->value.type->id == TypeTableEntryIdUnreachable) |
| 10665 | 10472 | return value; |
| 10666 | 10473 | |
| 10667 | | ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->value.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(); |
| 10474 | return ir_analyze_cast(ira, value, expected_type, value); |
| 10683 | 10475 | } |
| 10684 | 10476 | |
| 10685 | 10477 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { |