diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_decl.cpp | 14 | ||||
| -rw-r--r-- | src/check_expr.cpp | 36 | ||||
| -rw-r--r-- | src/checker.cpp | 5 |
3 files changed, 35 insertions, 20 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp index d3f82b1d3..8d375d548 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -45,6 +45,11 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex } t = default_type(t); } + if (is_type_gen_proc(t)) { + error(e->token, "Invalid use of a generic procedure in %.*s", LIT(context_name)); + e->type = t_invalid; + return NULL; + } if (is_type_bit_field_value(t)) { t = default_bit_field_value_type(t); } @@ -361,7 +366,12 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { if (pt->is_generic) { if (pd->body == NULL) { - error(e->token, "Generic procedures must have a body"); + error(e->token, "Polymorphic procedures must have a body"); + } + + if (is_foreign) { + error(e->token, "A foreign procedures cannot be a polymorphic"); + return; } } @@ -387,6 +397,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { pt->require_results = is_require_results; } + + if (is_foreign) { String name = e->token.string; if (pd->link_name.len > 0) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f6b2cf5c1..2f3b1630a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -12,7 +12,6 @@ enum CallArgumentError { CallArgumentError_ParameterNotFound, CallArgumentError_ParameterMissing, CallArgumentError_DuplicateParameter, - CallArgumentError_GenericProcedureNotSupported, }; enum CallArgumentErrorMode { @@ -285,9 +284,11 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { if (is_type_any(dst)) { - // NOTE(bill): Anything can cast to `Any` - add_type_info_type(c, s); - return 10; + if (!is_type_gen_proc(src)) { + // NOTE(bill): Anything can cast to `Any` + add_type_info_type(c, s); + return 10; + } } @@ -4241,13 +4242,17 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id case BuiltinProc_type_of: - // proc type_of_val(val: Type) -> type(Type) - check_assignment(c, operand, NULL, str_lit("argument of `type_of_val`")); + // proc type_of(val: Type) -> type(Type) + check_assignment(c, operand, NULL, str_lit("argument of `type_of`")); if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) { return false; } - if (operand->type == NULL || operand->type == t_invalid || is_type_gen_proc(operand->type)) { - error(operand->expr, "Invalid argument to `type_of_val`"); + if (operand->type == NULL || operand->type == t_invalid) { + error(operand->expr, "Invalid argument to `type_of`"); + return false; + } + if (is_type_gen_proc(operand->type)) { + error(operand->expr, "`type_of` of generic procedure cannot be determined"); return false; } operand->mode = Addressing_Type; @@ -4999,10 +5004,10 @@ Entity *find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Type *final_proc_type = make_type_proc(c->allocator, c->context.scope, NULL, 0, NULL, 0, false, pt->calling_convention); check_procedure_type(c, final_proc_type, pt->node, operands); - auto *found = map_get(&c->info.gen_procs, hash_pointer(base_entity->identifier)); - if (found) { - for_array(i, *found) { - Entity *other = (*found)[i]; + auto *found_gen_procs = map_get(&c->info.gen_procs, hash_pointer(base_entity->identifier)); + if (found_gen_procs) { + for_array(i, *found_gen_procs) { + Entity *other = (*found_gen_procs)[i]; if (are_types_identical(other->type, final_proc_type)) { // NOTE(bill): This scope is not needed any more, destroy it destroy_scope(scope); @@ -5041,13 +5046,13 @@ Entity *find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, proc_info.body = pd->body; proc_info.tags = tags; - if (found) { - array_add(found, entity); + if (found_gen_procs) { + array_add(found_gen_procs, entity); } else { Array<Entity *> array = {}; array_init(&array, heap_allocator()); array_add(&array, entity); - map_set(&c->info.gen_procs, hash_pointer(entity->identifier), array); + map_set(&c->info.gen_procs, hash_pointer(base_entity->identifier), array); } GB_ASSERT(entity != NULL); @@ -5373,7 +5378,6 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { Entity *gen_entity = NULL; if (pt->is_generic && err == CallArgumentError_None) { - // err = CallArgumentError_GenericProcedureNotSupported; ProcedureInfo proc_info = {}; gen_entity = find_or_generate_polymorphic_procedure(c, entity, &ordered_operands, &proc_info); if (gen_entity != NULL) { diff --git a/src/checker.cpp b/src/checker.cpp index 7d717e7cb..051020ae6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -87,7 +87,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("size_of"), 1, false, Expr_Expr}, {STR_LIT("align_of"), 1, false, Expr_Expr}, {STR_LIT("offset_of"), 2, false, Expr_Expr}, - {STR_LIT("type_of_val"), 1, false, Expr_Expr}, + {STR_LIT("type_of"), 1, false, Expr_Expr}, {STR_LIT("type_info"), 1, false, Expr_Expr}, {STR_LIT("compile_assert"), 1, false, Expr_Expr}, @@ -1456,7 +1456,7 @@ void check_procedure_overloading(Checker *c, Entity *e) { TypeProc *ptq = &base_type(q->type)->Proc; if (ptq->is_generic) { q->type = t_invalid; - error(q->token, "Generic procedure `%.*s` cannot be overloaded", LIT(name)); + error(q->token, "Polymorphic procedure `%.*s` cannot be overloaded", LIT(name)); continue; } } @@ -2269,7 +2269,6 @@ void check_parsed_files(Checker *c) { if (pi->decl->gen_proc_type == NULL) { continue; } - // gb_printf_err("Generic procedure `%.*s` -> %s\n", LIT(pi->token.string), type_to_string(pi->decl->gen_proc_type)); } add_curr_ast_file(c, pi->file); |