| ... | @@ -60,7 +60,7 @@ enum ConstCastResultId { | ... | @@ -60,7 +60,7 @@ enum ConstCastResultId { |
| 60 | ConstCastResultIdType, | 60 | ConstCastResultIdType, |
| 61 | ConstCastResultIdUnresolvedInferredErrSet, | 61 | ConstCastResultIdUnresolvedInferredErrSet, |
| 62 | ConstCastResultIdAsyncAllocatorType, | 62 | ConstCastResultIdAsyncAllocatorType, |
| 63 | ConstCastResultIdNullWrapPtr, | 63 | ConstCastResultIdNullWrapPtr |
| 64 | }; | 64 | }; |
| 65 | | 65 | |
| 66 | struct ConstCastOnly; | 66 | struct ConstCastOnly; |
| ... | @@ -8471,9 +8471,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry | ... | @@ -8471,9 +8471,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8471 | if (wanted_type == actual_type) | 8471 | if (wanted_type == actual_type) |
| 8472 | return result; | 8472 | return result; |
| 8473 | | 8473 | |
| 8474 | // * and [*] can do a const-cast-only to ?* and ?[*], respectively | 8474 | // *T and [*]T may const-cast-only to ?*U and ?[*]U, respectively |
| 8475 | // but not if there is a mutable parent pointer | 8475 | // but not if we want a mutable pointer |
| 8476 | // and not if the pointer is zero bits | 8476 | // and not if the actual pointer has zero bits |
| 8477 | if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional && | 8477 | if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional && |
| 8478 | wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer && | 8478 | wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer && |
| 8479 | actual_type->id == TypeTableEntryIdPointer && type_has_bits(actual_type)) | 8479 | actual_type->id == TypeTableEntryIdPointer && type_has_bits(actual_type)) |
| ... | @@ -8488,6 +8488,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry | ... | @@ -8488,6 +8488,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 8488 | return result; | 8488 | return result; |
| 8489 | } | 8489 | } |
| 8490 | | 8490 | |
| | 8491 | // *T and [*]T can always cast to ?*c_void |
| | 8492 | if (wanted_type->id == TypeTableEntryIdPointer && |
| | 8493 | wanted_type->data.pointer.ptr_len == PtrLenSingle && |
| | 8494 | wanted_type->data.pointer.child_type == g->builtin_types.entry_c_void && |
| | 8495 | actual_type->id == TypeTableEntryIdPointer && |
| | 8496 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && |
| | 8497 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) |
| | 8498 | { |
| | 8499 | assert(actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment); |
| | 8500 | return result; |
| | 8501 | } |
| | 8502 | |
| 8491 | // pointer const | 8503 | // pointer const |
| 8492 | if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) { | 8504 | if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) { |
| 8493 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, | 8505 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, |