diff --git a/compiler/transf.nim b/compiler/transf.nim index d64276cfb..fc400c524 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -474,12 +474,14 @@ proc transformConv(c: PTransf, n: PNode): PTransNode = type TPutArgInto = enum - paDirectMapping, paFastAsgn, paVarAsgn + paDirectMapping, paFastAsgn, paVarAsgn, paComplexOpenarray proc putArgInto(arg: PNode, formal: PType): TPutArgInto = # This analyses how to treat the mapping "formal <-> arg" in an # inline context. if skipTypes(formal, abstractInst).kind in {tyOpenArray, tyVarargs}: + if arg.kind == nkStmtListExpr: + return paComplexOpenarray return paDirectMapping # XXX really correct? # what if ``arg`` has side-effects? case arg.kind @@ -569,6 +571,14 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = assert(skipTypes(formal.typ, abstractInst).kind == tyVar) 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.sons[0]) + var temp = newTemp(c, typ, formal.info) + addVar(v, temp) + add(stmtList, newAsgnStmt(c, temp, arg.PTransNode)) + idNodeTablePut(newC.mapping, formal, temp) + var body = iter.getBody.copyTree pushInfoContext(n.info) # XXX optimize this somehow. But the check "c.inlining" is not correct: diff --git a/tests/iter/tcomplex_openarray.nim b/tests/iter/tcomplex_openarray.nim new file mode 100644 index 000000000..6fc191e90 --- /dev/null +++ b/tests/iter/tcomplex_openarray.nim @@ -0,0 +1,33 @@ + +# bug #3221 + +import algorithm, math, sequtils + + +iterator permutations[T](ys: openarray[T]): seq[T] = + var + d = 1 + c = newSeq[int](ys.len) + xs = newSeq[T](ys.len) + for i, y in ys: xs[i] = y + yield xs + block outer: + while true: + while d > 1: + dec d + c[d] = 0 + while c[d] >= d: + inc d + if d >= ys.len: break outer + let i = if (d and 1) == 1: c[d] else: 0 + swap xs[i], xs[d] + yield xs + inc c[d] + +proc dig_vectors(): void = + var v_nums: seq[int] + v_nums = newSeq[int](1) + for perm in permutations(toSeq(0 .. 1)): + v_nums[0] = 1 + +dig_vectors()