summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-08-12 13:58:35 +0200
committerAraq <rumpf_a@web.de>2019-08-12 13:58:35 +0200
commit289b5e9ef93cd350e75f4d90d264e56df64c5a8d (patch)
tree21f47f7c927cb3e9cde69cdd4e52c39c81cc99a5 /compiler
parentc9c28bf85ee428e710a510a9825e514d30b0e298 (diff)
downloadNim-289b5e9ef93cd350e75f4d90d264e56df64c5a8d.tar.gz
fixes #11254
Diffstat (limited to 'compiler')
-rw-r--r--compiler/injectdestructors.nim11
-rw-r--r--compiler/sempass2.nim10
-rw-r--r--compiler/types.nim11
3 files changed, 20 insertions, 12 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 6f1da37fb..4f96d236f 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -437,17 +437,6 @@ proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
      localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
          "` is already consumed at " & toFileLineCol(c. graph.config, s.info))
 
-proc isSinkTypeForParam(t: PType): bool =
-  # a parameter like 'seq[owned T]' must not be used only once, but its
-  # elements must, so we detect this case here:
-  result = t.skipTypes({tyGenericInst, tyAlias}).kind in {tySink, tyOwned}
-  when false:
-    if isSinkType(t):
-      if t.skipTypes({tyGenericInst, tyAlias}).kind in {tyArray, tyVarargs, tyOpenArray, tySequence}:
-        result = false
-      else:
-        result = true
-
 proc passCopyToSink(n: PNode; c: var Con): PNode =
   result = newNodeIT(nkStmtListExpr, n.info, n.typ)
   let tmp = getTemp(c, n.typ, n.info)
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 8252a7857..c31f86f98 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -34,7 +34,7 @@ In the construct let/var x = expr() x's type is marked.
 
 In x = y the type of x is marked.
 
-For every sink parameter of type T T is marked. TODO!
+For every sink parameter of type T T is marked.
 
 For every call f() the return type of f() is marked.
 
@@ -977,6 +977,14 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
   var t: TEffects
   initEffects(g, effects, s, t, c)
   track(t, body)
+
+  if s.kind != skMacro:
+    let params = s.typ.n
+    for i in 1 ..< params.len:
+      let param = params[i].sym
+      if isSinkTypeForParam(param.typ):
+        createTypeBoundOps(t.graph, t.c, param.typ, param.info)
+
   if not isEmptyType(s.typ.sons[0]) and
       ({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
       s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and
diff --git a/compiler/types.nim b/compiler/types.nim
index fcf21fc54..11006de30 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1600,3 +1600,14 @@ proc isException*(t: PType): bool =
     if t.sons[0] == nil: break
     t = skipTypes(t.sons[0], abstractPtrs)
   return false
+
+proc isSinkTypeForParam*(t: PType): bool =
+  # a parameter like 'seq[owned T]' must not be used only once, but its
+  # elements must, so we detect this case here:
+  result = t.skipTypes({tyGenericInst, tyAlias}).kind in {tySink, tyOwned}
+  when false:
+    if isSinkType(t):
+      if t.skipTypes({tyGenericInst, tyAlias}).kind in {tyArray, tyVarargs, tyOpenArray, tySequence}:
+        result = false
+      else:
+        result = true