This commit is contained in:
gingerBill
2018-02-14 21:46:39 +00:00
parent 2e92d0c821
commit 6a85546b76
4 changed files with 51 additions and 9 deletions

View File

@@ -920,6 +920,7 @@ bool check_type_specialization_to(Checker *c, Type *specialization, Type *type,
}
// gb_printf_err("#1 %s %s\n", type_to_string(type), type_to_string(specialization));
if (t->kind == Type_Struct) {
if (t->Struct.polymorphic_parent == specialization) {
return true;
}
@@ -1937,24 +1938,31 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
Operand o = {};
check_ident(c, &o, e, named_type, nullptr, false);
gbString err_str;
gbString err_str = nullptr;
defer (gb_string_free(err_str));
switch (o.mode) {
case Addressing_Invalid:
break;
case Addressing_Type:
case Addressing_Type: {
*type = o.type;
if (!c->context.in_polymorphic_specialization) {
if (is_type_polymorphic_struct_unspecialized(o.type)) {
err_str = expr_to_string(e);
error(e, "Invalid use of a non-specialized polymorphic type '%s'", err_str);
}
}
return true;
}
case Addressing_NoValue:
err_str = expr_to_string(e);
error(e, "'%s' used as a type", err_str);
gb_string_free(err_str);
break;
default:
err_str = expr_to_string(e);
error(e, "'%s' used as a type when not a type", err_str);
gb_string_free(err_str);
break;
}
case_end;
@@ -1980,6 +1988,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
Token token = ident->Ident.token;
Type *specific = nullptr;
if (pt->specialization != nullptr) {
auto prev_ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = prev_ips);
c->context.in_polymorphic_specialization = true;
AstNode *s = pt->specialization;
specific = check_type(c, s);
if (false && !is_type_polymorphic_struct(specific)) {
@@ -2088,6 +2100,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
case_end;
case_ast_node(st, StructType, e);
bool ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = ips);
c->context.in_polymorphic_specialization = false;
*type = make_type_struct(c->allocator);
set_base_type(named_type, *type);
check_open_scope(c, e);
@@ -2098,6 +2114,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
case_end;
case_ast_node(ut, UnionType, e);
bool ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = ips);
c->context.in_polymorphic_specialization = false;
*type = make_type_union(c->allocator);
set_base_type(named_type, *type);
check_open_scope(c, e);
@@ -2108,6 +2128,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
case_end;
case_ast_node(et, EnumType, e);
bool ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = ips);
c->context.in_polymorphic_specialization = false;
*type = make_type_enum(c->allocator);
set_base_type(named_type, *type);
check_open_scope(c, e);
@@ -2127,6 +2151,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
case_end;
case_ast_node(pt, ProcType, e);
bool ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = ips);
c->context.in_polymorphic_specialization = false;
*type = alloc_type(c->allocator, Type_Proc);
set_base_type(named_type, *type);
check_open_scope(c, e);
@@ -2136,6 +2164,10 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
case_end;
case_ast_node(mt, MapType, e);
bool ips = c->context.in_polymorphic_specialization;
defer (c->context.in_polymorphic_specialization = ips);
c->context.in_polymorphic_specialization = false;
*type = alloc_type(c->allocator, Type_Map);
set_base_type(named_type, *type);
check_map_type(c, *type, e);

View File

@@ -285,6 +285,7 @@ struct CheckerContext {
bool collect_delayed_decls;
bool allow_polymorphic_types;
bool no_polymorphic_errors;
bool in_polymorphic_specialization;
Scope * polymorphic_scope;
};

View File

@@ -200,7 +200,9 @@ void warning_va(Token token, char *fmt, va_list va) {
gb_mutex_lock(&global_error_collector.mutex);
global_error_collector.warning_count++;
// NOTE(bill): Duplicate error, skip it
if (global_error_collector.prev != token.pos) {
if (token.pos.line == 0) {
gb_printf_err("Error: %s\n", gb_bprintf_va(fmt, va));
} else if (global_error_collector.prev != token.pos) {
global_error_collector.prev = token.pos;
gb_printf_err("%.*s(%td:%td) Warning: %s\n",
LIT(token.pos.file), token.pos.line, token.pos.column,
@@ -214,15 +216,14 @@ void error_va(Token token, char *fmt, va_list va) {
gb_mutex_lock(&global_error_collector.mutex);
global_error_collector.count++;
// NOTE(bill): Duplicate error, skip it
if (global_error_collector.prev != token.pos) {
if (token.pos.line == 0) {
gb_printf_err("Error: %s\n", gb_bprintf_va(fmt, va));
} else if (global_error_collector.prev != token.pos) {
global_error_collector.prev = token.pos;
gb_printf_err("%.*s(%td:%td) %s\n",
LIT(token.pos.file), token.pos.line, token.pos.column,
gb_bprintf_va(fmt, va));
} else if (token.pos.line == 0) {
gb_printf_err("Error: %s\n", gb_bprintf_va(fmt, va));
}
gb_mutex_unlock(&global_error_collector.mutex);
}

View File

@@ -954,6 +954,14 @@ bool is_type_polymorphic_struct_specialized(Type *t) {
return false;
}
bool is_type_polymorphic_struct_unspecialized(Type *t) {
t = base_type(t);
if (t->kind == Type_Struct) {
return t->Struct.is_polymorphic && !t->Struct.is_poly_specialized;
}
return false;
}
bool is_type_polymorphic(Type *t) {
switch (t->kind) {