diff options
| author | Kevin Watters <kevinwatters@gmail.com> | 2019-03-31 12:03:22 -0400 |
|---|---|---|
| committer | Kevin Watters <kevinwatters@gmail.com> | 2019-03-31 12:03:22 -0400 |
| commit | 381fbd3dafed820583c97f176d2694b21358d178 (patch) | |
| tree | 071c9b572b655ca2ca5597a7252eebe228670a02 /src | |
| parent | 76a2807b56a9c0a40c66915d5b77cf537ad376f2 (diff) | |
| parent | dd9113786c4e7b18e894bd3ceee94cdf08ac6037 (diff) | |
Merge branch 'master' of github.com:odin-lang/Odin
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.cpp | 32 | ||||
| -rw-r--r-- | src/check_type.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 8 | ||||
| -rw-r--r-- | src/parser.cpp | 5 |
4 files changed, 44 insertions, 7 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index af3ef01b4..d10dd33c7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5,6 +5,7 @@ enum CallArgumentError { CallArgumentError_NonVariadicExpand, CallArgumentError_VariadicTuple, CallArgumentError_MultipleVariadicExpand, + CallArgumentError_AmbiguousPolymorphicVariadic, CallArgumentError_ArgumentCount, CallArgumentError_TooFewArguments, CallArgumentError_TooManyArguments, @@ -4492,6 +4493,15 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { err = CallArgumentError_NonVariadicExpand; } else if (operands.count == 0 && param_count_excluding_defaults == 0) { err = CallArgumentError_None; + + if (variadic) { + GB_ASSERT(param_tuple != nullptr && param_tuple->variables.count > 0); + Type *t = param_tuple->variables[0]->type; + if (is_type_polymorphic(t)) { + error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input"); + err = CallArgumentError_AmbiguousPolymorphicVariadic; + } + } } else { i32 error_code = 0; if (operands.count < param_count_excluding_defaults) { @@ -4583,6 +4593,12 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { GB_ASSERT(is_type_slice(slice)); Type *elem = base_type(slice)->Slice.elem; Type *t = elem; + + if (is_type_polymorphic(t)) { + error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input"); + err = CallArgumentError_AmbiguousPolymorphicVariadic; + } + for (; operand_index < operands.count; operand_index++) { Operand o = operands[operand_index]; if (vari_expand) { @@ -4761,11 +4777,24 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { for (isize i = 0; i < param_count; i++) { + Entity *e = pt->params->Tuple.variables[i]; Operand *o = &ordered_operands[i]; + bool param_is_variadic = pt->variadic && pt->variadic_index == i; + + if (o->mode == Addressing_Invalid) { + if (param_is_variadic) { + Type *slice = e->type; + GB_ASSERT(is_type_slice(slice)); + Type *elem = base_type(slice)->Slice.elem; + if (is_type_polymorphic(elem)) { + error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input"); + err = CallArgumentError_AmbiguousPolymorphicVariadic; + return err; + } + } continue; } - Entity *e = pt->params->Tuple.variables[i]; if (e->kind == Entity_TypeName) { GB_ASSERT(pt->is_polymorphic); @@ -4782,7 +4811,6 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { } } else { i64 s = 0; - bool param_is_variadic = pt->variadic && pt->variadic_index == i; if (!check_is_assignable_to_with_score(c, o, e->type, &s, param_is_variadic)) { bool ok = false; if (e->flags & EntityFlag_AutoCast) { diff --git a/src/check_type.cpp b/src/check_type.cpp index 1721ed881..22cd409ee 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1570,6 +1570,12 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is if (operands != nullptr && variables.count < operands->count) { Operand op = (*operands)[variables.count]; + if (op.expr == nullptr) { + // NOTE(bill): 2019-03-30 + // This is just to add the error message to determine_type_from_polymorphic which + // depends on valid position information + op.expr = _params; + } if (is_type_polymorphic_type) { type = determine_type_from_polymorphic(ctx, type, op); if (type == t_invalid) { diff --git a/src/ir.cpp b/src/ir.cpp index b5ff56b93..b486a6309 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1433,11 +1433,13 @@ irValue *ir_value_procedure(irModule *m, Entity *entity, Type *type, Ast *type_e irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefix, i64 id) { gbAllocator a = ir_allocator(); Token token = {Token_Ident}; - isize name_len = prefix.len + 10; + isize name_len = prefix.len + 1 + 20; - char *text = gb_alloc_array(a, char, name_len); + auto suffix_id = cast(unsigned long long)id; + char *text = gb_alloc_array(a, char, name_len+1); gb_snprintf(text, name_len, - "%.*s-%llx", LIT(prefix), cast(unsigned long long)id); + "%.*s-%llu", LIT(prefix), suffix_id); + text[name_len] = 0; String s = make_string_c(text); diff --git a/src/parser.cpp b/src/parser.cpp index 2eee82e22..12b7edb01 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3024,6 +3024,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi isize total_name_count = 0; bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis; bool seen_ellipsis = false; + bool is_signature = (allowed_flags & FieldFlag_Signature) == FieldFlag_Signature; while (f->curr_token.kind != follow && f->curr_token.kind != Token_Colon && @@ -3064,7 +3065,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi if (f->curr_token.kind != Token_Eq) { type = parse_var_type(f, allow_ellipsis, allow_typeid_token); Ast *tt = unparen_expr(type); - if (!any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { + if (is_signature && !any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { syntax_error(type, "Specialization of typeid is not allowed without polymorphic names"); } } @@ -3121,7 +3122,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi if (f->curr_token.kind != Token_Eq) { type = parse_var_type(f, allow_ellipsis, allow_typeid_token); Ast *tt = unparen_expr(type); - if (!any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { + if (is_signature && !any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) { syntax_error(type, "Specialization of typeid is not allowed without polymorphic names"); } } |