summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-12-15 13:54:41 +0100
committerAndreas Rumpf <rumpf_a@web.de>2018-12-15 13:54:41 +0100
commite3a668a33baaf9d89b287827eaab3fa1cdfec877 (patch)
treebf374e97230a61d036176638bcaf7798d70985d3 /compiler
parent446f911a173a595648fa444c83d931193198eeb6 (diff)
downloadNim-e3a668a33baaf9d89b287827eaab3fa1cdfec877.tar.gz
--gc:destructors: baby steps
Diffstat (limited to 'compiler')
-rw-r--r--compiler/destroyer.nim23
-rw-r--r--compiler/semstmts.nim9
-rw-r--r--compiler/semtypes.nim5
3 files changed, 22 insertions, 15 deletions
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim
index 40af11e70..03ce9a5cf 100644
--- a/compiler/destroyer.nim
+++ b/compiler/destroyer.nim
@@ -296,7 +296,8 @@ proc makePtrType(c: Con, baseType: PType): PType =
 template genOp(opr, opname, ri) =
   let op = opr
   if op == nil:
-    globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t))
+    globalError(c.graph.config, dest.info, "internal error: '" & opname &
+      "' operator not found for type " & typeToString(t))
   elif op.ast[genericParamsPos].kind != nkEmpty:
     globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
   patchHead op
@@ -365,7 +366,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode =
   result.add genWasMoved(n, c)
   result.add tempAsNode
 
-proc sinkParamIsLastReadCheck(c: var Con, s: PNode) = 
+proc sinkParamIsLastReadCheck(c: var Con, s: PNode) =
   assert s.kind == nkSym and s.sym.kind == skParam
   if not isLastRead(s, c):
      localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s &
@@ -427,7 +428,7 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
       result = copyNode(arg)
       for i in 0..<arg.len:
         var branch = copyNode(arg[i])
-        if arg[i].kind in {nkElifBranch, nkElifExpr}:   
+        if arg[i].kind in {nkElifBranch, nkElifExpr}:
           branch.add p(arg[i][0], c)
           branch.add pArgIfTyped(arg[i][1])
         else:
@@ -442,13 +443,13 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
           branch = arg[i] # of branch conditions are constants
           branch[^1] = pArgIfTyped(arg[i][^1])
         elif arg[i].kind in {nkElifBranch, nkElifExpr}:
-          branch = copyNode(arg[i])   
+          branch = copyNode(arg[i])
           branch.add p(arg[i][0], c)
           branch.add pArgIfTyped(arg[i][1])
         else:
-          branch = copyNode(arg[i]) 
+          branch = copyNode(arg[i])
           branch.add pArgIfTyped(arg[i][0])
-        result.add branch     
+        result.add branch
     else:
       # an object that is not temporary but passed to a 'sink' parameter
       # results in a copy.
@@ -476,7 +477,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
     result.add ri2
   of nkBracketExpr:
     if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym):
-      # unpacking of tuple: move out the elements 
+      # unpacking of tuple: move out the elements
       result = genSink(c, dest.typ, dest, ri)
     else:
       result = genCopy(c, dest.typ, dest, ri)
@@ -509,11 +510,11 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
         branch = ri[i] # of branch conditions are constants
         branch[^1] = moveOrCopyIfTyped(ri[i][^1])
       elif ri[i].kind in {nkElifBranch, nkElifExpr}:
-        branch = copyNode(ri[i])   
+        branch = copyNode(ri[i])
         branch.add p(ri[i][0], c)
         branch.add moveOrCopyIfTyped(ri[i][1])
       else:
-        branch = copyNode(ri[i]) 
+        branch = copyNode(ri[i])
         branch.add moveOrCopyIfTyped(ri[i][0])
       result.add branch
   of nkBracket:
@@ -550,7 +551,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
       sinkParamIsLastReadCheck(c, ri)
       var snk = genSink(c, dest.typ, dest, ri)
       snk.add ri
-      result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))   
+      result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved))
     elif ri.sym.kind != skParam and isLastRead(ri, c):
       # Rule 3: `=sink`(x, z); wasMoved(z)
       var snk = genSink(c, dest.typ, dest, ri)
@@ -647,7 +648,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
     let params = owner.typ.n
     for i in 1 ..< params.len:
       let param = params[i].sym
-      if param.typ.kind == tySink and hasDestructor(param.typ): 
+      if param.typ.kind == tySink and hasDestructor(param.typ):
         c.destroys.add genDestroy(c, param.typ.skipTypes({tyGenericInst, tyAlias, tySink}), params[i])
 
   let body = p(n, c)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 2d98d84e1..277fbd75f 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1427,6 +1427,12 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
     addResult(c, s.typ.sons[0], n.info, s.kind)
     addResultNode(c, n)
 
+proc canonType(c: PContext, t: PType): PType =
+  if t.kind == tySequence:
+    result = c.graph.sysTypes[tySequence]
+  else:
+    result = t
+
 proc semOverride(c: PContext, s: PSym, n: PNode) =
   case s.name.s.normalize
   of "=destroy":
@@ -1440,6 +1446,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
         elif obj.kind == tyGenericInvocation: obj = obj.sons[0]
         else: break
       if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
+        obj = canonType(c, obj)
         if obj.destructor.isNil:
           obj.destructor = s
         else:
@@ -1491,6 +1498,8 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
           objB = objB.sons[0]
         else: break
       if obj.kind in {tyObject, tyDistinct, tySequence, tyString} and sameType(obj, objB):
+        # attach these ops to the canonical tySequence
+        obj = canonType(c, obj)
         let opr = if s.name.s == "=": addr(obj.assignment) else: addr(obj.sink)
         if opr[].isNil:
           opr[] = s
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 7159e17e7..6c095587a 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1551,10 +1551,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
         # XXX figure out why this has children already...
         result.sons.setLen 0
         result.n = nil
-        if c.config.selectedGc == gcDestructors:
-          result.flags = {tfHasAsgn}
-        else:
-          result.flags = {}
+        result.flags = {tfHasAsgn}
         semContainerArg(c, n, "seq", result)
       else:
         result = semContainer(c, n, tySequence, "seq", prev)