destructors now work with overloaded assignment operators; fixes #2811; fixes #1632

This commit is contained in:
Araq 2015-08-05 21:27:53 +02:00
commit 0d8942d45e
7 changed files with 175 additions and 15 deletions

View file

@ -369,6 +369,15 @@ proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
else:
result.add identDefs
proc addDefer(c: PContext; result: var PNode; s: PSym) =
let deferDestructorCall = createDestructorCall(c, s)
if deferDestructorCall != nil:
if result.kind != nkStmtList:
let oldResult = result
result = newNodeI(nkStmtList, result.info)
result.add oldResult
result.add deferDestructorCall
proc isDiscardUnderscore(v: PSym): bool =
if v.name.s == "_":
v.flags.incl(sfGenSym)
@ -469,6 +478,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if def.kind == nkPar: v.ast = def[j]
v.typ = tup.sons[j]
b.sons[j] = newSymNode(v)
addDefer(c, result, v)
checkNilable(v)
if sfCompileTime in v.flags: hasCompileTime = true
if hasCompileTime: vm.setupCompileTimeVar(c.module, result)
@ -1371,7 +1381,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
for i in countup(0, length - 1):
let k = n.sons[i].kind
case k
of nkFinally, nkExceptBranch, nkDefer:
of nkFinally, nkExceptBranch:
# stand-alone finally and except blocks are
# transformed into regular try blocks:
#
@ -1424,14 +1434,6 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
n.typ = n.sons[i].typ
if not isEmptyType(n.typ): n.kind = nkStmtListExpr
case n.sons[i].kind
of nkVarSection, nkLetSection:
let (outer, inner) = insertDestructors(c, n.sons[i])
if outer != nil:
n.sons[i] = outer
var rest = newNode(nkStmtList, n.info, n.sons[i+1 .. length-1])
inner.addSon(semStmtList(c, rest, flags))
n.sons.setLen(i+1)
return
of LastBlockStmts:
for j in countup(i + 1, length - 1):
case n.sons[j].kind