better compile errors when frame depends on itself
This commit is contained in:
parent
8be95af480
commit
bfa1d12fba
|
@ -5179,11 +5179,14 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
|
|||
if (fn->anal_state == FnAnalStateInvalid)
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
break;
|
||||
case FnAnalStateProbing:
|
||||
add_node_error(g, fn->proto_node,
|
||||
case FnAnalStateProbing: {
|
||||
ErrorMsg *msg = add_node_error(g, fn->proto_node,
|
||||
buf_sprintf("cannot resolve '%s': function not fully analyzed yet",
|
||||
buf_ptr(&frame_type->name)));
|
||||
ir_add_analysis_trace(fn->ir_executable.analysis, msg,
|
||||
buf_sprintf("depends on its own frame here"));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
}
|
||||
ZigType *fn_type = get_async_fn_type(g, fn->type_entry);
|
||||
|
||||
|
@ -5201,8 +5204,10 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
|
|||
if (callee->anal_state == FnAnalStateProbing) {
|
||||
ErrorMsg *msg = add_node_error(g, fn->proto_node,
|
||||
buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
|
||||
add_error_note(g, msg, call->base.source_node,
|
||||
ErrorMsg *note = add_error_note(g, msg, call->base.source_node,
|
||||
buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
|
||||
ir_add_analysis_trace(callee->ir_executable.analysis, note,
|
||||
buf_sprintf("depends on the frame here"));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
|
||||
|
|
12
src/ir.cpp
12
src/ir.cpp
|
@ -8217,18 +8217,24 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
|
|||
return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
|
||||
}
|
||||
|
||||
static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {
|
||||
static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {
|
||||
if (!exec || !exec->source_node || limit < 0) return;
|
||||
add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
|
||||
|
||||
add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);
|
||||
ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);
|
||||
}
|
||||
|
||||
void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text) {
|
||||
IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
|
||||
add_error_note(ira->codegen, err_msg, old_instruction->source_node, text);
|
||||
ir_add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10);
|
||||
}
|
||||
|
||||
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
|
||||
invalidate_exec(exec);
|
||||
ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
|
||||
if (exec->parent_exec) {
|
||||
add_call_stack_errors(codegen, exec, err_msg, 10);
|
||||
ir_add_call_stack_errors(codegen, exec, err_msg, 10);
|
||||
}
|
||||
return err_msg;
|
||||
}
|
||||
|
|
|
@ -28,4 +28,6 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal
|
|||
AstNode *source_node);
|
||||
const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
|
||||
|
||||
void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,36 @@ const tests = @import("tests.zig");
|
|||
const builtin = @import("builtin");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add(
|
||||
"async function indirectly depends on its own frame",
|
||||
\\export fn entry() void {
|
||||
\\ _ = async amain();
|
||||
\\}
|
||||
\\async fn amain() void {
|
||||
\\ other();
|
||||
\\}
|
||||
\\fn other() void {
|
||||
\\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:4:1: error: unable to determine async function frame of 'amain'",
|
||||
"tmp.zig:5:10: note: analysis of function 'other' depends on the frame",
|
||||
"tmp.zig:8:13: note: depends on the frame here",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"async function depends on its own frame",
|
||||
\\export fn entry() void {
|
||||
\\ _ = async amain();
|
||||
\\}
|
||||
\\async fn amain() void {
|
||||
\\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet",
|
||||
"tmp.zig:5:13: note: depends on its own frame here",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"non async function pointer passed to @asyncCall",
|
||||
\\export fn entry() void {
|
||||
|
|
Loading…
Reference in New Issue
Block a user