summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/injectdestructors.nim3
-rw-r--r--compiler/lowerings.nim1
-rw-r--r--tests/destructor/tasync_prototype.nim54
3 files changed, 57 insertions, 1 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 8a9b5d7b8..18fb0f5c8 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -422,7 +422,8 @@ proc cycleCheck(n: PNode; c: var Con) =
   var field: PNode = nil
   while true:
     if x.kind == nkDotExpr:
-      if field == nil: field = x[1]
+      field = x[1]
+      if field.kind == nkSym and sfCursor in field.sym.flags: return
       x = x[0]
     elif x.kind in {nkBracketExpr, nkCheckedFieldExpr, nkDerefExpr, nkHiddenDeref}:
       x = x[0]
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index 894efab5c..ac29d600b 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -215,6 +215,7 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
   assert t.kind != tyTyped
   propagateToOwner(obj, t)
   field.position = obj.n.len
+  field.flags = s.flags * {sfCursor}
   obj.n.add newSymNode(field)
   fieldCheck()
 
diff --git a/tests/destructor/tasync_prototype.nim b/tests/destructor/tasync_prototype.nim
new file mode 100644
index 000000000..bd80adf0c
--- /dev/null
+++ b/tests/destructor/tasync_prototype.nim
@@ -0,0 +1,54 @@
+discard """
+  output: '''asdas
+processClient end
+false
+MEMORY 0
+'''
+  cmd: '''nim c --gc:arc $file'''
+"""
+
+type
+  PAsyncHttpServer = ref object
+    value: string
+  PFutureBase {.acyclic.} = ref object
+    callback: proc () {.closure.}
+    value: string
+    failed: bool
+
+proc accept(server: PAsyncHttpServer): PFutureBase =
+  new(result)
+  result.callback = proc () =
+    discard
+  server.value = "hahaha"
+
+proc processClient(): PFutureBase =
+  new(result)
+
+proc serve(server: PAsyncHttpServer): PFutureBase =
+  iterator serveIter(): PFutureBase {.closure.} =
+    echo server.value
+    while true:
+      var acceptAddrFut = server.accept()
+      yield acceptAddrFut
+      var fut = acceptAddrFut.value
+
+      var f {.cursor.} = processClient()
+      when true:
+        f.callback =
+          proc () =
+            echo("processClient end")
+            echo(f.failed)
+      yield f
+  var x = serveIter
+  for i in 0 .. 1:
+    result = x()
+    if result.callback != nil:
+      result.callback()
+
+let mem = getOccupiedMem()
+
+proc main =
+  discard serve(PAsyncHttpServer(value: "asdas"))
+
+main()
+echo "MEMORY ", getOccupiedMem() - mem