diff options
| author | gingerBill <bill@gingerbill.org> | 2019-03-30 10:43:53 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2019-03-30 10:43:53 +0000 |
| commit | 7580ec494b144d85bf96af114d32fc60f0f8c0ad (patch) | |
| tree | 7d53c390c7f6017be2ab899ba94b5b6614c834cc /src/check_expr.cpp | |
| parent | a9b20c29b1ade46d82ab6c62dfcf9148d86daae0 (diff) | |
Disallow ambiguous singularly variadic polymorphic parameters #361
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 32 |
1 files changed, 30 insertions, 2 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) { |