| ... | @@ -63,6 +63,7 @@ enum ConstCastResultId { | ... | @@ -63,6 +63,7 @@ enum ConstCastResultId { |
| 63 | ConstCastResultIdPointerChild, | 63 | ConstCastResultIdPointerChild, |
| 64 | ConstCastResultIdSliceChild, | 64 | ConstCastResultIdSliceChild, |
| 65 | ConstCastResultIdOptionalChild, | 65 | ConstCastResultIdOptionalChild, |
| | 66 | ConstCastResultIdOptionalShape, |
| 66 | ConstCastResultIdErrorUnionPayload, | 67 | ConstCastResultIdErrorUnionPayload, |
| 67 | ConstCastResultIdErrorUnionErrorSet, | 68 | ConstCastResultIdErrorUnionErrorSet, |
| 68 | ConstCastResultIdFnAlign, | 69 | ConstCastResultIdFnAlign, |
| ... | @@ -11946,8 +11947,22 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted | ... | @@ -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 | if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { | 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 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, | 11966 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, |
| 11952 | actual_type->data.maybe.child_type, source_node, wanted_is_mutable); | 11967 | actual_type->data.maybe.child_type, source_node, wanted_is_mutable); |
| 11953 | if (child.id == ConstCastResultIdInvalid) | 11968 | if (child.id == ConstCastResultIdInvalid) |
| ... | @@ -14549,6 +14564,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa | ... | @@ -14549,6 +14564,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 14549 | report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); | 14564 | report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); |
| 14550 | break; | 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 | case ConstCastResultIdErrorUnionErrorSet: { | 14574 | case ConstCastResultIdErrorUnionErrorSet: { |
| 14553 | ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, | 14575 | ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, |
| 14554 | buf_sprintf("error set '%s' cannot cast into error set '%s'", | 14576 | buf_sprintf("error set '%s' cannot cast into error set '%s'", |