From 70da1f748a3d3d7195830c6e18967d875bff6c2b Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 14 Jan 2025 23:06:17 +0100 Subject: [PATCH] Enum associated declarations accidentally allowed declaration in function style. #1841 --- releasenotes.md | 1 + src/compiler/parse_global.c | 20 ++++++++++++++++--- .../enum_with_associated_value_decl.c3 | 7 +++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test/test_suite/enumerations/enum_with_associated_value_decl.c3 diff --git a/releasenotes.md b/releasenotes.md index f10e73289..2615194b4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -213,6 +213,7 @@ - @tag on macros cannot be retrieved with tagof #1582 - Taking the $typeof of a wildcard optional returns `void!`. - Fix bug with enums with jump tables #1840. +- Enum associated declarations accidentally allowed declaration in function style. #1841 ### Stdlib changes - Remove unintended print of `char[]` as String diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 55b0056cd..e2868ac2f 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -2331,17 +2331,31 @@ static inline Decl *parse_enum_declaration(ParseContext *c) if (!parse_attributes_for_global(c, enum_const)) return poisoned_decl; if (try_consume(c, TOKEN_EQ)) { + Expr **args = NULL; if (expected_parameters == 1 || !tok_is(c, TOKEN_LBRACE)) { ASSIGN_EXPR_OR_RET(Expr *single, parse_expr(c), poisoned_decl); - vec_add(enum_const->enum_constant.args, single); + vec_add(args, single); } else { CONSUME_OR_RET(TOKEN_LBRACE, poisoned_decl); - if (!parse_arg_list(c, &enum_const->enum_constant.args, TOKEN_RBRACE, 0)) return poisoned_decl; - CONSUME_OR_RET(TOKEN_RBRACE, poisoned_decl); + while (1) + { + if (try_consume(c, TOKEN_RBRACE)) break; + ASSIGN_EXPR_OR_RET(Expr *arg, parse_expr(c), poisoned_decl); + vec_add(args, arg); + if (tok_is(c, TOKEN_COLON) && arg->expr_kind == EXPR_IDENTIFIER) + { + print_error_at(extend_span_with_token(arg->span, c->span), + "This looks like a designated initializer, but that style of declaration " + "is not supported for declaring enum associated values."); + return poisoned_decl; + } + if (try_consume(c, TOKEN_COMMA)) continue; + } } + enum_const->enum_constant.args = args; } vec_add(decl->enums.values, enum_const); // Allow trailing ',' diff --git a/test/test_suite/enumerations/enum_with_associated_value_decl.c3 b/test/test_suite/enumerations/enum_with_associated_value_decl.c3 new file mode 100644 index 000000000..485fc9489 --- /dev/null +++ b/test/test_suite/enumerations/enum_with_associated_value_decl.c3 @@ -0,0 +1,7 @@ +enum Test2 : (usz a, usz b) { + FOO = {4, 5, }, +} + +enum Test : (usz a, usz b) { + FOO = {a: 1, b: 1}, // #error: This looks like +} \ No newline at end of file