Typecheck method promotion for interfaces
This commit is contained in:
parent
3481042259
commit
3c50c182a8
10
compile.c
10
compile.c
@ -56,6 +56,11 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (needed->tag == FunctionType && actual->tag == FunctionType) {
|
||||
*code = CORD_all("(", compile_type(env, needed), ")", *code);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1710,7 +1715,10 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
binding_t *b = get_namespace_binding(env, impl, field->name);
|
||||
if (b) {
|
||||
// TODO: typecheck implementation!
|
||||
c = CORD_all(c, ", (void*)", b->code);
|
||||
CORD field_code = b->code;
|
||||
if (!promote(env, &field_code, b->type, field->type))
|
||||
code_err(ast, "I can't promote the method '%s' from %T to %T", field->name, b->type, field->type);
|
||||
c = CORD_all(c, ", ", field_code);
|
||||
} else {
|
||||
type_t *member_t = get_field_type(impl_t, field->name);
|
||||
if (!member_t)
|
||||
|
13
types.c
13
types.c
@ -270,6 +270,19 @@ bool can_promote(type_t *actual, type_t *needed)
|
||||
if (needed->tag == ClosureType && actual->tag == FunctionType)
|
||||
return type_eq(actual, Match(needed, ClosureType)->fn);
|
||||
|
||||
if (actual->tag == FunctionType && needed->tag == FunctionType) {
|
||||
for (arg_t *actual_arg = Match(actual, FunctionType)->args, *needed_arg = Match(needed, FunctionType)->args;
|
||||
actual_arg || needed_arg; actual_arg = actual_arg->next, needed_arg = needed_arg->next) {
|
||||
if (!actual_arg || !needed_arg) return false;
|
||||
if (type_eq(actual_arg->type, needed_arg->type)) continue;
|
||||
if (actual_arg->type->tag == PointerType && needed_arg->type->tag == PointerType
|
||||
&& can_promote(actual_arg->type, needed_arg->type))
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user