Allow doc comments on individual struct members, faultdefs and enum values #2427.

This commit is contained in:
Christoffer Lerno
2025-09-06 16:18:33 +02:00
parent 95375a2591
commit bd9bc118db
3 changed files with 61 additions and 1 deletions

View File

@@ -56,6 +56,7 @@
- `$defined(#hash)` will not check the internal expression, just that `#hash` exists. Use `$defined((void)#hash)` for the old behaviour.
- Added optional macro arguments using `macro foo(int x = ...)` which can be checked using `$defined(x)`.
- Add compile time ternary `$val ??? <expr> : <expr>`.
- Allow doc comments on individual struct members, faultdefs and enum values #2427.
### Fixes
- List.remove_at would incorrectly trigger ASAN.

View File

@@ -1728,7 +1728,22 @@ static inline bool parse_fn_parameter_list(ParseContext *c, Signature *signature
// --- Parse types
static bool parse_element_contract(ParseContext *c, const char *error)
{
AstId contracts = 0;
if (!parse_contracts(c, &contracts)) return false;
if (!contracts) return true;
Ast *ast = astptr(contracts);
while (ast)
{
if (ast->ast_kind != AST_CONTRACT || ast->contract_stmt.kind != CONTRACT_COMMENT)
{
RETURN_PRINT_ERROR_AT(false, ast, "No constraints are allowed on %s.", error);
}
ast = astptrzero(ast->next);
}
return true;
}
/**
* Expect pointer to after '{'
*
@@ -1754,6 +1769,7 @@ static bool parse_struct_body(ParseContext *c, Decl *parent)
ArrayIndex index = 0;
while (!tok_is(c, TOKEN_RBRACE))
{
if (!parse_element_contract(c, "struct/union members")) return decl_poison(parent);
TokenType token_type = c->tok;
if (token_type == TOKEN_STRUCT || token_type == TOKEN_UNION || token_type == TOKEN_BITSTRUCT)
{
@@ -2476,6 +2492,7 @@ static inline Decl *parse_macro_declaration(ParseContext *c, AstId docs)
static inline Decl *parse_fault(ParseContext *c)
{
if (!parse_element_contract(c, "faults")) return poisoned_decl;
Decl *decl = decl_new(DECL_FAULT, symstr(c), c->span);
if (!consume_const_name(c, "fault")) return poisoned_decl;
if (!parse_attributes_for_global(c, decl)) return poisoned_decl;
@@ -2556,6 +2573,7 @@ static bool parse_enum_values(ParseContext *c, Decl*** values_ref, Visibility vi
Decl **values = NULL;
while (!try_consume(c, TOKEN_RBRACE))
{
if (!parse_element_contract(c, "enum values")) return false;
Decl *enum_const = decl_new(DECL_ENUM_CONSTANT, symstr(c), c->span);
if (is_const_enum) enum_const->enum_constant.is_raw = is_const_enum;
enum_const->visibility = visibility;

View File

@@ -0,0 +1,41 @@
module test;
import std;
struct Foo
{
<* hello *>
int a;
<* test *>
union
{
<* test2 *>
int b;
}
struct foo
{
<* baz *>
int g;
}
}
faultdef <* hello *> FOO;
enum Abc
{
<* test *>
XYZ
}
faultdef <* @require a > 0 *> FOO2; // #error: No constraints are allowed on faults
enum Abc2
{
<* @require a > 0 *> // #error: No constraints are allowed on enum values
XYZ
}
struct Test
{
<* @require a > 0 *> // #error: No constraints are allowed on struct/union members
int a;
}
fn void main()
{}