From 37692baf49370d096e0d9ac2c8bf51ed7bd8cf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 7 Apr 2020 14:42:59 +0200 Subject: [PATCH] fix #13739 (#13742) --- compiler/transf.nim | 9 ++++----- tests/iter/titer_issues.nim | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/compiler/transf.nim b/compiler/transf.nim index 18d9b913004e..cbf904255cb8 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -560,8 +560,8 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto = of nkBracket: return paFastAsgnTakeTypeFromArg else: - return paDirectMapping # XXX really correct? - # what if ``arg`` has side-effects? + # XXX incorrect, causes #13417 when `arg` has side effects. + return paDirectMapping case arg.kind of nkEmpty..nkNilLit: result = paDirectMapping @@ -671,9 +671,8 @@ proc transformFor(c: PTransf, n: PNode): PNode = idNodeTablePut(newC.mapping, formal, arg) # XXX BUG still not correct if the arg has a side effect! of paComplexOpenarray: - let typ = newType(tySequence, formal.owner) - addSonSkipIntLit(typ, formal.typ[0]) - var temp = newTemp(c, typ, formal.info) + # arrays will deep copy here (pretty bad). + var temp = newTemp(c, arg.typ, formal.info) addVar(v, temp) stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg)) idNodeTablePut(newC.mapping, formal, temp) diff --git a/tests/iter/titer_issues.nim b/tests/iter/titer_issues.nim index a7830dfabdfa..872ebe2b7d37 100644 --- a/tests/iter/titer_issues.nim +++ b/tests/iter/titer_issues.nim @@ -18,6 +18,15 @@ end 1 2 7 +9002 +9004 +9006 +9008 +9010 +9012 +9014 +9016 +9018 ''' """ @@ -213,3 +222,21 @@ block t2023_objiter: var o = init() echo(o.iter()) + + +block: + # issue #13739 + iterator myIter(arg: openarray[int]): int = + var tmp = 0 + let len = arg.len + while tmp < len: + yield arg[tmp] * 2 + inc tmp + + proc someProc() = + var data = [4501,4502,4503,4504,4505,4506,4507,4508,4509] + # StmtListExpr should not get special treatment. + for x in myIter((discard;data)): + echo x + + someProc()