mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-24 03:46:40 +00:00
Fix #187
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user