mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
implement noasync scopes
This commit is contained in:
parent
6f8d732599
commit
3618256c97
6 changed files with 77 additions and 2 deletions
|
|
@ -2330,6 +2330,7 @@ enum ScopeId {
|
||||||
ScopeIdRuntime,
|
ScopeIdRuntime,
|
||||||
ScopeIdTypeOf,
|
ScopeIdTypeOf,
|
||||||
ScopeIdExpr,
|
ScopeIdExpr,
|
||||||
|
ScopeIdNoAsync,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
|
|
@ -2462,6 +2463,11 @@ struct ScopeCompTime {
|
||||||
Scope base;
|
Scope base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This scope is created for a noasync expression.
|
||||||
|
// NodeTypeNoAsync
|
||||||
|
struct ScopeNoAsync {
|
||||||
|
Scope base;
|
||||||
|
};
|
||||||
|
|
||||||
// This scope is created for a function definition.
|
// This scope is created for a function definition.
|
||||||
// NodeTypeFnDef
|
// NodeTypeFnDef
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {
|
||||||
case ScopeIdDecls:
|
case ScopeIdDecls:
|
||||||
case ScopeIdFnDef:
|
case ScopeIdFnDef:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdVarDecl:
|
case ScopeIdVarDecl:
|
||||||
case ScopeIdCImport:
|
case ScopeIdCImport:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
|
|
@ -226,6 +227,12 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||||
return &scope->base;
|
return &scope->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||||
|
ScopeNoAsync *scope = heap::c_allocator.create<ScopeNoAsync>();
|
||||||
|
init_scope(g, &scope->base, ScopeIdNoAsync, node, parent);
|
||||||
|
return &scope->base;
|
||||||
|
}
|
||||||
|
|
||||||
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||||
ScopeTypeOf *scope = heap::c_allocator.create<ScopeTypeOf>();
|
ScopeTypeOf *scope = heap::c_allocator.create<ScopeTypeOf>();
|
||||||
init_scope(g, &scope->base, ScopeIdTypeOf, node, parent);
|
init_scope(g, &scope->base, ScopeIdTypeOf, node, parent);
|
||||||
|
|
@ -3755,6 +3762,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||||
case NodeTypeCompTime:
|
case NodeTypeCompTime:
|
||||||
preview_comptime_decl(g, node, decls_scope);
|
preview_comptime_decl(g, node, decls_scope);
|
||||||
break;
|
break;
|
||||||
|
case NodeTypeNoAsync:
|
||||||
case NodeTypeParamDecl:
|
case NodeTypeParamDecl:
|
||||||
case NodeTypeReturnExpr:
|
case NodeTypeReturnExpr:
|
||||||
case NodeTypeDefer:
|
case NodeTypeDefer:
|
||||||
|
|
@ -6176,6 +6184,7 @@ static void mark_suspension_point(Scope *scope) {
|
||||||
case ScopeIdDecls:
|
case ScopeIdDecls:
|
||||||
case ScopeIdFnDef:
|
case ScopeIdFnDef:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdCImport:
|
case ScopeIdCImport:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
case ScopeIdTypeOf:
|
case ScopeIdTypeOf:
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
|
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
|
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
|
||||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
|
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
|
Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
|
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
|
||||||
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
|
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
|
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||||
|
|
|
||||||
|
|
@ -687,6 +687,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||||
case ScopeIdLoop:
|
case ScopeIdLoop:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdRuntime:
|
case ScopeIdRuntime:
|
||||||
case ScopeIdTypeOf:
|
case ScopeIdTypeOf:
|
||||||
case ScopeIdExpr:
|
case ScopeIdExpr:
|
||||||
|
|
@ -3934,6 +3935,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
|
||||||
case ScopeIdLoop:
|
case ScopeIdLoop:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdRuntime:
|
case ScopeIdRuntime:
|
||||||
case ScopeIdTypeOf:
|
case ScopeIdTypeOf:
|
||||||
case ScopeIdExpr:
|
case ScopeIdExpr:
|
||||||
|
|
|
||||||
52
src/ir.cpp
52
src/ir.cpp
|
|
@ -4978,6 +4978,7 @@ static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_
|
||||||
case ScopeIdLoop:
|
case ScopeIdLoop:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdRuntime:
|
case ScopeIdRuntime:
|
||||||
case ScopeIdTypeOf:
|
case ScopeIdTypeOf:
|
||||||
case ScopeIdExpr:
|
case ScopeIdExpr:
|
||||||
|
|
@ -5033,6 +5034,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope
|
||||||
case ScopeIdLoop:
|
case ScopeIdLoop:
|
||||||
case ScopeIdSuspend:
|
case ScopeIdSuspend:
|
||||||
case ScopeIdCompTime:
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdNoAsync:
|
||||||
case ScopeIdRuntime:
|
case ScopeIdRuntime:
|
||||||
case ScopeIdTypeOf:
|
case ScopeIdTypeOf:
|
||||||
case ScopeIdExpr:
|
case ScopeIdExpr:
|
||||||
|
|
@ -7307,6 +7309,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_noasync_scope(Scope *scope) {
|
||||||
|
for (;;) {
|
||||||
|
switch (scope->id) {
|
||||||
|
case ScopeIdNoAsync:
|
||||||
|
return true;
|
||||||
|
case ScopeIdDefer:
|
||||||
|
case ScopeIdDeferExpr:
|
||||||
|
case ScopeIdDecls:
|
||||||
|
case ScopeIdFnDef:
|
||||||
|
case ScopeIdCompTime:
|
||||||
|
case ScopeIdVarDecl:
|
||||||
|
case ScopeIdCImport:
|
||||||
|
case ScopeIdSuspend:
|
||||||
|
return false;
|
||||||
|
case ScopeIdExpr:
|
||||||
|
case ScopeIdTypeOf:
|
||||||
|
case ScopeIdBlock:
|
||||||
|
case ScopeIdLoop:
|
||||||
|
case ScopeIdRuntime:
|
||||||
|
scope = scope->parent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
|
static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
|
||||||
ResultLoc *result_loc)
|
ResultLoc *result_loc)
|
||||||
{
|
{
|
||||||
|
|
@ -7315,8 +7342,19 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,
|
||||||
if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
|
if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
|
||||||
return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
|
return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
|
||||||
|
|
||||||
|
bool is_noasync = is_noasync_scope(scope);
|
||||||
|
CallModifier modifier = node->data.fn_call_expr.modifier;
|
||||||
|
if (is_noasync) {
|
||||||
|
if (modifier == CallModifierAsync) {
|
||||||
|
add_node_error(irb->codegen, node,
|
||||||
|
buf_sprintf("async call in noasync scope"));
|
||||||
|
return irb->codegen->invalid_inst_src;
|
||||||
|
}
|
||||||
|
modifier = CallModifierNoAsync;
|
||||||
|
}
|
||||||
|
|
||||||
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
|
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
|
||||||
return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, node->data.fn_call_expr.modifier,
|
return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier,
|
||||||
nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc);
|
nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9170,6 +9208,14 @@ static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNod
|
||||||
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
|
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
|
||||||
|
assert(node->type == NodeTypeNoAsync);
|
||||||
|
|
||||||
|
Scope *child_scope = create_noasync_scope(irb->codegen, node, parent_scope);
|
||||||
|
// purposefully pass null for result_loc and let EndExpr handle it
|
||||||
|
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
|
static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
|
||||||
IrInstSrc *is_comptime;
|
IrInstSrc *is_comptime;
|
||||||
if (ir_should_inline(irb->exec, break_scope)) {
|
if (ir_should_inline(irb->exec, break_scope)) {
|
||||||
|
|
@ -9763,7 +9809,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
|
||||||
{
|
{
|
||||||
assert(node->type == NodeTypeAwaitExpr);
|
assert(node->type == NodeTypeAwaitExpr);
|
||||||
|
|
||||||
bool is_noasync = node->data.await_expr.noasync_token != nullptr;
|
bool is_noasync = is_noasync_scope(scope);
|
||||||
|
|
||||||
AstNode *expr_node = node->data.await_expr.expr;
|
AstNode *expr_node = node->data.await_expr.expr;
|
||||||
if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
|
if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
|
||||||
|
|
@ -9938,6 +9984,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
|
||||||
return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
|
return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
|
||||||
case NodeTypeCompTime:
|
case NodeTypeCompTime:
|
||||||
return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
|
return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
|
||||||
|
case NodeTypeNoAsync:
|
||||||
|
return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc);
|
||||||
case NodeTypeErrorType:
|
case NodeTypeErrorType:
|
||||||
return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
|
return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
|
||||||
case NodeTypeBreak:
|
case NodeTypeBreak:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,15 @@ const tests = @import("tests.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
|
cases.addTest("combination of noasync and async",
|
||||||
|
\\export fn entry() void {
|
||||||
|
\\ noasync async foo();
|
||||||
|
\\}
|
||||||
|
\\fn foo() void {}
|
||||||
|
, &[_][]const u8{
|
||||||
|
"tmp.zig:2:13: error: async call in noasync scope",
|
||||||
|
});
|
||||||
|
|
||||||
cases.addTest("@TypeOf with no arguments",
|
cases.addTest("@TypeOf with no arguments",
|
||||||
\\export fn entry() void {
|
\\export fn entry() void {
|
||||||
\\ _ = @TypeOf();
|
\\ _ = @TypeOf();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue