}
// NOTE: Returns 0 if it was not possible to make the types compatible.
-b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
+b32 unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) {
AstTyped* node = *pnode;
if (type == NULL) return 0;
if (node == NULL) return 0;
- // if (node_is_type((AstNode *) node)) return 0;
-
if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) {
if (node->entity != NULL) return 1;
if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.elem;
if (!type_is_sl_constructable(type)) return 0;
+ // If this shouldn't make permanent changes and submit entities,
+ // just assume that it works and don't submit the entities.
+ if (!permanent) return 1;
+
node->type = type;
add_entities_for_node(NULL, (AstNode *) node, NULL, NULL);
if (node->kind == Ast_Kind_Array_Literal && node->type_node == NULL) {
if (node->entity != NULL) return 1;
+
+ // If this shouldn't make permanent changes and submit entities,
+ // just assume that it works and don't submit the entities.
+ if (!permanent) return 1;
+
node->type = type;
node->flags |= Ast_Flag_Array_Literal_Typed;
if (expr_count != type->Compound.count) return 0;
fori (i, 0, (i64) expr_count) {
- if (!type_check_or_auto_cast(&compound->exprs[i], type->Compound.types[i])) return 0;
+ if (!unify_node_and_type_(&compound->exprs[i], type->Compound.types[i], permanent)) return 0;
}
compound->type = type_build_compound_type(context.ast_alloc, compound);
else if (node->kind == Ast_Kind_If_Expression) {
AstIfExpression* if_expr = (AstIfExpression *) node;
- b32 true_success = type_check_or_auto_cast(&if_expr->true_expr, type);
- b32 false_success = type_check_or_auto_cast(&if_expr->false_expr, type);
+ b32 true_success = unify_node_and_type_(&if_expr->true_expr, type, permanent);
+ b32 false_success = unify_node_and_type_(&if_expr->false_expr, type, permanent);
if (true_success && false_success) {
if_expr->type = type;
}
else if (node->kind == Ast_Kind_Alias) {
AstAlias* alias = (AstAlias *) node;
- return type_check_or_auto_cast(&alias->alias, type);
+ return unify_node_and_type_(&alias->alias, type, permanent);
}
return 0;
AstIfExpression* if_expr = (AstIfExpression *) node;
Type* ltype = resolve_expression_type(if_expr->true_expr);
- type_check_or_auto_cast(&if_expr->false_expr, ltype);
+ unify_node_and_type(&if_expr->false_expr, ltype);
if_expr->type = ltype;
}
return Check_Success;
}
- if (!type_check_or_auto_cast(&retnode->expr, *expected_return_type)) {
+ if (!unify_node_and_type(&retnode->expr, *expected_return_type)) {
ERROR_(retnode->token->pos,
"Expected to return a value of type '%s', returning value of type '%s'.",
type_get_name(*expected_return_type),
continue;
}
- if (!type_check_or_auto_cast(value, resolved_expr_type)) {
+ if (!unify_node_and_type(value, resolved_expr_type)) {
OnyxToken* tkn = sc->block->token;
if ((*value)->token) tkn = (*value)->token;
}
if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done;
- if (!type_check_or_auto_cast(&arg_arr[arg_pos]->value, formal_params[arg_pos])) {
+ if (!unify_node_and_type(&arg_arr[arg_pos]->value, formal_params[arg_pos])) {
ERROR_(arg_arr[arg_pos]->token->pos,
"The procedure '%s' expects a value of type '%s' for %d%s parameter, got '%s'.",
get_function_name(callee),
}
case AS_Expecting_Typed_VA: {
+ if (variadic_type->id == any_type->id) call->va_kind = VA_Kind_Any;
if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done;
if (variadic_type->id == any_type->id) {
- call->va_kind = VA_Kind_Any;
-
resolve_expression_type(arg_arr[arg_pos]->value);
arg_arr[arg_pos]->va_kind = VA_Kind_Any;
break;
call->va_kind = VA_Kind_Typed;
- if (!type_check_or_auto_cast(&arg_arr[arg_pos]->value, variadic_type)) {
+ if (!unify_node_and_type(&arg_arr[arg_pos]->value, variadic_type)) {
onyx_report_error(arg_arr[arg_pos]->token->pos,
"The procedure '%s' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.",
get_function_name(callee),
}
}
- if (!type_check_or_auto_cast(&binop->right, binop->left->type)) {
+ if (!unify_node_and_type(&binop->right, binop->left->type)) {
ERROR_(binop->token->pos,
"Cannot assign value of type '%s' to a '%s'.",
node_get_type_name(binop->right),
b32 right_ac = node_is_auto_cast((AstNode *) binop->right);
if (left_ac && right_ac) ERROR(binop->token->pos, "Cannot have auto cast on both sides of binary operator.");
- else if (type_check_or_auto_cast(&binop->left, rtype));
- else if (type_check_or_auto_cast(&binop->right, ltype));
+ else if (unify_node_and_type(&binop->left, rtype));
+ else if (unify_node_and_type(&binop->right, ltype));
else {
ERROR_(binop->token->pos,
"Cannot compare '%s' to '%s'.",
// :UnaryFieldAccessIsGross
if (binop->left->kind == Ast_Kind_Unary_Field_Access || binop->right->kind == Ast_Kind_Unary_Field_Access) {
- if (type_check_or_auto_cast(&binop->left, binop->right->type));
- else if (type_check_or_auto_cast(&binop->right, binop->left->type));
+ if (unify_node_and_type(&binop->left, binop->right->type));
+ else if (unify_node_and_type(&binop->right, binop->left->type));
else {
report_bad_binaryop(binop);
return Check_Error;
if (left_ac && right_ac) {
ERROR(binop->token->pos, "Cannot have auto cast on both sides of binary operator.");
}
- else if (type_check_or_auto_cast(&binop->left, binop->right->type));
- else if (type_check_or_auto_cast(&binop->right, binop->left->type));
+ else if (unify_node_and_type(&binop->left, binop->right->type));
+ else if (unify_node_and_type(&binop->right, binop->left->type));
else {
ERROR_(binop->token->pos,
"Mismatched types for binary operation '%s'. left: '%s', right: '%s'.",
YIELD_((*actual)->token->pos, "Trying to resolve type of expression for member '%s'.", smem.name);
}
- if (!type_check_or_auto_cast(actual, formal)) {
+ if (!unify_node_and_type(actual, formal)) {
ERROR_(sl->token->pos,
"Mismatched types for %d%s member named '%s', expected '%s', got '%s'.",
i + 1, bh_num_suffix(i + 1),
al->flags &= ((*expr)->flags & Ast_Flag_Comptime) | (al->flags &~ Ast_Flag_Comptime);
- if (!type_check_or_auto_cast(expr, elem_type)) {
+ if (!unify_node_and_type(expr, elem_type)) {
ERROR_((*expr)->token->pos, "Mismatched types for value of in array, expected '%s', got '%s'.",
type_get_name(elem_type),
node_get_type_name(*expr));
StructMember smem;
type_lookup_member(expected_range_type, "low", &smem);
- if (!type_check_or_auto_cast(&range->low, smem.type)) {
+ if (!unify_node_and_type(&range->low, smem.type)) {
ERROR_(range->token->pos,
"Expected left side of range to be a 32-bit integer, got '%s'.",
node_get_type_name(range->low));
}
type_lookup_member(expected_range_type, "high", &smem);
- if (!type_check_or_auto_cast(&range->high, smem.type)) {
+ if (!unify_node_and_type(&range->high, smem.type)) {
ERROR_(range->token->pos,
"Expected right side of range to be a 32-bit integer, got '%s'.",
node_get_type_name(range->high));
CHECK(expression, &if_expr->true_expr);
CHECK(expression, &if_expr->false_expr);
- if (!type_check_or_auto_cast(&if_expr->cond, &basic_types[Basic_Kind_Bool])) {
+ if (!unify_node_and_type(&if_expr->cond, &basic_types[Basic_Kind_Bool])) {
ERROR_(if_expr->token->pos, "If-expression expected boolean for condition, got '%s'.",
type_get_name(if_expr->cond->type));
}
Type* code_type = type_build_from_ast(context.ast_alloc, builtin_code_type);
- if (!type_check_or_auto_cast(&insert->code_expr, code_type)) {
+ if (!unify_node_and_type(&insert->code_expr, code_type)) {
ERROR_(insert->token->pos, "#insert expected a value of type 'Code', got '%s'.",
type_get_name(insert->code_expr->type));
}
if ((*smem)->initial_value && *(*smem)->initial_value) {
CHECK(expression, (*smem)->initial_value);
- if (!type_check_or_auto_cast((*smem)->initial_value, (*smem)->type)) {
+ if (!unify_node_and_type((*smem)->initial_value, (*smem)->type)) {
ERROR_((*(*smem)->initial_value)->token->pos,
"Mismatched type for initial value, expected '%s', got '%s'.",
type_get_name((*smem)->type),
// when the default value is used as an argument and then has to be checked against
// the parameter type - brendanfh 2021/01/06
// if (param->default_value != NULL) {
- // if (!type_check_or_auto_cast(¶m->default_value, param->local->type)) {
+ // if (!unify_node_and_type(¶m->default_value, param->local->type)) {
// onyx_report_error(param->local->token->pos,
// "Expected default value of type '%s', was of type '%s'.",
// type_get_name(param->local->type),
if (memres->type != NULL) {
Type* memres_type = memres->type;
- if (!type_check_or_auto_cast(&memres->initial_value, memres_type)) {
+ if (!unify_node_and_type(&memres->initial_value, memres_type)) {
ERROR_(memres->token->pos,
"Cannot assign value of type '%s' to a '%s'.",
node_get_type_name(memres->initial_value),