From e11cafbd4f11fa5eae0cbdf03854291834b4cd77 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 7 Aug 2019 10:56:37 -0400 Subject: [PATCH] cancel works on non-pointers --- src/ir.cpp | 16 +++++++++++++--- test/stage1/behavior/cancel.zig | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 853cf4daa..76e8c91f3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7845,7 +7845,7 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) return irb->codegen->invalid_instruction; } - IrInstruction *operand = ir_gen_node(irb, node->data.cancel_expr.expr, scope); + IrInstruction *operand = ir_gen_node_extra(irb, node->data.cancel_expr.expr, scope, LValPtr, nullptr); if (operand == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; @@ -24496,10 +24496,20 @@ static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, } static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { - IrInstruction *frame = instruction->frame->child; - if (type_is_invalid(frame->value.type)) + IrInstruction *frame_ptr = instruction->frame->child; + if (type_is_invalid(frame_ptr->value.type)) return ira->codegen->invalid_instruction; + IrInstruction *frame; + if (frame_ptr->value.type->id == ZigTypeIdPointer && + frame_ptr->value.type->data.pointer.ptr_len == PtrLenSingle && + frame_ptr->value.type->data.pointer.child_type->id == ZigTypeIdCoroFrame) + { + frame = frame_ptr; + } else { + frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); + } + ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); if (type_is_invalid(casted_frame->value.type)) diff --git a/test/stage1/behavior/cancel.zig b/test/stage1/behavior/cancel.zig index c8636212b..b546857ae 100644 --- a/test/stage1/behavior/cancel.zig +++ b/test/stage1/behavior/cancel.zig @@ -92,3 +92,19 @@ async fn b4() void { } suspend; } + +test "cancel on a non-pointer" { + const S = struct { + fn doTheTest() void { + _ = async atest(); + } + fn atest() void { + var f = async func(); + cancel f; + } + fn func() void { + suspend; + } + }; + S.doTheTest(); +}