aboutsummaryrefslogtreecommitdiff
path: root/src/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile.c')
-rw-r--r--src/compile.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/compile.c b/src/compile.c
index eb250d74..2b714acf 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -2123,6 +2123,7 @@ Text_t compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bo
Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t)
{
+ assert(!is_incomplete_type(t));
if (ast->tag == Int && is_numeric_type(non_optional(t))) {
return compile_int_to_type(env, ast, t);
} else if (ast->tag == Num && t->tag == NumType) {
@@ -2180,10 +2181,20 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t)
if (t->tag == PointerType && Match(t, PointerType)->is_stack && actual->tag != PointerType)
return Texts("stack(", compile_to_type(env, ast, Match(t, PointerType)->pointed), ")");
- Text_t code = compile(env, ast);
- if (!promote(env, ast, &code, actual, t))
- code_err(ast, "I expected a ", type_to_str(t), " here, but this is a ", type_to_str(actual));
- return code;
+ if (!is_incomplete_type(actual)) {
+ Text_t code = compile(env, ast);
+ if (promote(env, ast, &code, actual, t))
+ return code;
+ }
+
+ arg_ast_t *constructor_args = new(arg_ast_t, .value=ast);
+ binding_t *constructor = get_constructor(env, t, constructor_args, true);
+ if (constructor) {
+ arg_t *arg_spec = Match(constructor->type, FunctionType)->args;
+ return Texts(constructor->code, "(", compile_arguments(env, ast, arg_spec, constructor_args), ")");
+ }
+
+ code_err(ast, "I expected a ", type_to_str(t), " here, but this is a ", type_to_str(actual));
}
Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type)
@@ -2771,7 +2782,7 @@ Text_t compile(env_t *env, ast_t *ast)
binding_t *b = get_namespace_binding(env, value, "negated");
if (b && b->type->tag == FunctionType) {
DeclareMatch(fn, b->type, FunctionType);
- if (fn->args && can_promote(t, get_arg_type(env, fn->args)))
+ if (fn->args && can_compile_to_type(env, value, get_arg_type(env, fn->args)))
return Texts(b->code, "(", compile_arguments(env, ast, fn->args, new(arg_ast_t, .value=value)), ")");
}
@@ -2796,7 +2807,7 @@ Text_t compile(env_t *env, ast_t *ast)
binding_t *b = get_namespace_binding(env, value, "negative");
if (b && b->type->tag == FunctionType) {
DeclareMatch(fn, b->type, FunctionType);
- if (fn->args && can_promote(t, get_arg_type(env, fn->args)))
+ if (fn->args && can_compile_to_type(env, value, get_arg_type(env, fn->args)))
return Texts(b->code, "(", compile_arguments(env, ast, fn->args, new(arg_ast_t, .value=value)), ")");
}