Commit e11cafbd4f

Andrew Kelley <andrew@ziglang.org>
2019-08-07 16:56:37
cancel works on non-pointers
1 parent f587fa1
Changed files (2)
src
test
stage1
behavior
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))
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();
+}