authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-14 11:22:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-14 11:22:12-04:00
logf3f838cc016fd8190a9bba46fa495fbc27325492
treeaeab69f487c8cab3441a04ed477eff869da4d934
parent7799423f24a0f628641e772146f1e6a5c2f6bdcb
signaturelock-open Commit is signed but in an unrecognized format.

add compile error for await in exported function


2 files changed, 43 insertions(+), 16 deletions(-)

src/analyze.cpp+29-16
......@@ -3893,18 +3893,18 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn) {
38933893 fn->inferred_async_node = inferred_async_none;
38943894}
38953895
3896static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node) {
3897 ZigType *fn_type = fn_table_entry->type_entry;
3896static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
3897 ZigType *fn_type = fn->type_entry;
38983898 assert(!fn_type->data.fn.is_generic);
38993899 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
39003900
3901 ZigType *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable,
3902 &fn_table_entry->analyzed_executable, fn_type_id->return_type, return_type_node);
3903 fn_table_entry->src_implicit_return_type = block_return_type;
3901 ZigType *block_return_type = ir_analyze(g, &fn->ir_executable,
3902 &fn->analyzed_executable, fn_type_id->return_type, return_type_node);
3903 fn->src_implicit_return_type = block_return_type;
39043904
3905 if (type_is_invalid(block_return_type) || fn_table_entry->analyzed_executable.invalid) {
3905 if (type_is_invalid(block_return_type) || fn->analyzed_executable.invalid) {
39063906 assert(g->errors.length > 0);
3907 fn_table_entry->anal_state = FnAnalStateInvalid;
3907 fn->anal_state = FnAnalStateInvalid;
39083908 return;
39093909 }
39103910
......@@ -3912,20 +3912,20 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_typ
39123912 ZigType *return_err_set_type = fn_type_id->return_type->data.error_union.err_set_type;
39133913 if (return_err_set_type->data.error_set.infer_fn != nullptr) {
39143914 ZigType *inferred_err_set_type;
3915 if (fn_table_entry->src_implicit_return_type->id == ZigTypeIdErrorSet) {
3916 inferred_err_set_type = fn_table_entry->src_implicit_return_type;
3917 } else if (fn_table_entry->src_implicit_return_type->id == ZigTypeIdErrorUnion) {
3918 inferred_err_set_type = fn_table_entry->src_implicit_return_type->data.error_union.err_set_type;
3915 if (fn->src_implicit_return_type->id == ZigTypeIdErrorSet) {
3916 inferred_err_set_type = fn->src_implicit_return_type;
3917 } else if (fn->src_implicit_return_type->id == ZigTypeIdErrorUnion) {
3918 inferred_err_set_type = fn->src_implicit_return_type->data.error_union.err_set_type;
39193919 } else {
39203920 add_node_error(g, return_type_node,
39213921 buf_sprintf("function with inferred error set must return at least one possible error"));
3922 fn_table_entry->anal_state = FnAnalStateInvalid;
3922 fn->anal_state = FnAnalStateInvalid;
39233923 return;
39243924 }
39253925
39263926 if (inferred_err_set_type->data.error_set.infer_fn != nullptr) {
39273927 if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {
3928 fn_table_entry->anal_state = FnAnalStateInvalid;
3928 fn->anal_state = FnAnalStateInvalid;
39293929 return;
39303930 }
39313931 }
......@@ -3945,12 +3945,25 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_typ
39453945 }
39463946 }
39473947
3948 CallingConvention cc = fn->type_entry->data.fn.fn_type_id.cc;
3949 if (cc != CallingConventionUnspecified && cc != CallingConventionAsync &&
3950 fn->inferred_async_node != nullptr &&
3951 fn->inferred_async_node != inferred_async_checking &&
3952 fn->inferred_async_node != inferred_async_none)
3953 {
3954 ErrorMsg *msg = add_node_error(g, fn->proto_node,
3955 buf_sprintf("function with calling convention '%s' cannot be async",
3956 calling_convention_name(cc)));
3957 add_async_error_notes(g, msg, fn);
3958 fn->anal_state = FnAnalStateInvalid;
3959 }
3960
39483961 if (g->verbose_ir) {
3949 fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name));
3950 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
3962 fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn->symbol_name));
3963 ir_print(g, stderr, &fn->analyzed_executable, 4);
39513964 fprintf(stderr, "}\n");
39523965 }
3953 fn_table_entry->anal_state = FnAnalStateComplete;
3966 fn->anal_state = FnAnalStateComplete;
39543967}
39553968
39563969static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
test/compile_errors.zig+14
......@@ -2,6 +2,20 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "invalid suspend in exported function",
7 \\export fn entry() void {
8 \\ var frame = async func();
9 \\ var result = await frame;
10 \\}
11 \\fn func() void {
12 \\ suspend;
13 \\}
14 ,
15 "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async",
16 "tmp.zig:3:18: note: await is a suspend point",
17 );
18
519 cases.add(
620 "async function indirectly depends on its own frame",
721 \\export fn entry() void {