| ... | ... | @@ -63,6 +63,7 @@ enum ConstCastResultId { |
| 63 | 63 | ConstCastResultIdPointerChild, |
| 64 | 64 | ConstCastResultIdSliceChild, |
| 65 | 65 | ConstCastResultIdOptionalChild, |
| 66 | ConstCastResultIdOptionalShape, |
| 66 | 67 | ConstCastResultIdErrorUnionPayload, |
| 67 | 68 | ConstCastResultIdErrorUnionErrorSet, |
| 68 | 69 | ConstCastResultIdFnAlign, |
| ... | ... | @@ -11946,8 +11947,22 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 11946 | 11947 | } |
| 11947 | 11948 | } |
| 11948 | 11949 | |
| 11949 | | // maybe |
| 11950 | // optional types |
| 11950 | 11951 | if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { |
| 11952 | // Consider the case where the wanted type is ??[*]T and the actual one |
| 11953 | // is ?[*]T, we cannot turn the former into the latter even though the |
| 11954 | // child types are compatible (?[*]T and [*]T are both represented as a |
| 11955 | // pointer). The extra level of indirection in ??[*]T means it's |
| 11956 | // represented as a regular, fat, optional type and, as a consequence, |
| 11957 | // has a different shape than the one of ?[*]T. |
| 11958 | if ((wanted_ptr_type != nullptr) != (actual_ptr_type != nullptr)) { |
| 11959 | // The use of type_mismatch is intentional |
| 11960 | result.id = ConstCastResultIdOptionalShape; |
| 11961 | result.data.type_mismatch = heap::c_allocator.allocate_nonzero<ConstCastTypeMismatch>(1); |
| 11962 | result.data.type_mismatch->wanted_type = wanted_type; |
| 11963 | result.data.type_mismatch->actual_type = actual_type; |
| 11964 | return result; |
| 11965 | } |
| 11951 | 11966 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, |
| 11952 | 11967 | actual_type->data.maybe.child_type, source_node, wanted_is_mutable); |
| 11953 | 11968 | if (child.id == ConstCastResultIdInvalid) |
| ... | ... | @@ -14549,6 +14564,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 14549 | 14564 | report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); |
| 14550 | 14565 | break; |
| 14551 | 14566 | } |
| 14567 | case ConstCastResultIdOptionalShape: { |
| 14568 | add_error_note(ira->codegen, parent_msg, source_node, |
| 14569 | buf_sprintf("optional type child '%s' cannot cast into optional type '%s'", |
| 14570 | buf_ptr(&cast_result->data.type_mismatch->actual_type->name), |
| 14571 | buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); |
| 14572 | break; |
| 14573 | } |
| 14552 | 14574 | case ConstCastResultIdErrorUnionErrorSet: { |
| 14553 | 14575 | ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, |
| 14554 | 14576 | buf_sprintf("error set '%s' cannot cast into error set '%s'", |