Support iterators returning lent T (#11938)
* lent iterators * rebase tests * update changelog * fix comments, more tests
This commit is contained in:
parent
9ae0dd611f
commit
2b565aad89
7 changed files with 116 additions and 27 deletions
|
|
@ -21,8 +21,8 @@ proc newDeref*(n: PNode): PNode {.inline.} =
|
|||
|
||||
proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode =
|
||||
if tup.kind == nkHiddenAddr:
|
||||
result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar}))
|
||||
result.addSon(newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar}).sons[i]))
|
||||
result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}))
|
||||
result.addSon(newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}).sons[i]))
|
||||
addSon(result[0], tup[0])
|
||||
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
|
||||
lit.intVal = i
|
||||
|
|
|
|||
|
|
@ -1781,21 +1781,21 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
|||
var t = skipTypes(restype, {tyGenericInst, tyAlias, tySink})
|
||||
case t.kind
|
||||
of tyVar, tyLent:
|
||||
if t.kind == tyVar: t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}:
|
||||
n.sons[0] = n.sons[0].sons[1]
|
||||
n.sons[0] = takeImplicitAddr(c, n.sons[0], t.kind == tyLent)
|
||||
of tyTuple:
|
||||
for i in 0..<t.sonsLen:
|
||||
var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
|
||||
let e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
|
||||
if e.kind in {tyVar, tyLent}:
|
||||
if e.kind == tyVar: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
if n.sons[0].kind in {nkPar, nkTupleConstr}:
|
||||
n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i], e.kind == tyLent)
|
||||
elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
|
||||
n.sons[0].sons[1].kind in {nkPar, nkTupleConstr}:
|
||||
var a = n.sons[0].sons[1]
|
||||
a.sons[i] = takeImplicitAddr(c, a.sons[i], false)
|
||||
a.sons[i] = takeImplicitAddr(c, a.sons[i], e.kind == tyLent)
|
||||
else:
|
||||
localError(c.config, n.sons[0].info, errXExpected, "tuple constructor")
|
||||
else: discard
|
||||
|
|
|
|||
|
|
@ -678,25 +678,30 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
var length = sonsLen(n)
|
||||
let iterBase = n.sons[length-2].typ
|
||||
var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink})
|
||||
var iterAfterVarLent = iter.skipTypes({tyLent, tyVar})
|
||||
# length == 3 means that there is one for loop variable
|
||||
# and thus no tuple unpacking:
|
||||
if iter.kind != tyTuple or length == 3:
|
||||
if iterAfterVarLent.kind != tyTuple or length == 3:
|
||||
if length == 3:
|
||||
if n.sons[0].kind == nkVarTuple:
|
||||
var mutable = false
|
||||
if iter.kind == tyVar:
|
||||
iter = iter.skipTypes({tyVar})
|
||||
mutable = true
|
||||
if sonsLen(n[0])-1 != sonsLen(iter):
|
||||
if sonsLen(n[0])-1 != sonsLen(iterAfterVarLent):
|
||||
localError(c.config, n[0].info, errWrongNumberOfVariables)
|
||||
for i in 0 ..< sonsLen(n[0])-1:
|
||||
var v = symForVar(c, n[0][i])
|
||||
if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
|
||||
if mutable:
|
||||
v.typ = newTypeS(tyVar, c)
|
||||
v.typ.sons.add iter[i]
|
||||
else:
|
||||
v.typ = iter.sons[i]
|
||||
case iter.kind
|
||||
of tyVar:
|
||||
v.typ = newTypeS(tyVar, c)
|
||||
v.typ.sons.add iterAfterVarLent[i]
|
||||
if tfVarIsPtr in iter.flags:
|
||||
v.typ.flags.incl tfVarIsPtr
|
||||
of tyLent:
|
||||
v.typ = newTypeS(tyLent, c)
|
||||
v.typ.sons.add iterAfterVarLent[i]
|
||||
if tfVarIsPtr in iter.flags:
|
||||
v.typ.flags.incl tfVarIsPtr
|
||||
else:
|
||||
v.typ = iter.sons[i]
|
||||
n.sons[0][i] = newSymNode(v)
|
||||
if sfGenSym notin v.flags: addDecl(c, v)
|
||||
elif v.owner == nil: v.owner = getCurrOwner(c)
|
||||
|
|
@ -712,15 +717,22 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
elif v.owner == nil: v.owner = getCurrOwner(c)
|
||||
else:
|
||||
localError(c.config, n.info, errWrongNumberOfVariables)
|
||||
elif length-2 != sonsLen(iter):
|
||||
elif length-2 != sonsLen(iterAfterVarLent):
|
||||
localError(c.config, n.info, errWrongNumberOfVariables)
|
||||
else:
|
||||
for i in 0 .. length - 3:
|
||||
if n.sons[i].kind == nkVarTuple:
|
||||
var mutable = false
|
||||
if iter[i].kind == tyVar:
|
||||
iter[i] = iter[i].skipTypes({tyVar})
|
||||
mutable = true
|
||||
var isLent = false
|
||||
iter[i] = case iter[i].kind
|
||||
of tyVar:
|
||||
mutable = true
|
||||
iter[i].skipTypes({tyVar})
|
||||
of tyLent:
|
||||
isLent = true
|
||||
iter[i].skipTypes({tyLent})
|
||||
else: iter[i]
|
||||
|
||||
if sonsLen(n[i])-1 != sonsLen(iter[i]):
|
||||
localError(c.config, n[i].info, errWrongNumberOfVariables)
|
||||
for j in 0 ..< sonsLen(n[i])-1:
|
||||
|
|
@ -729,6 +741,9 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
if mutable:
|
||||
v.typ = newTypeS(tyVar, c)
|
||||
v.typ.sons.add iter[i][j]
|
||||
elif isLent:
|
||||
v.typ = newTypeS(tyLent, c)
|
||||
v.typ.sons.add iter[i][j]
|
||||
else:
|
||||
v.typ = iter[i][j]
|
||||
n.sons[i][j] = newSymNode(v)
|
||||
|
|
@ -737,7 +752,19 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
else:
|
||||
var v = symForVar(c, n.sons[i])
|
||||
if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal)
|
||||
v.typ = iter.sons[i]
|
||||
case iter.kind
|
||||
of tyVar:
|
||||
v.typ = newTypeS(tyVar, c)
|
||||
v.typ.sons.add iterAfterVarLent[i]
|
||||
if tfVarIsPtr in iter.flags:
|
||||
v.typ.flags.incl tfVarIsPtr
|
||||
of tyLent:
|
||||
v.typ = newTypeS(tyLent, c)
|
||||
v.typ.sons.add iterAfterVarLent[i]
|
||||
if tfVarIsPtr in iter.flags:
|
||||
v.typ.flags.incl tfVarIsPtr
|
||||
else:
|
||||
v.typ = iter.sons[i]
|
||||
n.sons[i] = newSymNode(v)
|
||||
if sfGenSym notin v.flags:
|
||||
if not isDiscardUnderscore(v): addDecl(c, v)
|
||||
|
|
|
|||
|
|
@ -371,8 +371,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
|
|||
# c.transCon.forStmt.len == 3 means that there is one for loop variable
|
||||
# and thus no tuple unpacking:
|
||||
if e.typ.isNil: return result # can happen in nimsuggest for unknown reasons
|
||||
if skipTypes(e.typ, {tyGenericInst, tyAlias, tySink}).kind == tyTuple and
|
||||
c.transCon.forStmt.len != 3:
|
||||
if c.transCon.forStmt.len != 3:
|
||||
e = skipConv(e)
|
||||
if e.kind in {nkPar, nkTupleConstr}:
|
||||
for i in 0 ..< sonsLen(e):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue