diff options
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2f39a6b77..1fa0117ac 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -166,6 +166,13 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { Type *src = base_type(s); Type *dst = base_type(type); + if (is_type_untyped_undef(src)) { + if (type_has_undef(dst)) { + return 1; + } + return -1; + } + if (is_type_untyped_nil(src)) { if (type_has_nil(dst)) { return 1; @@ -328,6 +335,11 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n operand->mode = Addressing_Invalid; return; } + if (type == NULL && is_type_untyped_undef(operand->type)) { + error(operand->expr, "Use of --- in %.*s", LIT(context_name)); + operand->mode = Addressing_Invalid; + return; + } target_type = default_type(operand->type); if (type != NULL && !is_type_any(type)) { GB_ASSERT_MSG(is_type_typed(target_type), "%s", type_to_string(type)); @@ -3366,7 +3378,9 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level default: - if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) { + if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) { + target_type = t_untyped_undef; + } else if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) { operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); return; @@ -5043,6 +5057,9 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } else { // NOTE(bill): Generate the procedure type for this generic instance // TODO(bill): Clean this shit up! + + ProcedureInfo proc_info = {}; + if (pt->is_generic) { GB_ASSERT(entity != NULL); DeclInfo *old_decl = decl_info_of_entity(&c->info, entity); @@ -5091,8 +5108,13 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { add_entity_and_decl_info(c, ident, gen_entity, d); gen_entity->scope = entity->scope; add_entity_use(c, ident, gen_entity); - check_procedure_later(c, c->curr_ast_file, token, d, final_proc_type, pd->body, tags); + proc_info.file = c->curr_ast_file; + proc_info.token = token; + proc_info.decl = d; + proc_info.type = final_proc_type; + proc_info.body = pd->body; + proc_info.tags = tags; if (found) { array_add(found, gen_entity); @@ -5107,7 +5129,6 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { GB_ASSERT(gen_entity != NULL); } - TypeProc *pt = &final_proc_type->Proc; GB_ASSERT(pt->params != NULL); @@ -5124,6 +5145,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { continue; } else if (o.mode != Addressing_Type) { error(o.expr, "Expected a type for the argument"); + err = CallArgumentError_WrongTypes; } if (are_types_identical(e->type, o.type)) { @@ -5180,6 +5202,10 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { score += s; } } + + if (gen_entity != NULL && err == CallArgumentError_None) { + check_procedure_later(c, proc_info); + } } } @@ -5748,6 +5774,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t return kind; } + init_preload(c); o->mode = Addressing_Value; o->type = t_context; break; @@ -5761,6 +5788,11 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t check_ident(c, o, node, NULL, type_hint, false); case_end; + case_ast_node(u, Undef, node); + o->mode = Addressing_Value; + o->type = t_untyped_undef; + case_end; + case_ast_node(bl, BasicLit, node); Type *t = t_invalid; |