aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-02-14 21:46:39 +0000
committergingerBill <bill@gingerbill.org>2018-02-14 21:46:39 +0000
commit6a85546b761b67fa012a2cd49e32b2211bf02971 (patch)
tree94cf871608248e467280490bf570199061792f7b /src
parent2e92d0c821a386ed67389e6b6cb932f2a697a445 (diff)
Fix #187
Diffstat (limited to 'src')
-rw-r--r--src/check_type.cpp40
-rw-r--r--src/checker.hpp1
-rw-r--r--src/tokenizer.cpp11
-rw-r--r--src/types.cpp8
4 files changed, 51 insertions, 9 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 46399f7f1..47e27c27d 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -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);
diff --git a/src/checker.hpp b/src/checker.hpp
index 0e453c91d..bb8a11658 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -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;
};
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index d19024026..404b4cea6 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -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);
}
diff --git a/src/types.cpp b/src/types.cpp
index c40c076f1..2dcd05361 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -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) {