| author | |
| committer | |
| log | 66a490c27c01c958d8d20dbc289c6b2b934a724e |
| tree | edd444dfae7eb106453f9aa0aa9ec3908c97e2f1 |
| parent | 0ff396c34f93b60a000e1ee50e881a8c25122b79 |
| signature |
closes #30754 files changed, 43 insertions(+), 2 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -1396,6 +1396,7 @@ struct ZigFn { |
| 1396 | 1396 | AstNode *set_cold_node; |
| 1397 | 1397 | const AstNode *inferred_async_node; |
| 1398 | 1398 | ZigFn *inferred_async_fn; |
| 1399 | AstNode *non_async_node; | |
| 1399 | 1400 | |
| 1400 | 1401 | ZigList<GlobalExport> export_list; |
| 1401 | 1402 | ZigList<IrInstructionCallGen *> call_list; |
src/analyze.cpp+9-2| ... | ... | @@ -4144,8 +4144,15 @@ void semantic_analyze(CodeGen *g) { |
| 4144 | 4144 | |
| 4145 | 4145 | // second pass over functions for detecting async |
| 4146 | 4146 | for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { |
| 4147 | ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index); | |
| 4148 | analyze_fn_async(g, fn_entry, true); | |
| 4147 | ZigFn *fn = g->fn_defs.at(g->fn_defs_index); | |
| 4148 | analyze_fn_async(g, fn, true); | |
| 4149 | if (fn_is_async(fn) && fn->non_async_node != nullptr) { | |
| 4150 | ErrorMsg *msg = add_node_error(g, fn->proto_node, | |
| 4151 | buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name))); | |
| 4152 | add_error_note(g, msg, fn->non_async_node, | |
| 4153 | buf_sprintf("required to be non-async here")); | |
| 4154 | add_async_error_notes(g, msg, fn); | |
| 4155 | } | |
| 4149 | 4156 | } |
| 4150 | 4157 | } |
| 4151 | 4158 |
src/ir.cpp+18| ... | ... | @@ -15160,6 +15160,20 @@ no_mem_slot: |
| 15160 | 15160 | return var_ptr_instruction; |
| 15161 | 15161 | } |
| 15162 | 15162 | |
| 15163 | // This function is called when a comptime value becomes accessible at runtime. | |
| 15164 | static void mark_comptime_value_escape(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *val) { | |
| 15165 | ir_assert(value_is_comptime(val), source_instr); | |
| 15166 | if (val->special == ConstValSpecialUndef) | |
| 15167 | return; | |
| 15168 | ||
| 15169 | if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) { | |
| 15170 | ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); | |
| 15171 | if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) { | |
| 15172 | val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node; | |
| 15173 | } | |
| 15174 | } | |
| 15175 | } | |
| 15176 | ||
| 15163 | 15177 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 15164 | 15178 | IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const) |
| 15165 | 15179 | { |
| ... | ... | @@ -15256,6 +15270,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15256 | 15270 | break; |
| 15257 | 15271 | } |
| 15258 | 15272 | |
| 15273 | if (instr_is_comptime(value)) { | |
| 15274 | mark_comptime_value_escape(ira, source_instr, &value->value); | |
| 15275 | } | |
| 15276 | ||
| 15259 | 15277 | IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope, |
| 15260 | 15278 | source_instr->source_node, ptr, value); |
| 15261 | 15279 | return &store_ptr->base; |
test/compile_errors.zig+15| ... | ... | @@ -2,6 +2,21 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.add( | |
| 6 | "non-async function pointer eventually is inferred to become async", | |
| 7 | \\export fn a() void { | |
| 8 | \\ var non_async_fn: fn () void = undefined; | |
| 9 | \\ non_async_fn = func; | |
| 10 | \\} | |
| 11 | \\fn func() void { | |
| 12 | \\ suspend; | |
| 13 | \\} | |
| 14 | , | |
| 15 | "tmp.zig:5:1: error: 'func' cannot be async", | |
| 16 | "tmp.zig:3:20: note: required to be non-async here", | |
| 17 | "tmp.zig:6:5: note: suspends here", | |
| 18 | ); | |
| 19 | ||
| 5 | 20 | cases.add( |
| 6 | 21 | "bad alignment in @asyncCall", |
| 7 | 22 | \\export fn entry() void { |