summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorcooldome <ariabushenko@gmail.com>2020-11-05 22:29:05 +0000
committerGitHub <noreply@github.com>2020-11-05 23:29:05 +0100
commitfa5f225efc7161110b0d4cf57e86646f2b0d97f8 (patch)
tree829d8ec453862006a98fdf7c070a5570016791fb
parentd1bea1f71f0318f08ddd80b75706a602753b55d4 (diff)
downloadNim-fa5f225efc7161110b0d4cf57e86646f2b0d97f8.tar.gz
fix #15609 (#15856)
* fix #15609

* fix test
-rw-r--r--compiler/injectdestructors.nim19
-rw-r--r--tests/arc/tmovebug.nim33
2 files changed, 42 insertions, 10 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index 0b893ede8..7e64ebfdc 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -824,14 +824,10 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
     of nkAsgn, nkFastAsgn:
       if hasDestructor(c, n[0].typ) and n[1].kind notin {nkProcDef, nkDo, nkLambda} and
           not isCursor(n[0], c):
-        # rule (self-assignment-removal):
-        if n[1].kind == nkSym and n[0].kind == nkSym and n[0].sym == n[1].sym:
-          result = newNodeI(nkEmpty, n.info)
-        else:
-          if n[0].kind in {nkDotExpr, nkCheckedFieldExpr}:
-            cycleCheck(n, c)
-          assert n[1].kind notin {nkAsgn, nkFastAsgn}
-          result = moveOrCopy(p(n[0], c, s, mode), n[1], c, s)
+        if n[0].kind in {nkDotExpr, nkCheckedFieldExpr}:
+          cycleCheck(n, c)
+        assert n[1].kind notin {nkAsgn, nkFastAsgn}
+        result = moveOrCopy(p(n[0], c, s, mode), n[1], c, s)
       elif isDiscriminantField(n[0]):
         result = c.genDiscriminantAsgn(s, n)
       else:
@@ -954,8 +950,11 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
       result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
   of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
     result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
-  of nkSym:
-    if isSinkParam(ri.sym) and isLastRead(ri, c):
+  of nkSym:            
+    if dest.kind == nkSym and dest.sym == ri.sym:
+      # rule (self-assignment-removal):
+      result = newNodeI(nkEmpty, dest.info)
+    elif isSinkParam(ri.sym) and isLastRead(ri, c):
       # Rule 3: `=sink`(x, z); wasMoved(z)
       let snk = c.genSink(dest, ri, isDecl)
       result = newTree(nkStmtList, snk, c.genWasMoved(ri))
diff --git a/tests/arc/tmovebug.nim b/tests/arc/tmovebug.nim
index 3b7a7c5df..61105b44e 100644
--- a/tests/arc/tmovebug.nim
+++ b/tests/arc/tmovebug.nim
@@ -70,6 +70,9 @@ king
 hi
 try
 bye
+()
+()
+()
 '''
 """
 
@@ -524,3 +527,33 @@ proc getScope2(): string =
     "else"
 
 echo getScope2()
+
+
+#--------------------------------------------------------------------
+#bug  #15609
+
+type
+  Wrapper = object
+    discard
+
+proc newWrapper(): ref Wrapper =
+  new(result)
+  result
+
+
+proc newWrapper2(a: int): ref Wrapper =
+  new(result)
+  if a > 0:
+    result
+  else:
+    new(Wrapper)
+
+
+let w1 = newWrapper()
+echo $w1[]
+
+let w2 = newWrapper2(1)
+echo $w2[]
+
+let w3 = newWrapper2(-1)
+echo $w3[]
\ No newline at end of file