fixes #9441
This commit is contained in:
parent
467274a19a
commit
7a0191ac7e
2 changed files with 62 additions and 2 deletions
|
|
@ -718,19 +718,37 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
# ------------------ old stuff -------------------------------------------
|
# ------------------ old stuff -------------------------------------------
|
||||||
|
|
||||||
proc semCaptureSym*(s, owner: PSym) =
|
proc semCaptureSym*(s, owner: PSym) =
|
||||||
|
discard """
|
||||||
|
proc outer() =
|
||||||
|
var x: int
|
||||||
|
proc inner() =
|
||||||
|
proc innerInner() =
|
||||||
|
echo x
|
||||||
|
innerInner()
|
||||||
|
inner()
|
||||||
|
# inner() takes a closure too!
|
||||||
|
"""
|
||||||
|
proc propagateClosure(start, last: PSym) =
|
||||||
|
var o = start
|
||||||
|
while o != nil and o.kind != skModule:
|
||||||
|
if o == last: break
|
||||||
|
o.typ.callConv = ccClosure
|
||||||
|
o = o.skipGenericOwner
|
||||||
|
|
||||||
if interestingVar(s) and s.kind != skResult:
|
if interestingVar(s) and s.kind != skResult:
|
||||||
if owner.typ != nil and not isGenericRoutine(owner):
|
if owner.typ != nil and not isGenericRoutine(owner):
|
||||||
# XXX: is this really safe?
|
# XXX: is this really safe?
|
||||||
# if we capture a var from another generic routine,
|
# if we capture a var from another generic routine,
|
||||||
# it won't be consider captured.
|
# it won't be consider captured.
|
||||||
var o = owner.skipGenericOwner
|
var o = owner.skipGenericOwner
|
||||||
while o.kind != skModule and o != nil:
|
while o != nil and o.kind != skModule:
|
||||||
if s.owner == o:
|
if s.owner == o:
|
||||||
if owner.typ.callConv in {ccClosure, ccDefault} or owner.kind == skIterator:
|
if owner.typ.callConv in {ccClosure, ccDefault} or owner.kind == skIterator:
|
||||||
owner.typ.callConv = ccClosure
|
owner.typ.callConv = ccClosure
|
||||||
|
propagateClosure(owner.skipGenericOwner, s.owner)
|
||||||
else:
|
else:
|
||||||
discard "do not produce an error here, but later"
|
discard "do not produce an error here, but later"
|
||||||
#echo "computing .closure for ", owner.name.s, " ", owner.info, " because of ", s.name.s
|
#echo "computing .closure for ", owner.name.s, " because of ", s.name.s
|
||||||
o = o.skipGenericOwner
|
o = o.skipGenericOwner
|
||||||
# since the analysis is not entirely correct, we don't set 'tfCapturesEnv'
|
# since the analysis is not entirely correct, we don't set 'tfCapturesEnv'
|
||||||
# here
|
# here
|
||||||
|
|
|
||||||
42
tests/closure/tinfer_closure_for_nestedproc.nim
Normal file
42
tests/closure/tinfer_closure_for_nestedproc.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
discard """
|
||||||
|
action: compile
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #9441
|
||||||
|
import asyncdispatch, asyncfutures, strtabs
|
||||||
|
|
||||||
|
type
|
||||||
|
Request = object
|
||||||
|
Context = object
|
||||||
|
position: int
|
||||||
|
accept: bool
|
||||||
|
headers: StringTableRef
|
||||||
|
Handler = proc (r: ref Request, c: Context): Future[Context]
|
||||||
|
|
||||||
|
proc respond(req: Request): Future[void] = discard
|
||||||
|
|
||||||
|
proc handle*(h: Handler): auto = # (proc (req: Request): Future[void]) =
|
||||||
|
proc server(req: Request): Future[void] {.async.} =
|
||||||
|
let emptyCtx = Context(
|
||||||
|
position: 0,
|
||||||
|
accept: true,
|
||||||
|
headers: newStringTable()
|
||||||
|
)
|
||||||
|
var reqHeap = new(Request)
|
||||||
|
reqHeap[] = req
|
||||||
|
var
|
||||||
|
f: Future[Context]
|
||||||
|
ctx: Context
|
||||||
|
try:
|
||||||
|
f = h(reqHeap, emptyCtx)
|
||||||
|
ctx = await f
|
||||||
|
except:
|
||||||
|
discard
|
||||||
|
if f.failed:
|
||||||
|
await req.respond()
|
||||||
|
else:
|
||||||
|
if not ctx.accept:
|
||||||
|
await req.respond()
|
||||||
|
return server
|
||||||
|
|
||||||
|
waitFor handle(nil)(Request())
|
||||||
Loading…
Add table
Add a link
Reference in a new issue