summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/destroyer.nim18
-rw-r--r--compiler/semasgn.nim29
-rw-r--r--compiler/semexprs.nim13
-rw-r--r--tests/destructor/tcustomstrings.nim10
-rw-r--r--tests/destructor/topttree.nim6
5 files changed, 16 insertions, 60 deletions
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim
index a868a64ba..36839bf0b 100644
--- a/compiler/destroyer.nim
+++ b/compiler/destroyer.nim
@@ -164,26 +164,22 @@ proc isHarmlessVar*(s: PSym; c: Con): bool =
 template interestingSym(s: PSym): bool =
   s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ)
 
-proc patchHead(n: PNode; alreadyPatched: var IntSet) =
+proc patchHead(n: PNode) =
   if n.kind in nkCallKinds and n[0].kind == nkSym and n.len > 1:
     let s = n[0].sym
-    if sfFromGeneric in s.flags or true:
-      if s.name.s[0] == '=' and not containsOrIncl(alreadyPatched, s.id):
-        patchHead(s.getBody, alreadyPatched)
+    if sfFromGeneric in s.flags and s.name.s[0] == '=' and
+        s.name.s in ["=sink", "=", "=destroy"]:
+      excl(s.flags, sfFromGeneric)
+      patchHead(s.getBody)
       let t = n[1].typ.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred})
       template patch(op, field) =
-        if s.name.s == op and field != nil: #and field != s:
+        if s.name.s == op and field != nil and field != s:
           n.sons[0].sym = field
       patch "=sink", t.sink
       patch "=", t.assignment
       patch "=destroy", t.destructor
   for x in n:
-    patchHead(x, alreadyPatched)
-
-template patchHead(n: PNode) =
-  when false:
-    var alreadyPatched = initIntSet()
-    patchHead(n, alreadyPatched)
+    patchHead(x)
 
 proc genSink(t: PType; dest: PNode): PNode =
   let t = t.skipTypes({tyGenericInst, tyAlias})
diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim
index 0454ea379..5ae9feec2 100644
--- a/compiler/semasgn.nim
+++ b/compiler/semasgn.nim
@@ -314,24 +314,6 @@ proc overloadedAsgn(c: PContext; dest, src: PNode): PNode =
   let a = getAsgnOrLiftBody(c, dest.typ, dest.info)
   result = newAsgnCall(c, a, dest, src)
 
-proc patchHead(n: PNode; alreadyPatched: var IntSet) =
-  when true:
-    if n.kind in nkCallKinds and n[0].kind == nkSym and n.len > 1:
-      let s = n[0].sym
-      if sfFromGeneric in s.flags:
-        if not containsOrIncl(alreadyPatched, s.id):
-          patchHead(s.getBody, alreadyPatched)
-        let t = n[1].typ.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred})
-        template patch(op, field) =
-          if s.name.s == op and field != nil and field != s:
-            n.sons[0].sym = field
-
-        patch "=sink", t.sink
-        patch "=", t.assignment
-        patch "=destroy", t.destructor
-    for x in n:
-      patchHead(x, alreadyPatched)
-
 proc liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
   ## In the semantic pass this is called in strategic places
   ## to ensure we lift assignment, destructors and moves properly.
@@ -339,20 +321,9 @@ proc liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
   if not newDestructors or not hasDestructor(typ): return
   let typ = typ.skipTypes({tyGenericInst, tyAlias})
   # we generate the destructor first so that other operators can depend on it:
-  var changed = false
-  if typ.destructor != nil and typ.destructor.magic == mAsgn:
-    typ.destructor = nil
   if typ.destructor == nil:
     liftBody(c, typ, attachedDestructor, info)
-    changed = true
   if typ.assignment == nil:
     liftBody(c, typ, attachedAsgn, info)
-    changed = true
   if typ.sink == nil:
     liftBody(c, typ, attachedSink, info)
-    changed = true
-  if changed:
-    var alreadyPatched = initIntSet()
-    patchHead(typ.destructor.getBody, alreadyPatched)
-    patchHead(typ.assignment.getBody, alreadyPatched)
-    patchHead(typ.sink.getBody, alreadyPatched)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 2c80db52c..49dfbe8f4 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -664,19 +664,6 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
   of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
   of skTemplate: result = semTemplateExpr(c, result, callee, flags)
   else:
-    when false:
-      if callee.name.s[0] == '=' and result.len > 1:
-        # careful, do not skip tyDistinct here:
-        let t = result[1].typ.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred})
-
-        proc patchHead(callee: PSym; name: string; field: PSym; result: PNode) =
-          if callee.name.s == name and field != nil:
-            result.sons[0].sym = field
-
-        patchHead(callee, "=destroy", t.destructor, result)
-        patchHead(callee, "=sink", t.sink, result)
-        patchHead(callee, "=", t.assignment, result)
-
     semFinishOperands(c, result)
     activate(c, result)
     fixAbstractType(c, result)
diff --git a/tests/destructor/tcustomstrings.nim b/tests/destructor/tcustomstrings.nim
index 449a1e9f2..1a78df20b 100644
--- a/tests/destructor/tcustomstrings.nim
+++ b/tests/destructor/tcustomstrings.nim
@@ -8,6 +8,8 @@ after 20 20'''
   cmd: '''nim c --newruntime $file'''
 """
 
+{.this: self.}
+
 type
   mystring = object
     len, cap: int
@@ -46,10 +48,10 @@ proc `=`*(a: var mystring; b: mystring) =
     copyMem(a.data, b.data, a.cap+1)
 
 proc resize(self: var mystring) =
-  if cap == 0: cap = 8
-  else: cap = (cap * 3) shr 1
-  if data == nil: inc allocCount
-  data = cast[type(data)](realloc(data, cap + 1))
+  if self.cap == 0: self.cap = 8
+  else: self.cap = (self.cap * 3) shr 1
+  if self.data == nil: inc allocCount
+  self.data = cast[type(data)](realloc(self.data, self.cap + 1))
 
 proc add*(self: var mystring; c: char) =
   if self.len >= self.cap: resize(self)
diff --git a/tests/destructor/topttree.nim b/tests/destructor/topttree.nim
index a6380a2d5..45f2f66e6 100644
--- a/tests/destructor/topttree.nim
+++ b/tests/destructor/topttree.nim
@@ -3,7 +3,7 @@ discard """
 60.0
 90.0
 120.0
-4 1'''
+4 4'''
   cmd: '''nim c --newruntime $file'''
 """
 
@@ -18,8 +18,8 @@ var
 
 proc `=destroy`*[T](x: var opt[T]) =
   if x.data != nil:
-    when not supportsCopyMem(T):
-      `=destroy`(x.data[])
+    #when not supportsCopyMem(T):
+    `=destroy`(x.data[])
     dealloc(x.data)
     inc deallocCount
     x.data = nil