| author | |
| committer | |
| log | 3618256c97a9988f7d623eeabb667010ca30656f |
| tree | 0e6e0d8f3fc958809ffe9ea007416738d136c032 |
| parent | 6f8d732599461aa816f545b658a068eceb6ac9bc |
| signature |
6 files changed, 77 insertions(+), 2 deletions(-)
src/all_types.hpp+6| ... | ... | @@ -2330,6 +2330,7 @@ enum ScopeId { |
| 2330 | 2330 | ScopeIdRuntime, |
| 2331 | 2331 | ScopeIdTypeOf, |
| 2332 | 2332 | ScopeIdExpr, |
| 2333 | ScopeIdNoAsync, | |
| 2333 | 2334 | }; |
| 2334 | 2335 | |
| 2335 | 2336 | struct Scope { |
| ... | ... | @@ -2462,6 +2463,11 @@ struct ScopeCompTime { |
| 2462 | 2463 | Scope base; |
| 2463 | 2464 | }; |
| 2464 | 2465 | |
| 2466 | // This scope is created for a noasync expression. | |
| 2467 | // NodeTypeNoAsync | |
| 2468 | struct ScopeNoAsync { | |
| 2469 | Scope base; | |
| 2470 | }; | |
| 2465 | 2471 | |
| 2466 | 2472 | // This scope is created for a function definition. |
| 2467 | 2473 | // NodeTypeFnDef |
src/analyze.cpp+9| ... | ... | @@ -106,6 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) { |
| 106 | 106 | case ScopeIdDecls: |
| 107 | 107 | case ScopeIdFnDef: |
| 108 | 108 | case ScopeIdCompTime: |
| 109 | case ScopeIdNoAsync: | |
| 109 | 110 | case ScopeIdVarDecl: |
| 110 | 111 | case ScopeIdCImport: |
| 111 | 112 | case ScopeIdSuspend: |
| ... | ... | @@ -226,6 +227,12 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) { |
| 226 | 227 | return &scope->base; |
| 227 | 228 | } |
| 228 | 229 | |
| 230 | Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 231 | ScopeNoAsync *scope = heap::c_allocator.create<ScopeNoAsync>(); | |
| 232 | init_scope(g, &scope->base, ScopeIdNoAsync, node, parent); | |
| 233 | return &scope->base; | |
| 234 | } | |
| 235 | ||
| 229 | 236 | Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent) { |
| 230 | 237 | ScopeTypeOf *scope = heap::c_allocator.create<ScopeTypeOf>(); |
| 231 | 238 | init_scope(g, &scope->base, ScopeIdTypeOf, node, parent); |
| ... | ... | @@ -3755,6 +3762,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 3755 | 3762 | case NodeTypeCompTime: |
| 3756 | 3763 | preview_comptime_decl(g, node, decls_scope); |
| 3757 | 3764 | break; |
| 3765 | case NodeTypeNoAsync: | |
| 3758 | 3766 | case NodeTypeParamDecl: |
| 3759 | 3767 | case NodeTypeReturnExpr: |
| 3760 | 3768 | case NodeTypeDefer: |
| ... | ... | @@ -6176,6 +6184,7 @@ static void mark_suspension_point(Scope *scope) { |
| 6176 | 6184 | case ScopeIdDecls: |
| 6177 | 6185 | case ScopeIdFnDef: |
| 6178 | 6186 | case ScopeIdCompTime: |
| 6187 | case ScopeIdNoAsync: | |
| 6179 | 6188 | case ScopeIdCImport: |
| 6180 | 6189 | case ScopeIdSuspend: |
| 6181 | 6190 | case ScopeIdTypeOf: |
src/analyze.hpp+1| ... | ... | @@ -125,6 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent); |
| 125 | 125 | ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent); |
| 126 | 126 | ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry); |
| 127 | 127 | Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent); |
| 128 | Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 128 | 129 | Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime); |
| 129 | 130 | Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent); |
| 130 | 131 | ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent); |
src/codegen.cpp+2| ... | ... | @@ -687,6 +687,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { |
| 687 | 687 | case ScopeIdLoop: |
| 688 | 688 | case ScopeIdSuspend: |
| 689 | 689 | case ScopeIdCompTime: |
| 690 | case ScopeIdNoAsync: | |
| 690 | 691 | case ScopeIdRuntime: |
| 691 | 692 | case ScopeIdTypeOf: |
| 692 | 693 | case ScopeIdExpr: |
| ... | ... | @@ -3934,6 +3935,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { |
| 3934 | 3935 | case ScopeIdLoop: |
| 3935 | 3936 | case ScopeIdSuspend: |
| 3936 | 3937 | case ScopeIdCompTime: |
| 3938 | case ScopeIdNoAsync: | |
| 3937 | 3939 | case ScopeIdRuntime: |
| 3938 | 3940 | case ScopeIdTypeOf: |
| 3939 | 3941 | case ScopeIdExpr: |
src/ir.cpp+50-2| ... | ... | @@ -4978,6 +4978,7 @@ static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_ |
| 4978 | 4978 | case ScopeIdLoop: |
| 4979 | 4979 | case ScopeIdSuspend: |
| 4980 | 4980 | case ScopeIdCompTime: |
| 4981 | case ScopeIdNoAsync: | |
| 4981 | 4982 | case ScopeIdRuntime: |
| 4982 | 4983 | case ScopeIdTypeOf: |
| 4983 | 4984 | case ScopeIdExpr: |
| ... | ... | @@ -5033,6 +5034,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope |
| 5033 | 5034 | case ScopeIdLoop: |
| 5034 | 5035 | case ScopeIdSuspend: |
| 5035 | 5036 | case ScopeIdCompTime: |
| 5037 | case ScopeIdNoAsync: | |
| 5036 | 5038 | case ScopeIdRuntime: |
| 5037 | 5039 | case ScopeIdTypeOf: |
| 5038 | 5040 | case ScopeIdExpr: |
| ... | ... | @@ -7307,6 +7309,31 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod |
| 7307 | 7309 | zig_unreachable(); |
| 7308 | 7310 | } |
| 7309 | 7311 | |
| 7312 | static bool is_noasync_scope(Scope *scope) { | |
| 7313 | for (;;) { | |
| 7314 | switch (scope->id) { | |
| 7315 | case ScopeIdNoAsync: | |
| 7316 | return true; | |
| 7317 | case ScopeIdDefer: | |
| 7318 | case ScopeIdDeferExpr: | |
| 7319 | case ScopeIdDecls: | |
| 7320 | case ScopeIdFnDef: | |
| 7321 | case ScopeIdCompTime: | |
| 7322 | case ScopeIdVarDecl: | |
| 7323 | case ScopeIdCImport: | |
| 7324 | case ScopeIdSuspend: | |
| 7325 | return false; | |
| 7326 | case ScopeIdExpr: | |
| 7327 | case ScopeIdTypeOf: | |
| 7328 | case ScopeIdBlock: | |
| 7329 | case ScopeIdLoop: | |
| 7330 | case ScopeIdRuntime: | |
| 7331 | scope = scope->parent; | |
| 7332 | continue; | |
| 7333 | } | |
| 7334 | } | |
| 7335 | } | |
| 7336 | ||
| 7310 | 7337 | static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, |
| 7311 | 7338 | ResultLoc *result_loc) |
| 7312 | 7339 | { |
| ... | ... | @@ -7315,8 +7342,19 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, |
| 7315 | 7342 | if (node->data.fn_call_expr.modifier == CallModifierBuiltin) |
| 7316 | 7343 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 7317 | 7344 | |
| 7345 | bool is_noasync = is_noasync_scope(scope); | |
| 7346 | CallModifier modifier = node->data.fn_call_expr.modifier; | |
| 7347 | if (is_noasync) { | |
| 7348 | if (modifier == CallModifierAsync) { | |
| 7349 | add_node_error(irb->codegen, node, | |
| 7350 | buf_sprintf("async call in noasync scope")); | |
| 7351 | return irb->codegen->invalid_inst_src; | |
| 7352 | } | |
| 7353 | modifier = CallModifierNoAsync; | |
| 7354 | } | |
| 7355 | ||
| 7318 | 7356 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 7319 | return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, node->data.fn_call_expr.modifier, | |
| 7357 | return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier, | |
| 7320 | 7358 | nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); |
| 7321 | 7359 | } |
| 7322 | 7360 | |
| ... | ... | @@ -9170,6 +9208,14 @@ static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNod |
| 9170 | 9208 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); |
| 9171 | 9209 | } |
| 9172 | 9210 | |
| 9211 | static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { | |
| 9212 | assert(node->type == NodeTypeNoAsync); | |
| 9213 | ||
| 9214 | Scope *child_scope = create_noasync_scope(irb->codegen, node, parent_scope); | |
| 9215 | // purposefully pass null for result_loc and let EndExpr handle it | |
| 9216 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); | |
| 9217 | } | |
| 9218 | ||
| 9173 | 9219 | static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { |
| 9174 | 9220 | IrInstSrc *is_comptime; |
| 9175 | 9221 | if (ir_should_inline(irb->exec, break_scope)) { |
| ... | ... | @@ -9763,7 +9809,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no |
| 9763 | 9809 | { |
| 9764 | 9810 | assert(node->type == NodeTypeAwaitExpr); |
| 9765 | 9811 | |
| 9766 | bool is_noasync = node->data.await_expr.noasync_token != nullptr; | |
| 9812 | bool is_noasync = is_noasync_scope(scope); | |
| 9767 | 9813 | |
| 9768 | 9814 | AstNode *expr_node = node->data.await_expr.expr; |
| 9769 | 9815 | 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 |
| 9938 | 9984 | return ir_gen_switch_expr(irb, scope, node, lval, result_loc); |
| 9939 | 9985 | case NodeTypeCompTime: |
| 9940 | 9986 | return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); |
| 9987 | case NodeTypeNoAsync: | |
| 9988 | return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc); | |
| 9941 | 9989 | case NodeTypeErrorType: |
| 9942 | 9990 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); |
| 9943 | 9991 | case NodeTypeBreak: |
test/compile_errors.zig+9| ... | ... | @@ -2,6 +2,15 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("combination of noasync and async", | |
| 6 | \\export fn entry() void { | |
| 7 | \\ noasync async foo(); | |
| 8 | \\} | |
| 9 | \\fn foo() void {} | |
| 10 | , &[_][]const u8{ | |
| 11 | "tmp.zig:2:13: error: async call in noasync scope", | |
| 12 | }); | |
| 13 | ||
| 5 | 14 | cases.addTest("@TypeOf with no arguments", |
| 6 | 15 | \\export fn entry() void { |
| 7 | 16 | \\ _ = @TypeOf(); |