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/check_expr.cpp | |
| parent | 76a2807b56a9c0a40c66915d5b77cf537ad376f2 (diff) | |
| parent | dd9113786c4e7b18e894bd3ceee94cdf08ac6037 (diff) | |
Merge branch 'master' of github.com:odin-lang/Odin
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) { |