astgen: add decltest support and within_fn flag in testDecl/fnDecl
Port two missing features from upstream AstGen.zig: 1. Handle identifier-named tests (decltest): when the token after `test` is an identifier, set decl_id to DECL_ID_DECLTEST and record the identifier string as the test name. Upstream performs full scope resolution for validation which is skipped here. 2. Add `within_fn` field to AstGenCtx (mirrors AstGen.within_fn). Save, set to true, and restore in both testDecl and fnDecl. This flag propagates to maybe_generic on namespace scopes for container declarations inside function/test bodies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
20
astgen.c
20
astgen.c
@@ -113,6 +113,7 @@ typedef struct {
|
|||||||
uint32_t nodes_need_rl_len;
|
uint32_t nodes_need_rl_len;
|
||||||
uint32_t nodes_need_rl_cap;
|
uint32_t nodes_need_rl_cap;
|
||||||
bool has_compile_errors;
|
bool has_compile_errors;
|
||||||
|
bool within_fn; // AstGen.zig:49
|
||||||
} AstGenCtx;
|
} AstGenCtx;
|
||||||
|
|
||||||
static void setCompileError(AstGenCtx* ag, const char* where, int line) {
|
static void setCompileError(AstGenCtx* ag, const char* where, int line) {
|
||||||
@@ -8065,8 +8066,13 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts,
|
|||||||
uint32_t name_len;
|
uint32_t name_len;
|
||||||
strLitAsString(ag, test_name_token, &test_name, &name_len);
|
strLitAsString(ag, test_name_token, &test_name, &name_len);
|
||||||
decl_id = DECL_ID_TEST;
|
decl_id = DECL_ID_TEST;
|
||||||
|
} else if (tree->tokens.tags[test_name_token] == TOKEN_IDENTIFIER) {
|
||||||
|
// Identifier test name (decltest) (AstGen.zig:4763-4834).
|
||||||
|
// Upstream performs full scope resolution for validation; we skip
|
||||||
|
// the validation and just record the identifier as the test name.
|
||||||
|
test_name = identAsString(ag, test_name_token);
|
||||||
|
decl_id = DECL_ID_DECLTEST;
|
||||||
}
|
}
|
||||||
// TODO: handle identifier test names (decltest).
|
|
||||||
|
|
||||||
// Set up decl_block GenZir (AstGen.zig:4735-4743).
|
// Set up decl_block GenZir (AstGen.zig:4735-4743).
|
||||||
GenZir decl_block;
|
GenZir decl_block;
|
||||||
@@ -8094,9 +8100,12 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts,
|
|||||||
fn_block.break_block = UINT32_MAX;
|
fn_block.break_block = UINT32_MAX;
|
||||||
fn_block.any_defer_node = UINT32_MAX;
|
fn_block.any_defer_node = UINT32_MAX;
|
||||||
|
|
||||||
// Set fn_block and fn_ret_ty for the body (AstGen.zig:4849-4853).
|
// Set within_fn, fn_block and fn_ret_ty for the body
|
||||||
|
// (AstGen.zig:4848-4853).
|
||||||
|
bool prev_within_fn = ag->within_fn;
|
||||||
void* prev_fn_block = ag->fn_block;
|
void* prev_fn_block = ag->fn_block;
|
||||||
uint32_t prev_fn_ret_ty = ag->fn_ret_ty;
|
uint32_t prev_fn_ret_ty = ag->fn_ret_ty;
|
||||||
|
ag->within_fn = true;
|
||||||
setFnBlock(ag, &fn_block);
|
setFnBlock(ag, &fn_block);
|
||||||
ag->fn_ret_ty = ZIR_REF_ANYERROR_VOID_ERROR_UNION_TYPE;
|
ag->fn_ret_ty = ZIR_REF_ANYERROR_VOID_ERROR_UNION_TYPE;
|
||||||
|
|
||||||
@@ -8109,6 +8118,7 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts,
|
|||||||
uint32_t block_result
|
uint32_t block_result
|
||||||
= fullBodyExpr(&fn_block, &fn_block.base, RL_NONE_VAL, body_node);
|
= fullBodyExpr(&fn_block, &fn_block.base, RL_NONE_VAL, body_node);
|
||||||
|
|
||||||
|
ag->within_fn = prev_within_fn;
|
||||||
ag->fn_block = prev_fn_block;
|
ag->fn_block = prev_fn_block;
|
||||||
ag->fn_ret_ty = prev_fn_ret_ty;
|
ag->fn_ret_ty = prev_fn_ret_ty;
|
||||||
|
|
||||||
@@ -8192,6 +8202,11 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts,
|
|||||||
uint32_t decl_line = ag->source_line;
|
uint32_t decl_line = ag->source_line;
|
||||||
uint32_t decl_column = ag->source_column;
|
uint32_t decl_column = ag->source_column;
|
||||||
|
|
||||||
|
// Set this now, since parameter types, return type, etc may be generic
|
||||||
|
// (AstGen.zig:4097-4100).
|
||||||
|
bool prev_within_fn = ag->within_fn;
|
||||||
|
ag->within_fn = true;
|
||||||
|
|
||||||
// Save source cursor for restoring after ret_gz (AstGen.zig:4387-4388).
|
// Save source cursor for restoring after ret_gz (AstGen.zig:4387-4388).
|
||||||
uint32_t saved_source_offset = ag->source_offset;
|
uint32_t saved_source_offset = ag->source_offset;
|
||||||
uint32_t saved_source_line = ag->source_line;
|
uint32_t saved_source_line = ag->source_line;
|
||||||
@@ -8470,6 +8485,7 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts,
|
|||||||
|
|
||||||
fullBodyExpr(&body_gz, &body_gz.base, RL_NONE_VAL, body_node);
|
fullBodyExpr(&body_gz, &body_gz.base, RL_NONE_VAL, body_node);
|
||||||
|
|
||||||
|
ag->within_fn = prev_within_fn;
|
||||||
ag->fn_block = prev_fn_block;
|
ag->fn_block = prev_fn_block;
|
||||||
ag->fn_ret_ty = prev_fn_ret_ty;
|
ag->fn_ret_ty = prev_fn_ret_ty;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user