diff options
-rw-r--r-- | compiler/destroyer.nim | 18 | ||||
-rw-r--r-- | compiler/semasgn.nim | 29 | ||||
-rw-r--r-- | compiler/semexprs.nim | 13 | ||||
-rw-r--r-- | tests/destructor/tcustomstrings.nim | 10 | ||||
-rw-r--r-- | tests/destructor/topttree.nim | 6 |
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 |