summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorcooldome <cdome@bk.ru>2019-08-28 11:07:46 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-08-28 12:07:46 +0200
commitc9f49cbc0a9314585ca70b3365e49ab82dfdcc13 (patch)
treef0ec679d11911e59665d822206709713a958b467
parent84351da9d85867083de9376f7e08b1c840be6bc0 (diff)
downloadNim-c9f49cbc0a9314585ca70b3365e49ab82dfdcc13.tar.gz
lift destructor for openarray (#12073)
* destroy for sink openarray
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/ccgtypes.nim4
-rw-r--r--compiler/liftdestructors.nim8
-rw-r--r--compiler/sem.nim10
-rw-r--r--tests/destructor/tmove_objconstr.nim17
5 files changed, 30 insertions, 13 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index ddf81c874..6e5006bb7 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1496,14 +1496,14 @@ proc propagateToOwner*(owner, elem: PType) =
   if tfHasAsgn in elem.flags:
     let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
     if o2.kind in {tyTuple, tyObject, tyArray,
-                   tySequence, tyOpt, tySet, tyDistinct}:
+                   tySequence, tyOpt, tySet, tyDistinct, tyOpenArray, tyVarargs}:
       o2.flags.incl tfHasAsgn
       owner.flags.incl tfHasAsgn
 
   if tfHasOwned in elem.flags:
     let o2 = owner.skipTypes({tyGenericInst, tyAlias, tySink})
     if o2.kind in {tyTuple, tyObject, tyArray,
-                   tySequence, tyOpt, tySet, tyDistinct}:
+                   tySequence, tyOpt, tySet, tyDistinct, tyOpenArray, tyVarargs}:
       o2.flags.incl tfHasOwned
       owner.flags.incl tfHasOwned
 
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 584e69b30..1e3826780 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -469,7 +469,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
     add(params, param.loc.r)
     # declare the len field for open arrays:
     var arr = param.typ
-    if arr.kind in {tyVar, tyLent}: arr = arr.lastSon
+    if arr.kind in {tyVar, tyLent, tySink}: arr = arr.lastSon
     var j = 0
     while arr.kind in {tyOpenArray, tyVarargs}:
       # this fixes the 'sort' bug:
@@ -477,7 +477,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
       # need to pass hidden parameter:
       addf(params, ", NI $1Len_$2", [param.loc.r, j.rope])
       inc(j)
-      arr = arr.sons[0]
+      arr = arr.sons[0].skipTypes({tySink})
   if t.sons[0] != nil and isInvalidReturnType(m.config, t.sons[0]):
     var arr = t.sons[0]
     if params != nil: add(params, ", ")
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index abd294e5a..71f0baecf 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -506,7 +506,11 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   of tyTuple:
     fillBodyTup(c, t, body, x, y)
   of tyVarargs, tyOpenArray:
-    localError(c.g.config, c.info, "cannot copy openArray")
+    if c.kind == attachedDestructor:
+      forallElements(c, t, body, x, y)
+    else:
+      discard "cannot copy openArray"
+
   of tyFromExpr, tyProxy, tyBuiltInTypeClass, tyUserTypeClass,
      tyUserTypeClassInst, tyCompositeTypeClass, tyAnd, tyOr, tyNot, tyAnything,
      tyGenericParam, tyGenericBody, tyNil, tyUntyped, tyTyped,
@@ -626,7 +630,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
   var canon = g.canonTypes.getOrDefault(h)
   var overwrite = false
   if canon == nil:
-    let typ = orig.skipTypes({tyGenericInst, tyAlias})
+    let typ = orig.skipTypes({tyGenericInst, tyAlias, tySink})
     g.canonTypes[h] = typ
     canon = typ
   elif canon != orig:
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 7c47dac22..70a84501f 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -77,14 +77,12 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
       discard safeSemExpr(c, n)
 
 proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
-  result = arg
-  let x = result.skipConv
+  let x = arg.skipConv
   if x.kind in {nkPar, nkTupleConstr, nkCurly} and formal.kind != tyUntyped:
     changeType(c, x, formal, check=true)
-  else:
-    result = skipHiddenSubConv(result)
-    #result.typ = takeType(formal, arg.typ)
-    #echo arg.info, " picked ", result.typ.typeToString
+  result = arg
+  result = skipHiddenSubConv(result)
+
 
 proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
   if arg.typ.isNil:
diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim
index bfc819ceb..be92d1503 100644
--- a/tests/destructor/tmove_objconstr.nim
+++ b/tests/destructor/tmove_objconstr.nim
@@ -175,4 +175,19 @@ proc myfuncLoop(x: int): MySeqNonCopyable =
     var cc = newMySeq(i, 5.0)
     result = cc
 
-discard myfuncLoop(3)
\ No newline at end of file
+discard myfuncLoop(3)
+
+#------------------------------------------------------------
+# Move into table via openarray
+#------------------------------------------------------------
+
+type
+  TableNonCopyable = object
+    x: seq[(string, MySeqNonCopyable)]
+
+proc toTable(pairs: sink openArray[(string, MySeqNonCopyable)]): TableNonCopyable =
+  discard
+
+
+let mytable = {"a": newMySeq(2, 5.0)}.toTable
+