authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-15 19:19:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-15 19:19:28-05:00
loga05e224150a5a4bcad5ab1b399b43db8a0e28104
treedb8352ab2ca029b95050c78364adc4ac0deb1240
parent7293e012d7956b892380517e914108ffadc6941b
signaturelock-open Commit is signed but in an unrecognized format.

typecheck the panic function

this adds the prototype of panic to @import("builtin") and then uses it to do an implicit cast of the panic function to this prototype, rather than redoing all the implicit cast logic. closes #1894 closes #1895

7 files changed, 50 insertions(+), 48 deletions(-)

src/all_types.hpp+1
......@@ -1758,6 +1758,7 @@ struct CodeGen {
17581758 ZigFn *cur_fn;
17591759 ZigFn *main_fn;
17601760 ZigFn *panic_fn;
1761 TldFn *panic_tld_fn;
17611762 AstNode *root_export_decl;
17621763
17631764 CacheHash cache_hash;
src/analyze.cpp+22-39
......@@ -1351,7 +1351,7 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no
13511351 size_t backward_branch_count = 0;
13521352 return ir_eval_const_value(g, scope, node, type_entry,
13531353 &backward_branch_count, default_backward_branch_quota,
1354 nullptr, nullptr, node, type_name, nullptr);
1354 nullptr, nullptr, node, type_name, nullptr, nullptr);
13551355}
13561356
13571357ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
......@@ -3247,36 +3247,19 @@ static bool scope_is_root_decls(Scope *scope) {
32473247 zig_unreachable();
32483248}
32493249
3250static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, ZigType *fn_type) {
3251 add_node_error(g, proto_node,
3252 buf_sprintf("expected 'fn([]const u8, ?*builtin.StackTrace) noreturn', found '%s'",
3253 buf_ptr(&fn_type->name)));
3254}
3255
3256static void typecheck_panic_fn(CodeGen *g, ZigFn *panic_fn) {
3257 AstNode *proto_node = panic_fn->proto_node;
3258 assert(proto_node->type == NodeTypeFnProto);
3259 ZigType *fn_type = panic_fn->type_entry;
3260 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
3261 if (fn_type_id->param_count != 2) {
3262 return wrong_panic_prototype(g, proto_node, fn_type);
3263 }
3264 ZigType *const_u8_ptr = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
3265 PtrLenUnknown, 0, 0, 0);
3266 ZigType *const_u8_slice = get_slice_type(g, const_u8_ptr);
3267 if (fn_type_id->param_info[0].type != const_u8_slice) {
3268 return wrong_panic_prototype(g, proto_node, fn_type);
3269 }
3250void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) {
3251 ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn");
3252 assert(panic_fn_type_val != nullptr);
3253 assert(panic_fn_type_val->type->id == ZigTypeIdMetaType);
3254 ZigType *panic_fn_type = panic_fn_type_val->data.x_type;
32703255
3271 ZigType *optional_ptr_to_stack_trace_type = get_optional_type(g, get_ptr_to_stack_trace_type(g));
3272 if (fn_type_id->param_info[1].type != optional_ptr_to_stack_trace_type) {
3273 return wrong_panic_prototype(g, proto_node, fn_type);
3274 }
3256 AstNode *fake_decl = allocate<AstNode>(1);
3257 *fake_decl = *panic_fn->proto_node;
3258 fake_decl->type = NodeTypeSymbol;
3259 fake_decl->data.symbol_expr.symbol = &panic_fn->symbol_name;
32753260
3276 ZigType *actual_return_type = fn_type_id->return_type;
3277 if (actual_return_type != g->builtin_types.entry_unreachable) {
3278 return wrong_panic_prototype(g, proto_node, fn_type);
3279 }
3261 // call this for the side effects of casting to panic_fn_type
3262 analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr);
32803263}
32813264
32823265ZigType *get_test_fn_type(CodeGen *g) {
......@@ -3371,18 +3354,18 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
33713354 if (!fn_table_entry->type_entry->data.fn.is_generic) {
33723355 if (fn_def_node)
33733356 g->fn_defs.append(fn_table_entry);
3357 }
33743358
3375 if (scope_is_root_decls(tld_fn->base.parent_scope) &&
3376 (import == g->root_import || import->package == g->panic_package))
3359 if (scope_is_root_decls(tld_fn->base.parent_scope) &&
3360 (import == g->root_import || import->package == g->panic_package))
3361 {
3362 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
3363 g->main_fn = fn_table_entry;
3364 } else if ((import->package == g->panic_package || g->have_pub_panic) &&
3365 buf_eql_str(&fn_table_entry->symbol_name, "panic"))
33773366 {
3378 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
3379 g->main_fn = fn_table_entry;
3380 } else if ((import->package == g->panic_package || g->have_pub_panic) &&
3381 buf_eql_str(&fn_table_entry->symbol_name, "panic"))
3382 {
3383 g->panic_fn = fn_table_entry;
3384 typecheck_panic_fn(g, fn_table_entry);
3385 }
3367 g->panic_fn = fn_table_entry;
3368 g->panic_tld_fn = tld_fn;
33863369 }
33873370 }
33883371 } else if (source_node->type == NodeTypeTestDecl) {
src/analyze.hpp+1
......@@ -239,4 +239,5 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);
239239Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
240240 ConstExprValue *const_val, ZigType *wanted_type);
241241
242void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn);
242243#endif
src/codegen.cpp+4
......@@ -7144,6 +7144,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
71447144 " instruction_addresses: []usize,\n"
71457145 "};\n\n");
71467146
7147 buf_append_str(contents, "pub const PanicFn = fn([]const u8, ?*StackTrace) noreturn;\n\n");
7148
71477149 const char *cur_os = nullptr;
71487150 {
71497151 buf_appendf(contents, "pub const Os = enum {\n");
......@@ -7913,6 +7915,8 @@ static void gen_root_source(CodeGen *g) {
79137915 }
79147916 }
79157917
7918 typecheck_panic_fn(g, g->panic_tld_fn, g->panic_fn);
7919
79167920 report_errors_and_maybe_exit(g);
79177921
79187922}
src/ir.cpp+9-6
......@@ -9949,7 +9949,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
99499949ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
99509950 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
99519951 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
9952 IrExecutable *parent_exec)
9952 IrExecutable *parent_exec, AstNode *expected_type_source_node)
99539953{
99549954 if (expected_type != nullptr && type_is_invalid(expected_type))
99559955 return &codegen->invalid_instruction->value;
......@@ -9985,7 +9985,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
99859985 analyzed_executable->backward_branch_count = backward_branch_count;
99869986 analyzed_executable->backward_branch_quota = backward_branch_quota;
99879987 analyzed_executable->begin_scope = scope;
9988 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node);
9988 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node);
99899989 if (type_is_invalid(result_type))
99909990 return &codegen->invalid_instruction->value;
99919991
......@@ -10863,10 +10863,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1086310863 }
1086410864 break;
1086510865 }
10866 case ConstCastResultIdFnIsGeneric:
10867 add_error_note(ira->codegen, parent_msg, source_node,
10868 buf_sprintf("only one of the functions is generic"));
10869 break;
1086610870 case ConstCastResultIdFnAlign: // TODO
1086710871 case ConstCastResultIdFnCC: // TODO
1086810872 case ConstCastResultIdFnVarArgs: // TODO
10869 case ConstCastResultIdFnIsGeneric: // TODO
1087010873 case ConstCastResultIdFnReturnType: // TODO
1087110874 case ConstCastResultIdFnArgCount: // TODO
1087210875 case ConstCastResultIdFnGenericArgCount: // TODO
......@@ -13856,7 +13859,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1385613859 AstNode *body_node = fn_entry->body_node;
1385713860 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
1385813861 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
13859 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
13862 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node);
1386013863
1386113864 if (inferred_err_set_type != nullptr) {
1386213865 inferred_err_set_type->data.error_set.infer_fn = nullptr;
......@@ -14052,7 +14055,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1405214055 ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
1405314056 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen),
1405414057 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
14055 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec);
14058 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);
1405614059 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
1405714060 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
1405814061 const_instruction->base.value = *align_result;
......@@ -18464,7 +18467,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
1846418467 ZigType *void_type = ira->codegen->builtin_types.entry_void;
1846518468 ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type,
1846618469 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr,
18467 &cimport_scope->buf, block_node, nullptr, nullptr);
18470 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr);
1846818471 if (type_is_invalid(cimport_result->type))
1846918472 return ira->codegen->invalid_instruction;
1847018473
src/ir.hpp+1-1
......@@ -16,7 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
1616ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
1717 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
1818 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
19 IrExecutable *parent_exec);
19 IrExecutable *parent_exec, AstNode *expected_type_source_node);
2020
2121ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
2222 ZigType *expected_type, AstNode *expected_type_source_node);
test/compile_errors.zig+12-2
......@@ -346,13 +346,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
346346 );
347347
348348 cases.add(
349 "Panic declared with wrong type signature in tests",
349 "wrong panic signature, runtime function",
350350 \\test "" {}
351351 \\
352352 \\pub fn panic() void {}
353353 \\
354354 ,
355 ".tmp_source.zig:3:5: error: expected 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn() void'",
355 ".tmp_source.zig:3:5: error: expected type 'fn([]const u8, ?*StackTrace) noreturn', found 'fn() void'",
356 );
357
358 cases.add(
359 "wrong panic signature, generic function",
360 \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
361 \\ while (true) {}
362 \\}
363 ,
364 ".tmp_source.zig:1:5: error: expected type 'fn([]const u8, ?*StackTrace) noreturn', found 'fn([]const u8,var)var'",
365 ".tmp_source.zig:1:5: note: only one of the functions is generic",
356366 );
357367
358368 cases.add(