From 69fe7070250e0dbbcc0fafff4e341d1d805b7d59 Mon Sep 17 00:00:00 2001 From: cooldome Date: Mon, 9 Nov 2020 11:26:12 +0000 Subject: [PATCH] Fix 15629 (#15888) * fix #15858 * fix space * fix #15629 * Revert "fix space" * Revert "fix #15858" --- compiler/varpartitions.nim | 23 +++++++++++++---------- tests/arc/topt_cursor2.nim | 29 +++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 34a64c7595..2e781c0419 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -45,6 +45,8 @@ proc `<`(a, b: AbstractTime): bool {.borrow.} proc inc(x: var AbstractTime; diff = 1) {.borrow.} proc dec(x: var AbstractTime; diff = 1) {.borrow.} +proc `$`(x: AbstractTime): string {.borrow.} + type SubgraphFlag = enum isMutated, # graph might be mutated @@ -591,33 +593,34 @@ proc deps(c: var Partitions; dest, src: PNode) = for s in sources: connect(c, t, s, dest.info) - if cursorInference in c.goals and src.kind != nkEmpty: - if dest.kind == nkSym: - let vid = variableId(c, dest.sym) + if cursorInference in c.goals and src.kind != nkEmpty: + let d = pathExpr(dest, c.owner) + if d != nil and d.kind == nkSym: + let vid = variableId(c, d.sym) if vid >= 0: destMightOwn(c, c.s[vid], src) for s in sources: - if s == dest.sym: + if s == d.sym: discard "assignments like: it = it.next are fine" elif {sfGlobal, sfThread} * s.flags != {} or hasDisabledAsgn(s.typ): # do not borrow from a global variable or from something with a # disabled assignment operator. c.s[vid].flags.incl preventCursor - when explainCursors: echo "A not a cursor: ", dest.sym, " ", s + when explainCursors: echo "A not a cursor: ", d.sym, " ", s else: let srcid = variableId(c, s) if srcid >= 0: if s.kind notin {skResult, skParam} and ( c.s[srcid].aliveEnd < c.s[vid].aliveEnd): # you cannot borrow from a local that lives shorter than 'vid': - when explainCursors: echo "B not a cursor ", dest.sym, " ", c.s[srcid].aliveEnd, " ", c.s[vid].aliveEnd + when explainCursors: echo "B not a cursor ", d.sym, " ", c.s[srcid].aliveEnd, " ", c.s[vid].aliveEnd c.s[vid].flags.incl preventCursor elif {isReassigned, preventCursor} * c.s[srcid].flags != {}: # you cannot borrow from something that is re-assigned: - when explainCursors: echo "C not a cursor ", dest.sym, " ", c.s[srcid].flags, " reassignedTo ", c.s[srcid].reassignedTo + when explainCursors: echo "C not a cursor ", d.sym, " ", c.s[srcid].flags, " reassignedTo ", c.s[srcid].reassignedTo c.s[vid].flags.incl preventCursor - elif c.s[srcid].reassignedTo != 0 and c.s[srcid].reassignedTo != dest.sym.id: - when explainCursors: echo "D not a cursor ", dest.sym, " reassignedTo ", c.s[srcid].reassignedTo + elif c.s[srcid].reassignedTo != 0 and c.s[srcid].reassignedTo != d.sym.id: + when explainCursors: echo "D not a cursor ", d.sym, " reassignedTo ", c.s[srcid].reassignedTo c.s[vid].flags.incl preventCursor const @@ -900,4 +903,4 @@ proc computeCursors*(s: PSym; n: PNode; config: ConfigRef) = discard "cannot cursor into a graph that is mutated" else: v.sym.flags.incl sfCursor - #echo "this is now a cursor ", v.sym, " ", par.s[rid].flags, " ", config $ v.sym.info + #echo "this is now a cursor ", v.sym, " ", par.s[rid].flags, " ", config $ v.sym.info \ No newline at end of file diff --git a/tests/arc/topt_cursor2.nim b/tests/arc/topt_cursor2.nim index 2e6fb256f9..4b566ed24e 100644 --- a/tests/arc/topt_cursor2.nim +++ b/tests/arc/topt_cursor2.nim @@ -1,6 +1,8 @@ -discard """ - output: '''emptyemptyempty''' +discard """ cmd: '''nim c --gc:arc $file''' + output: '''emptyemptyempty +inner destroy +''' """ # bug #15039 @@ -49,3 +51,26 @@ proc parse() = echo children parse() + + +#------------------------------------------------------------------------------ +# issue #15629 + +type inner = object +type outer = ref inner + +proc `=destroy`(b: var inner) = + echo "inner destroy" + +proc newOuter(): outer = + new(result) + +type holder = object + contents: outer + +proc main() = + var t: holder + t.contents = newOuter() + +main() +