diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index 5f56b97e8..b77f2fe85 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -935,9 +935,15 @@ func void testExprBlock() printf("Was %d\n", x); } +typedef func int(int) as Blorb; + +func int eokf(int x) +{ + return x * x + 1; +} + func int main(int x) { - printf("Helo!\n"); testErrorBug(); testErrors(); diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 4369f6aaf..5765c4766 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -37,7 +37,29 @@ static bool sema_type_mismatch(Expr *expr, Type *type, CastType cast_type) case CAST_TYPE_OPTIONAL_IMPLICIT: UNREACHABLE } - SEMA_ERROR(expr, "Cannot %s '%s' to '%s'.", action, type_to_error_string(expr->type), type_to_error_string(type)); + Type *expr_type = expr->type; + if (expr_type == expr_type->canonical) + { + if (type->canonical == type) + { + SEMA_ERROR(expr, "Cannot %s '%s' to '%s'.", action, type_to_error_string(expr_type), type_to_error_string(type)); + } + else + { + SEMA_ERROR(expr, "Cannot %s '%s' to '%s' ('%s').", action, type_to_error_string(expr_type), type_to_error_string(type), type_to_error_string(type->canonical)); + } + } + else + { + if (type->canonical == type) + { + SEMA_ERROR(expr, "Cannot %s '%s' (%s) to '%s'.", action, type_to_error_string(expr_type), type_to_error_string(expr_type->canonical), type_to_error_string(type)); + } + else + { + SEMA_ERROR(expr, "Cannot %s '%s' (%s) to '%s' ('%s').", action, type_to_error_string(expr_type), type_to_error_string(expr_type->canonical), type_to_error_string(type), type_to_error_string(type->canonical)); + } + } return false; } @@ -132,6 +154,7 @@ bool ptpt(Expr* left, Type *from_canonical, Type *canonical, Type *type, CastTyp { if (cast_type != CAST_TYPE_EXPLICIT && !may_implicitly_cast_ptr_to_ptr(from_canonical, canonical)) { + if (cast_type == CAST_TYPE_OPTIONAL_IMPLICIT) return true; return sema_type_mismatch(left, type, cast_type); } RETURN_NON_CONST_CAST(CAST_PTRPTR); diff --git a/src/compiler/types.c b/src/compiler/types.c index 608e58013..4ba5e390f 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -99,13 +99,38 @@ const char *type_to_error_string(Type *type) case TYPE_F32: case TYPE_F64: case TYPE_FXX: - case TYPE_FUNC: case TYPE_UNION: case TYPE_ERROR: return type->name; + case TYPE_FUNC: + { + asprintf(&buffer, "func %s(", type_to_error_string(type->func.signature->rtype->type)); + VECEACH(type->func.signature->params, i) + { + if (i != 0) buffer = strcat_arena(buffer, ", "); + strcat_arena(buffer, type_to_error_string(type->func.signature->params[i]->type)); + } + buffer = strcat_arena(buffer, ")"); + if (type->func.signature->throw_any) + { + return strcat_arena(buffer, " throws"); + } + if (!vec_size(type->func.signature->throws)) return buffer; + buffer = strcat_arena(buffer, " throws "); + VECEACH(type->func.signature->throws, i) + { + if (i != 0) buffer = strcat_arena(buffer, ", "); + buffer = strcat_arena(buffer, type_to_error_string(type->func.signature->throws[i]->type)); + } + return buffer; + } case TYPE_TYPEID: return "typeid"; case TYPE_POINTER: + if (type->pointer->type_kind == TYPE_FUNC) + { + return type_to_error_string(type->pointer); + } asprintf(&buffer, "%s*", type_to_error_string(type->pointer)); return buffer; case TYPE_STRING: