fixes #6626
This commit is contained in:
parent
be87fe9176
commit
e0591d4941
3 changed files with 18 additions and 2 deletions
|
|
@ -134,3 +134,5 @@ This now needs to be written as:
|
||||||
own random number generators that do not require locking.
|
own random number generators that do not require locking.
|
||||||
- The compiler is now more consistent in its treatment of ambiguous symbols:
|
- The compiler is now more consistent in its treatment of ambiguous symbols:
|
||||||
Types that shadow procs and vice versa are marked as ambiguous (bug #6693).
|
Types that shadow procs and vice versa are marked as ambiguous (bug #6693).
|
||||||
|
- ``yield`` (or ``await`` which is mapped to ``yield``) never worked reliably
|
||||||
|
in an array, seq or object constructor and is now prevented at compile-time.
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,7 @@ type
|
||||||
LiftingPass = object
|
LiftingPass = object
|
||||||
processed: IntSet
|
processed: IntSet
|
||||||
envVars: Table[int, PNode]
|
envVars: Table[int, PNode]
|
||||||
|
inContainer: int
|
||||||
|
|
||||||
proc initLiftingPass(fn: PSym): LiftingPass =
|
proc initLiftingPass(fn: PSym): LiftingPass =
|
||||||
result.processed = initIntSet()
|
result.processed = initIntSet()
|
||||||
|
|
@ -597,6 +598,8 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
|
|
||||||
proc transformYield(n: PNode; owner: PSym; d: DetectionPass;
|
proc transformYield(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
c: var LiftingPass): PNode =
|
c: var LiftingPass): PNode =
|
||||||
|
if c.inContainer > 0:
|
||||||
|
localError(n.info, "invalid control flow: 'yield' within a constructor")
|
||||||
let state = getStateField(owner)
|
let state = getStateField(owner)
|
||||||
assert state != nil
|
assert state != nil
|
||||||
assert state.typ != nil
|
assert state.typ != nil
|
||||||
|
|
@ -703,11 +706,14 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
if not c.processed.containsOrIncl(s.id):
|
if not c.processed.containsOrIncl(s.id):
|
||||||
#if s.name.s == "temp":
|
#if s.name.s == "temp":
|
||||||
# echo renderTree(s.getBody, {renderIds})
|
# echo renderTree(s.getBody, {renderIds})
|
||||||
|
let oldInContainer = c.inContainer
|
||||||
|
c.inContainer = 0
|
||||||
let body = wrapIterBody(liftCapturedVars(s.getBody, s, d, c), s)
|
let body = wrapIterBody(liftCapturedVars(s.getBody, s, d, c), s)
|
||||||
if c.envvars.getOrDefault(s.id).isNil:
|
if c.envvars.getOrDefault(s.id).isNil:
|
||||||
s.ast.sons[bodyPos] = body
|
s.ast.sons[bodyPos] = body
|
||||||
else:
|
else:
|
||||||
s.ast.sons[bodyPos] = newTree(nkStmtList, rawClosureCreation(s, d, c), body)
|
s.ast.sons[bodyPos] = newTree(nkStmtList, rawClosureCreation(s, d, c), body)
|
||||||
|
c.inContainer = oldInContainer
|
||||||
if s.typ.callConv == ccClosure:
|
if s.typ.callConv == ccClosure:
|
||||||
result = symToClosure(n, owner, d, c)
|
result = symToClosure(n, owner, d, c)
|
||||||
elif s.id in d.capturedVars:
|
elif s.id in d.capturedVars:
|
||||||
|
|
@ -733,9 +739,12 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
n.sons[1] = x.sons[1]
|
n.sons[1] = x.sons[1]
|
||||||
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
|
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
|
||||||
if n.typ != nil and n[namePos].kind == nkSym:
|
if n.typ != nil and n[namePos].kind == nkSym:
|
||||||
|
let oldInContainer = c.inContainer
|
||||||
|
c.inContainer = 0
|
||||||
let m = newSymNode(n[namePos].sym)
|
let m = newSymNode(n[namePos].sym)
|
||||||
m.typ = n.typ
|
m.typ = n.typ
|
||||||
result = liftCapturedVars(m, owner, d, c)
|
result = liftCapturedVars(m, owner, d, c)
|
||||||
|
c.inContainer = oldInContainer
|
||||||
of nkHiddenStdConv:
|
of nkHiddenStdConv:
|
||||||
if n.len == 2:
|
if n.len == 2:
|
||||||
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
|
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
|
||||||
|
|
@ -750,8 +759,12 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
# special case 'when nimVm' due to bug #3636:
|
# special case 'when nimVm' due to bug #3636:
|
||||||
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
|
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
let inContainer = n.kind in {nkObjConstr, nkBracket}
|
||||||
|
if inContainer: inc c.inContainer
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
n.sons[i] = liftCapturedVars(n[i], owner, d, c)
|
n.sons[i] = liftCapturedVars(n[i], owner, d, c)
|
||||||
|
if inContainer: dec c.inContainer
|
||||||
|
|
||||||
# ------------------ old stuff -------------------------------------------
|
# ------------------ old stuff -------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''@[1, 2, 3, 4]'''
|
errormsg: "invalid control flow: 'yield' within a constructor"
|
||||||
|
line: 16
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# bug #5314
|
# bug #5314, bug #6626
|
||||||
|
|
||||||
import asyncdispatch
|
import asyncdispatch
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue