mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow doc comments on individual struct members, faultdefs and enum values #2427.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
41
test/test_suite/errors/contracts_in_defs.c3
Normal file
41
test/test_suite/errors/contracts_in_defs.c3
Normal 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()
|
||||
{}
|
||||
Reference in New Issue
Block a user