diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-10-14 09:32:57 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-10-14 20:37:49 +0200 |
commit | 8780d25e038ed6ca6815f3ed4aa6a7a58416714b (patch) | |
tree | ffa8aa46e6821e084673f0278a47fac1423566ee /compiler | |
parent | 4eaa2bf15d1f59311b2fb7efac39cd652f9b2a42 (diff) | |
download | Nim-8780d25e038ed6ca6815f3ed4aa6a7a58416714b.tar.gz |
minor refactorings for better destructors
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/nversion.nim | 2 | ||||
-rw-r--r-- | compiler/rodread.nim | 7 | ||||
-rw-r--r-- | compiler/rodwrite.nim | 8 | ||||
-rw-r--r-- | compiler/semasgn.nim | 6 | ||||
-rw-r--r-- | compiler/semstmts.nim | 27 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 16 |
7 files changed, 51 insertions, 17 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index a6f774790..6519b698a 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1081,7 +1081,7 @@ proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym, result.info = info result.options = gOptions result.owner = owner - result.offset = - 1 + result.offset = -1 result.id = getID() when debugIds: registerId(result) diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 4d4fe6c95..85265a7c0 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -13,5 +13,5 @@ const MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets? VersionAsString* = system.NimVersion - RodFileVersion* = "1222" # modify this if the rod-format changes! + RodFileVersion* = "1223" # modify this if the rod-format changes! diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 31b54d760..2546aa77a 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -336,10 +336,13 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType = if r.s[r.pos] == '\17': inc(r.pos) result.assignment = rrGetSym(r, decodeVInt(r.s, r.pos), info) - while r.s[r.pos] == '\18': + if r.s[r.pos] == '\18': + inc(r.pos) + result.sink = rrGetSym(r, decodeVInt(r.s, r.pos), info) + while r.s[r.pos] == '\19': inc(r.pos) let x = decodeVInt(r.s, r.pos) - doAssert r.s[r.pos] == '\19' + doAssert r.s[r.pos] == '\20' inc(r.pos) let y = rrGetSym(r, decodeVInt(r.s, r.pos), info) result.methods.safeAdd((x, y)) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index fb50c6473..1bc136acf 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -245,10 +245,14 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = add(result, '\17') encodeVInt(t.assignment.id, result) pushSym(w, t.assignment) - for i, s in items(t.methods): + if t.sink != nil: add(result, '\18') - encodeVInt(i, result) + encodeVInt(t.sink.id, result) + pushSym(w, t.sink) + for i, s in items(t.methods): add(result, '\19') + encodeVInt(i, result) + add(result, '\20') encodeVInt(s.id, result) pushSym(w, s) encodeLoc(w, t.loc, result) diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index dbb2a140b..caed11341 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -92,13 +92,13 @@ proc newAsgnStmt(le, ri: PNode): PNode = result.sons[0] = le result.sons[1] = ri -proc newDestructorCall(op: PSym; x: PNode): PNode = +proc newOpCall(op: PSym; x: PNode): PNode = result = newNodeIT(nkCall, x.info, op.typ.sons[0]) result.add(newSymNode(op)) result.add x proc newDeepCopyCall(op: PSym; x, y: PNode): PNode = - result = newAsgnStmt(x, newDestructorCall(op, y)) + result = newAsgnStmt(x, newOpCall(op, y)) proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool = case c.kind @@ -107,7 +107,7 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool = if op != nil: markUsed(c.info, op, c.c.graph.usageSym) styleCheckUse(c.info, op) - body.add newDestructorCall(op, x) + body.add newOpCall(op, x) result = true of attachedAsgn: if tfHasAsgn in t.flags: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3e6e918f1..c6e03cef3 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1277,9 +1277,30 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) = proc semOverride(c: PContext, s: PSym, n: PNode) = case s.name.s.normalize of "destroy", "=destroy": - doDestructorStuff(c, s, n) - if not newDestructors and not experimentalMode(c): - localError n.info, "use the {.experimental.} pragma to enable destructors" + if newDestructors: + let t = s.typ + var noError = false + if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar: + var obj = t.sons[1].sons[0] + while true: + incl(obj.flags, tfHasAsgn) + if obj.kind == tyGenericBody: obj = obj.lastSon + elif obj.kind == tyGenericInvocation: obj = obj.sons[0] + else: break + if obj.kind in {tyObject, tyDistinct}: + if obj.destructor.isNil: + obj.destructor = s + else: + localError(n.info, errGenerated, + "cannot bind another '" & s.name.s & "' to: " & typeToString(obj)) + noError = true + if not noError: + localError(n.info, errGenerated, + "signature for '" & s.name.s & "' must be proc[T: object](x: var T)") + else: + doDestructorStuff(c, s, n) + if not experimentalMode(c): + localError n.info, "use the {.experimental.} pragma to enable destructors" incl(s.flags, sfUsed) of "deepcopy", "=deepcopy": if s.typ.len == 2 and diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index a3953d87e..172a557b3 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -357,11 +357,17 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = assert newbody.kind in {tyRef, tyPtr} assert newbody.lastSon.typeInst == nil newbody.lastSon.typeInst = result - let asgn = newbody.assignment - if asgn != nil and sfFromGeneric notin asgn.flags: - # '=' needs to be instantiated for generics when the type is constructed: - newbody.assignment = cl.c.instTypeBoundOp(cl.c, asgn, result, cl.info, - attachedAsgn, 1) + template typeBound(field) = + let opr = newbody.field + if opr != nil and sfFromGeneric notin opr.flags: + # '=' needs to be instantiated for generics when the type is constructed: + newbody.field = cl.c.instTypeBoundOp(cl.c, opr, result, cl.info, + attachedAsgn, 1) + # we need to produce the destructor first here because generated '=' + # and '=sink' operators can rely on it: + if newDestructors: typeBound(destructor) + typeBound(assignment) + typeBound(sink) let methods = skipTypes(bbody, abstractPtrs).methods for col, meth in items(methods): # we instantiate the known methods belonging to that type, this causes |