diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 85a9ccf42..d07122552 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -628,7 +628,7 @@ proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool = # XXX Allow closure deref operations here if we know # the owner controlled the closure allocation? result = n.kind == nkSym and n.sym.owner == owner and - sfGlobal notin n.sym.flags and + {sfGlobal, sfThread, sfCursor} * n.sym.flags == {} and (n.sym.kind != skParam or isSinkParam(n.sym)) # or n.sym.typ.kind == tyVar) # Note: There is a different move analyzer possible that checks for # consume(param.key); param.key = newValue for all paths. Then code like diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 7a6cc4f63..4535c9aac 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -48,7 +48,7 @@ type s: seq[VarIndex] graphs: seq[MutationInfo] unanalysableMutation, performCursorInference: bool - inAsgnSource: int + inAsgnSource, inConstructor: int proc `$`*(config: ConfigRef; g: MutationInfo): string = result = "" @@ -264,8 +264,10 @@ proc analyseAsgn(c: var Partitions; dest: var VarIndex; n: PNode) = dest.flags.incl ownsData of nkCurly, nkBracket, nkPar, nkTupleConstr: + inc c.inConstructor for son in n: analyseAsgn(c, dest, son) + dec c.inConstructor if n.typ.skipTypes(abstractInst).kind == tySequence: # you must destroy a sequence: dest.flags.incl ownsData @@ -278,6 +280,8 @@ proc analyseAsgn(c: var Partitions; dest: var VarIndex; n: PNode) = else: # otherwise it's just a dependency, nothing to worry about: connect(c, dest.sym, n.sym, n.info) + # but a construct like ``[symbol]`` is dangerous: + if c.inConstructor > 0: dest.flags.incl ownsData of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr, nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr, nkAddr, nkHiddenAddr: diff --git a/tests/arc/topt_no_cursor.nim b/tests/arc/topt_no_cursor.nim index 3ea4deaf1..fe63e7585 100644 --- a/tests/arc/topt_no_cursor.nim +++ b/tests/arc/topt_no_cursor.nim @@ -2,8 +2,9 @@ discard """ output: '''(repo: "", package: "meo", ext: "") doing shady stuff... 3 -6''' - cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --hint:Performance:off $file''' +6 +(@[1], @[2])''' + cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off $file''' nimout: '''--expandArc: newTarget var @@ -37,6 +38,44 @@ var `=`(sibling.right, saved.left) `=sink`(sibling.parent, saved) `=destroy`(sibling) +-- end of expandArc ------------------------ +--expandArc: p1 + +var + lresult + lvalue + _ +`=`(lresult, [123]) +var lnext_cursor: string +_ = ( + let blitTmp = lresult + blitTmp, ";") +lvalue = _[0] +lnext_cursor = _[1] +`=sink`(result.value, lvalue) +-- end of expandArc ------------------------ +--expandArc: tt + +var + a + :tmpD + :tmpD_1 + :tmpD_2 +try: + var it_cursor = x + a = ( + wasMoved(:tmpD) + `=`(:tmpD, it_cursor.key) + :tmpD, + wasMoved(:tmpD_1) + `=`(:tmpD_1, it_cursor.val) + :tmpD_1) + echo [ + :tmpD_2 = `$`(a) + :tmpD_2] +finally: + `=destroy`(:tmpD_2) + `=destroy_1`(a) -- end of expandArc ------------------------''' """ @@ -98,3 +137,37 @@ proc main = echo five.right.value main() + +type + Maybe = object + value: seq[int] + +proc p1(): Maybe = + let lresult = @[123] + var lvalue: seq[int] + var lnext: string + (lvalue, lnext) = (lresult, ";") + + result.value = lvalue + +proc tissue15130 = + doAssert p1().value == @[123] + +tissue15130() + +type + KeyValue = tuple[key, val: seq[int]] + +proc tt(x: KeyValue) = + var it = x + let a = (it.key, it.val) + echo a + +proc encodedQuery = + var query: seq[KeyValue] + query.add (key: @[1], val: @[2]) + + for elem in query: + elem.tt() + +encodedQuery()