| ... | @@ -6753,11 +6753,26 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, | ... | @@ -6753,11 +6753,26 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 6753 | } | 6753 | } |
| 6754 | | 6754 | |
| 6755 | // if we got here with error sets, make an error showing the incompatibilities | 6755 | // if we got here with error sets, make an error showing the incompatibilities |
| | 6756 | ZigList<ErrorTableEntry *> *missing_errors = nullptr; |
| 6756 | if (const_cast_result.id == ConstCastResultIdErrSet) { | 6757 | if (const_cast_result.id == ConstCastResultIdErrSet) { |
| | 6758 | missing_errors = &const_cast_result.data.error_set.missing_errors; |
| | 6759 | } |
| | 6760 | if (const_cast_result.id == ConstCastResultIdErrorUnionErrorSet) { |
| | 6761 | if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSet) { |
| | 6762 | missing_errors = &const_cast_result.data.error_union_error_set->data.error_set.missing_errors; |
| | 6763 | } else if (const_cast_result.data.error_union_error_set->id == ConstCastResultIdErrSetGlobal) { |
| | 6764 | ErrorMsg *msg = ir_add_error(ira, value, |
| | 6765 | buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name))); |
| | 6766 | add_error_note(ira->codegen, msg, value->source_node, |
| | 6767 | buf_sprintf("unable to cast global error set into smaller set")); |
| | 6768 | return ImplicitCastMatchResultReportedError; |
| | 6769 | } |
| | 6770 | } |
| | 6771 | if (missing_errors != nullptr) { |
| 6757 | ErrorMsg *msg = ir_add_error(ira, value, | 6772 | ErrorMsg *msg = ir_add_error(ira, value, |
| 6758 | buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name))); | 6773 | buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name))); |
| 6759 | for (size_t i = 0; i < const_cast_result.data.error_set.missing_errors.length; i += 1) { | 6774 | for (size_t i = 0; i < missing_errors->length; i += 1) { |
| 6760 | ErrorTableEntry *error_entry = const_cast_result.data.error_set.missing_errors.at(i); | 6775 | ErrorTableEntry *error_entry = missing_errors->at(i); |
| 6761 | add_error_note(ira->codegen, msg, error_entry->decl_node, | 6776 | add_error_note(ira->codegen, msg, error_entry->decl_node, |
| 6762 | buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); | 6777 | buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); |
| 6763 | } | 6778 | } |
| ... | @@ -7187,6 +7202,84 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod | ... | @@ -7187,6 +7202,84 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7187 | } | 7202 | } |
| 7188 | } | 7203 | } |
| 7189 | | 7204 | |
| | 7205 | if (prev_type->id == TypeTableEntryIdErrorUnion && cur_type->id == TypeTableEntryIdErrorUnion) { |
| | 7206 | TypeTableEntry *prev_payload_type = prev_type->data.error_union.payload_type; |
| | 7207 | TypeTableEntry *cur_payload_type = cur_type->data.error_union.payload_type; |
| | 7208 | |
| | 7209 | bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, |
| | 7210 | source_node).id == ConstCastResultIdOk; |
| | 7211 | bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, |
| | 7212 | source_node).id == ConstCastResultIdOk; |
| | 7213 | |
| | 7214 | if (const_cast_prev || const_cast_cur) { |
| | 7215 | if (const_cast_cur) { |
| | 7216 | prev_inst = cur_inst; |
| | 7217 | } |
| | 7218 | |
| | 7219 | TypeTableEntry *prev_err_set_type = prev_type->data.error_union.err_set_type; |
| | 7220 | TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type; |
| | 7221 | |
| | 7222 | if (!resolve_inferred_error_set(ira, prev_err_set_type, cur_inst->source_node)) { |
| | 7223 | return ira->codegen->builtin_types.entry_invalid; |
| | 7224 | } |
| | 7225 | |
| | 7226 | if (!resolve_inferred_error_set(ira, cur_err_set_type, cur_inst->source_node)) { |
| | 7227 | return ira->codegen->builtin_types.entry_invalid; |
| | 7228 | } |
| | 7229 | |
| | 7230 | if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { |
| | 7231 | err_set_type = ira->codegen->builtin_types.entry_global_error_set; |
| | 7232 | continue; |
| | 7233 | } |
| | 7234 | |
| | 7235 | if (err_set_type == nullptr) { |
| | 7236 | err_set_type = prev_err_set_type; |
| | 7237 | errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| | 7238 | for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { |
| | 7239 | ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; |
| | 7240 | errors[error_entry->value] = error_entry; |
| | 7241 | } |
| | 7242 | } |
| | 7243 | bool prev_is_superset = true; |
| | 7244 | for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { |
| | 7245 | ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; |
| | 7246 | ErrorTableEntry *error_entry = errors[contained_error_entry->value]; |
| | 7247 | if (error_entry == nullptr) { |
| | 7248 | prev_is_superset = false; |
| | 7249 | break; |
| | 7250 | } |
| | 7251 | } |
| | 7252 | if (prev_is_superset) { |
| | 7253 | continue; |
| | 7254 | } |
| | 7255 | // unset all the errors |
| | 7256 | for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { |
| | 7257 | ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; |
| | 7258 | errors[error_entry->value] = nullptr; |
| | 7259 | } |
| | 7260 | for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { |
| | 7261 | ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; |
| | 7262 | errors[error_entry->value] = error_entry; |
| | 7263 | } |
| | 7264 | bool cur_is_superset = true; |
| | 7265 | for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { |
| | 7266 | ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; |
| | 7267 | ErrorTableEntry *error_entry = errors[contained_error_entry->value]; |
| | 7268 | if (error_entry == nullptr) { |
| | 7269 | cur_is_superset = false; |
| | 7270 | break; |
| | 7271 | } |
| | 7272 | } |
| | 7273 | if (cur_is_superset) { |
| | 7274 | err_set_type = cur_err_set_type; |
| | 7275 | continue; |
| | 7276 | } |
| | 7277 | |
| | 7278 | err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); |
| | 7279 | continue; |
| | 7280 | } |
| | 7281 | } |
| | 7282 | |
| 7190 | if (types_match_const_cast_only(ira, prev_type, cur_type, source_node).id == ConstCastResultIdOk) { | 7283 | if (types_match_const_cast_only(ira, prev_type, cur_type, source_node).id == ConstCastResultIdOk) { |
| 7191 | continue; | 7284 | continue; |
| 7192 | } | 7285 | } |