diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -733,8 +733,17 @@ static usize min(usize a, usize b) { return a < b ? a : b; } +static bool is_c_pointer_compatible(VariableType *self) { + return self->variable_type_flags & (VARIABLE_TYPE_FLAG_OPTIONAL | VARIABLE_TYPE_FLAG_BORROW); +} + +static bool is_type_compatible_with(AstResolvedType *self, AstResolvedType *other, AstCompilerContext *context) { + return self->value.data == &context->compiler->default_types.str->lhs_expr && + other->value.data == context->compiler->default_types.c_char && is_c_pointer_compatible(&other->value.lhs_expr->type); +} + static bool resolve_data_type_equals(AstResolvedType *self, AstResolvedType *other) { - return self->type == other->type && self->value.data == other->value.data; + return self->value.data == other->value.data; } static bool function_parameter_is_vararg(FunctionParameter *self, AstCompilerContext *context) { @@ -742,6 +751,12 @@ static bool function_parameter_is_vararg(FunctionParameter *self, AstCompilerCon return self->resolve_data.type.value.data == &vararg_type->lhs_expr; } +static bool is_function_arg_compatible_with_parameter(AstResolvedType *arg, FunctionParameter *param, AstCompilerContext *context) { + return resolve_data_type_equals(arg, ¶m->resolve_data.type) || + is_type_compatible_with(arg, ¶m->resolve_data.type, context) || + function_parameter_is_vararg(param, context); +} + static void verify_func_call_matches_func_signature(FunctionCall *func_call, FunctionSignature *func_sig, AstCompilerContext *context) { Ast **arg = buffer_begin(&func_call->args); Ast **arg_end = buffer_end(&func_call->args); @@ -755,7 +770,7 @@ static void verify_func_call_matches_func_signature(FunctionCall *func_call, Fun usize num_check = min(num_args, num_params); usize i = 0; for(; i < num_check; ++i) { - if(!resolve_data_type_equals(&(*arg)->resolve_data.type, &func_param->resolve_data.type) && !function_parameter_is_vararg(func_param, context)) { + if(!is_function_arg_compatible_with_parameter(&(*arg)->resolve_data.type, func_param, context)) { BufferView arg_name = ast_resolved_type_get_name(&(*arg)->resolve_data.type); BufferView param_name = ast_resolved_type_get_name(&func_param->resolve_data.type); compiler_print_error(context->compiler, func_call->func.name.data, |