parent
0ff396c34f
commit
66a490c27c
|
@ -1396,6 +1396,7 @@ struct ZigFn {
|
|||
AstNode *set_cold_node;
|
||||
const AstNode *inferred_async_node;
|
||||
ZigFn *inferred_async_fn;
|
||||
AstNode *non_async_node;
|
||||
|
||||
ZigList<GlobalExport> export_list;
|
||||
ZigList<IrInstructionCallGen *> call_list;
|
||||
|
|
|
@ -4144,8 +4144,15 @@ void semantic_analyze(CodeGen *g) {
|
|||
|
||||
// second pass over functions for detecting async
|
||||
for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
|
||||
ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index);
|
||||
analyze_fn_async(g, fn_entry, true);
|
||||
ZigFn *fn = g->fn_defs.at(g->fn_defs_index);
|
||||
analyze_fn_async(g, fn, true);
|
||||
if (fn_is_async(fn) && fn->non_async_node != nullptr) {
|
||||
ErrorMsg *msg = add_node_error(g, fn->proto_node,
|
||||
buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name)));
|
||||
add_error_note(g, msg, fn->non_async_node,
|
||||
buf_sprintf("required to be non-async here"));
|
||||
add_async_error_notes(g, msg, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
src/ir.cpp
18
src/ir.cpp
|
@ -15160,6 +15160,20 @@ no_mem_slot:
|
|||
return var_ptr_instruction;
|
||||
}
|
||||
|
||||
// This function is called when a comptime value becomes accessible at runtime.
|
||||
static void mark_comptime_value_escape(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *val) {
|
||||
ir_assert(value_is_comptime(val), source_instr);
|
||||
if (val->special == ConstValSpecialUndef)
|
||||
return;
|
||||
|
||||
if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) {
|
||||
ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr);
|
||||
if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) {
|
||||
val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
|
||||
IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const)
|
||||
{
|
||||
|
@ -15256,6 +15270,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
|
|||
break;
|
||||
}
|
||||
|
||||
if (instr_is_comptime(value)) {
|
||||
mark_comptime_value_escape(ira, source_instr, &value->value);
|
||||
}
|
||||
|
||||
IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, ptr, value);
|
||||
return &store_ptr->base;
|
||||
|
|
|
@ -2,6 +2,21 @@ const tests = @import("tests.zig");
|
|||
const builtin = @import("builtin");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add(
|
||||
"non-async function pointer eventually is inferred to become async",
|
||||
\\export fn a() void {
|
||||
\\ var non_async_fn: fn () void = undefined;
|
||||
\\ non_async_fn = func;
|
||||
\\}
|
||||
\\fn func() void {
|
||||
\\ suspend;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:5:1: error: 'func' cannot be async",
|
||||
"tmp.zig:3:20: note: required to be non-async here",
|
||||
"tmp.zig:6:5: note: suspends here",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"bad alignment in @asyncCall",
|
||||
\\export fn entry() void {
|
||||
|
|
Loading…
Reference in New Issue