| author | |
| committer | |
| log | a05e224150a5a4bcad5ab1b399b43db8a0e28104 |
| tree | db8352ab2ca029b95050c78364adc4ac0deb1240 |
| parent | 7293e012d7956b892380517e914108ffadc6941b |
| signature | Commit is signed but in an unrecognized format. |
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 #18957 files changed, 50 insertions(+), 48 deletions(-)
src/all_types.hpp+1| ... | @@ -1758,6 +1758,7 @@ struct CodeGen { | ... | @@ -1758,6 +1758,7 @@ struct CodeGen { |
| 1758 | ZigFn *cur_fn; | 1758 | ZigFn *cur_fn; |
| 1759 | ZigFn *main_fn; | 1759 | ZigFn *main_fn; |
| 1760 | ZigFn *panic_fn; | 1760 | ZigFn *panic_fn; |
| 1761 | TldFn *panic_tld_fn; | ||
| 1761 | AstNode *root_export_decl; | 1762 | AstNode *root_export_decl; |
| 1762 | 1763 | ||
| 1763 | CacheHash cache_hash; | 1764 | CacheHash cache_hash; |
src/analyze.cpp+22-39| ... | @@ -1351,7 +1351,7 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no | ... | @@ -1351,7 +1351,7 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no |
| 1351 | size_t backward_branch_count = 0; | 1351 | size_t backward_branch_count = 0; |
| 1352 | return ir_eval_const_value(g, scope, node, type_entry, | 1352 | return ir_eval_const_value(g, scope, node, type_entry, |
| 1353 | &backward_branch_count, default_backward_branch_quota, | 1353 | &backward_branch_count, default_backward_branch_quota, |
| 1354 | nullptr, nullptr, node, type_name, nullptr); | 1354 | nullptr, nullptr, node, type_name, nullptr, nullptr); |
| 1355 | } | 1355 | } |
| 1356 | 1356 | ||
| 1357 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | 1357 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { |
| ... | @@ -3247,36 +3247,19 @@ static bool scope_is_root_decls(Scope *scope) { | ... | @@ -3247,36 +3247,19 @@ static bool scope_is_root_decls(Scope *scope) { |
| 3247 | zig_unreachable(); | 3247 | zig_unreachable(); |
| 3248 | } | 3248 | } |
| 3249 | 3249 | ||
| 3250 | static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, ZigType *fn_type) { | 3250 | void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) { |
| 3251 | add_node_error(g, proto_node, | 3251 | ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn"); |
| 3252 | buf_sprintf("expected 'fn([]const u8, ?*builtin.StackTrace) noreturn', found '%s'", | 3252 | assert(panic_fn_type_val != nullptr); |
| 3253 | buf_ptr(&fn_type->name))); | 3253 | assert(panic_fn_type_val->type->id == ZigTypeIdMetaType); |
| 3254 | } | 3254 | ZigType *panic_fn_type = panic_fn_type_val->data.x_type; |
| 3255 | |||
| 3256 | static 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 | } | ||
| 3270 | 3255 | ||
| 3271 | ZigType *optional_ptr_to_stack_trace_type = get_optional_type(g, get_ptr_to_stack_trace_type(g)); | 3256 | AstNode *fake_decl = allocate<AstNode>(1); |
| 3272 | if (fn_type_id->param_info[1].type != optional_ptr_to_stack_trace_type) { | 3257 | *fake_decl = *panic_fn->proto_node; |
| 3273 | return wrong_panic_prototype(g, proto_node, fn_type); | 3258 | fake_decl->type = NodeTypeSymbol; |
| 3274 | } | 3259 | fake_decl->data.symbol_expr.symbol = &panic_fn->symbol_name; |
| 3275 | 3260 | ||
| 3276 | ZigType *actual_return_type = fn_type_id->return_type; | 3261 | // call this for the side effects of casting to panic_fn_type |
| 3277 | if (actual_return_type != g->builtin_types.entry_unreachable) { | 3262 | analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr); |
| 3278 | return wrong_panic_prototype(g, proto_node, fn_type); | ||
| 3279 | } | ||
| 3280 | } | 3263 | } |
| 3281 | 3264 | ||
| 3282 | ZigType *get_test_fn_type(CodeGen *g) { | 3265 | ZigType *get_test_fn_type(CodeGen *g) { |
| ... | @@ -3371,18 +3354,18 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -3371,18 +3354,18 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3371 | if (!fn_table_entry->type_entry->data.fn.is_generic) { | 3354 | if (!fn_table_entry->type_entry->data.fn.is_generic) { |
| 3372 | if (fn_def_node) | 3355 | if (fn_def_node) |
| 3373 | g->fn_defs.append(fn_table_entry); | 3356 | g->fn_defs.append(fn_table_entry); |
| 3357 | } | ||
| 3374 | 3358 | ||
| 3375 | if (scope_is_root_decls(tld_fn->base.parent_scope) && | 3359 | if (scope_is_root_decls(tld_fn->base.parent_scope) && |
| 3376 | (import == g->root_import || import->package == g->panic_package)) | 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")) | ||
| 3377 | { | 3366 | { |
| 3378 | if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { | 3367 | g->panic_fn = fn_table_entry; |
| 3379 | g->main_fn = fn_table_entry; | 3368 | g->panic_tld_fn = tld_fn; |
| 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 | } | ||
| 3386 | } | 3369 | } |
| 3387 | } | 3370 | } |
| 3388 | } else if (source_node->type == NodeTypeTestDecl) { | 3371 | } 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); | ... | @@ -239,4 +239,5 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry); |
| 239 | Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, | 239 | Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, |
| 240 | ConstExprValue *const_val, ZigType *wanted_type); | 240 | ConstExprValue *const_val, ZigType *wanted_type); |
| 241 | 241 | ||
| 242 | void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn); | ||
| 242 | #endif | 243 | #endif |
src/codegen.cpp+4| ... | @@ -7144,6 +7144,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -7144,6 +7144,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 7144 | " instruction_addresses: []usize,\n" | 7144 | " instruction_addresses: []usize,\n" |
| 7145 | "};\n\n"); | 7145 | "};\n\n"); |
| 7146 | 7146 | ||
| 7147 | buf_append_str(contents, "pub const PanicFn = fn([]const u8, ?*StackTrace) noreturn;\n\n"); | ||
| 7148 | |||
| 7147 | const char *cur_os = nullptr; | 7149 | const char *cur_os = nullptr; |
| 7148 | { | 7150 | { |
| 7149 | buf_appendf(contents, "pub const Os = enum {\n"); | 7151 | buf_appendf(contents, "pub const Os = enum {\n"); |
| ... | @@ -7913,6 +7915,8 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -7913,6 +7915,8 @@ static void gen_root_source(CodeGen *g) { |
| 7913 | } | 7915 | } |
| 7914 | } | 7916 | } |
| 7915 | 7917 | ||
| 7918 | typecheck_panic_fn(g, g->panic_tld_fn, g->panic_fn); | ||
| 7919 | |||
| 7916 | report_errors_and_maybe_exit(g); | 7920 | report_errors_and_maybe_exit(g); |
| 7917 | 7921 | ||
| 7918 | } | 7922 | } |
src/ir.cpp+9-6| ... | @@ -9949,7 +9949,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un | ... | @@ -9949,7 +9949,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un |
| 9949 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 9949 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 9950 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 9950 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 9951 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, | 9951 | 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) |
| 9953 | { | 9953 | { |
| 9954 | if (expected_type != nullptr && type_is_invalid(expected_type)) | 9954 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 9955 | return &codegen->invalid_instruction->value; | 9955 | return &codegen->invalid_instruction->value; |
| ... | @@ -9985,7 +9985,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod | ... | @@ -9985,7 +9985,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 9985 | analyzed_executable->backward_branch_count = backward_branch_count; | 9985 | analyzed_executable->backward_branch_count = backward_branch_count; |
| 9986 | analyzed_executable->backward_branch_quota = backward_branch_quota; | 9986 | analyzed_executable->backward_branch_quota = backward_branch_quota; |
| 9987 | analyzed_executable->begin_scope = scope; | 9987 | 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); |
| 9989 | if (type_is_invalid(result_type)) | 9989 | if (type_is_invalid(result_type)) |
| 9990 | return &codegen->invalid_instruction->value; | 9990 | return &codegen->invalid_instruction->value; |
| 9991 | 9991 | ||
| ... | @@ -10863,10 +10863,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa | ... | @@ -10863,10 +10863,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 10863 | } | 10863 | } |
| 10864 | break; | 10864 | break; |
| 10865 | } | 10865 | } |
| 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; | ||
| 10866 | case ConstCastResultIdFnAlign: // TODO | 10870 | case ConstCastResultIdFnAlign: // TODO |
| 10867 | case ConstCastResultIdFnCC: // TODO | 10871 | case ConstCastResultIdFnCC: // TODO |
| 10868 | case ConstCastResultIdFnVarArgs: // TODO | 10872 | case ConstCastResultIdFnVarArgs: // TODO |
| 10869 | case ConstCastResultIdFnIsGeneric: // TODO | ||
| 10870 | case ConstCastResultIdFnReturnType: // TODO | 10873 | case ConstCastResultIdFnReturnType: // TODO |
| 10871 | case ConstCastResultIdFnArgCount: // TODO | 10874 | case ConstCastResultIdFnArgCount: // TODO |
| 10872 | case ConstCastResultIdFnGenericArgCount: // TODO | 10875 | case ConstCastResultIdFnGenericArgCount: // TODO |
| ... | @@ -13856,7 +13859,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -13856,7 +13859,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 13856 | AstNode *body_node = fn_entry->body_node; | 13859 | AstNode *body_node = fn_entry->body_node; |
| 13857 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, | 13860 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 13858 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, | 13861 | 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); |
| 13860 | 13863 | ||
| 13861 | if (inferred_err_set_type != nullptr) { | 13864 | if (inferred_err_set_type != nullptr) { |
| 13862 | inferred_err_set_type->data.error_set.infer_fn = nullptr; | 13865 | inferred_err_set_type->data.error_set.infer_fn = nullptr; |
| ... | @@ -14052,7 +14055,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call | ... | @@ -14052,7 +14055,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14052 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, | 14055 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, |
| 14053 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), | 14056 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), |
| 14054 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, | 14057 | 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); |
| 14056 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 14059 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14057 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); | 14060 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14058 | const_instruction->base.value = *align_result; | 14061 | const_instruction->base.value = *align_result; |
| ... | @@ -18464,7 +18467,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct | ... | @@ -18464,7 +18467,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 18464 | ZigType *void_type = ira->codegen->builtin_types.entry_void; | 18467 | ZigType *void_type = ira->codegen->builtin_types.entry_void; |
| 18465 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, | 18468 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 18466 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, | 18469 | 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); |
| 18468 | if (type_is_invalid(cimport_result->type)) | 18471 | if (type_is_invalid(cimport_result->type)) |
| 18469 | return ira->codegen->invalid_instruction; | 18472 | return ira->codegen->invalid_instruction; |
| 18470 | 18473 |
src/ir.hpp+1-1| ... | @@ -16,7 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); | ... | @@ -16,7 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); |
| 16 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 16 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 17 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 17 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 18 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, | 18 | 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); |
| 20 | 20 | ||
| 21 | ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, | 21 | ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, |
| 22 | ZigType *expected_type, AstNode *expected_type_source_node); | 22 | 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 { | ... | @@ -346,13 +346,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 346 | ); | 346 | ); |
| 347 | 347 | ||
| 348 | cases.add( | 348 | cases.add( |
| 349 | "Panic declared with wrong type signature in tests", | 349 | "wrong panic signature, runtime function", |
| 350 | \\test "" {} | 350 | \\test "" {} |
| 351 | \\ | 351 | \\ |
| 352 | \\pub fn panic() void {} | 352 | \\pub fn panic() void {} |
| 353 | \\ | 353 | \\ |
| 354 | , | 354 | , |
| 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", | ||
| 356 | ); | 366 | ); |
| 357 | 367 | ||
| 358 | cases.add( | 368 | cases.add( |