Unsplat with named parameters was accidentally disallowed.

This commit is contained in:
Christoffer Lerno
2024-07-22 11:44:34 +02:00
parent 9584efd84c
commit 1bb76b1a49
4 changed files with 22 additions and 11 deletions

View File

@@ -50,6 +50,7 @@
- Constants defined by indexing into another constant could fail codegen.
- Stdlib nolibc code bugs fixed.
- Regression: duplicate symbols with static variable declared in macro #1248.
- Unsplat with named parameters was accidentally disallowed.
### Stdlib changes
- Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions.

View File

@@ -498,6 +498,11 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *
{
if (splat)
{
if (*splat)
{
PRINT_ERROR_HERE("'...' is only allowed on the last argument in a call.");
return false;
}
*splat = try_consume(c, TOKEN_ELLIPSIS);
}
ASSIGN_EXPR_OR_RET(expr, parse_expr(c), false);
@@ -510,8 +515,6 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *
if (tok_is(c, param_end)) return true;
if (splat && *splat)
{
PRINT_ERROR_HERE("'...' is only allowed on the last argument in a call.");
return false;
}
}
}

View File

@@ -1301,6 +1301,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
// 2. Loop through the parameters.
bool has_named = false;
bool found_splat = false;
for (unsigned i = 0; i < num_args; i++)
{
Expr *arg = args[i];
@@ -1340,7 +1341,13 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
actual_args[index] = arg->designator_expr.value;
continue;
}
if (*vararg_splat_ref)
{
if (no_match_ref) goto NO_MATCH_REF;
RETURN_SEMA_FUNC_ERROR(callee->definition, arg,
"This looks like an argument after a splatted variable, which "
"isn't allowed. Did you add too many arguments?");
}
if (has_named)
{
RETURN_SEMA_FUNC_ERROR(callee->definition, args[i - 1],
@@ -1365,14 +1372,6 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
// 11a. Look if we did a splat
if (call->call_expr.splat_vararg)
{
// 11b. Is this the last argument, or did we get some before the splat?
if (i < num_args - 1)
{
if (no_match_ref) goto NO_MATCH_REF;
RETURN_SEMA_FUNC_ERROR(callee->definition, arg,
"This looks like a variable argument before an splatted variable which "
"isn't allowed. Did you add too many arguments?");
}
*vararg_splat_ref = arg;
continue;
}

View File

@@ -0,0 +1,8 @@
fn void test(int... abc, int a)
{ }
fn void main()
{
int[] b = { 1, 2 };
test(...b, .a = 123);
}